DEV Community

Cover image for I Stopped Writing React Boilerplate by Hand, Here’s My AI Workflow
Nabeel Krissane
Nabeel Krissane

Posted on

I Stopped Writing React Boilerplate by Hand, Here’s My AI Workflow

If you've built more than a handful of React apps, you know the drill. New project, same 45 minutes: folder structure, routing setup, API client, auth context, form handlers, loading states. Again.

This repetitive setup work isn't just annoying it's expensive. It's time you're not spending on the actual product logic that makes your app valuable.

In this article, I'll walk through the exact AI-assisted workflow I use to eliminate React boilerplate, with real code examples, the mistakes I made along the way, and practical tips you can apply to your next project today.

The Problem: Boilerplate Is a Silent Productivity Killer

Every React project needs the same foundational pieces:

  • API service layer with error handling
  • Custom hooks for data fetching
  • Form validation logic
  • Auth context and protected routes
  • Loading and error UI states

None of this is hard. It's just repetitive, and repetitive work is where bugs sneak in.

Why this happens:

Most teams don't have a shared starter template. Every developer rebuilds these patterns slightly differently, which leads to inconsistent code across the codebase.

What developers usually do wrong:

  1. Copy-pasting from an old project without adapting it to the new one's needs
  2. Skipping error handling because "I'll add it later" (you won't)
  3. Writing one-off hooks instead of reusable, typed abstractions
  4. Not standardizing folder structure, which makes onboarding new devs painful

The Solution: AI as a Boilerplate Generator, Not a Code Replacement

Here's the key mindset shift: AI shouldn't write your business logic. It should write your scaffolding — the predictable, pattern-based code that follows the same shape every time.

I use AI (Claude or ChatGPT) with structured prompts to generate:

  • Typed API clients
  • Reusable custom hooks
  • Form components with validation
  • Boilerplate-heavy context providers

Then I review, adjust, and integrate. This cuts setup time from 45 minutes to about 5.

Step-by-Step Implementation

Step 1: Setup

Start with a clean Vite + React + TypeScript project:

npm create vite@latest my-app -- --template react-ts
cd my-app
npm install axios react-hook-form zod
Enter fullscreen mode Exit fullscreen mode

We're using axios for HTTP requests, react-hook-form for form state, and zod for schema validation — a common, production-proven stack.

Step 2: Configuration

Create a .env file for your API base URL:

VITE_API_BASE_URL=https://api.yourapp.com
Enter fullscreen mode Exit fullscreen mode

This keeps environment-specific config out of your code, which is critical for staging vs. production deployments.

Step 3: Core Implementation

Here's the AI-generated API client I use as a base (then customize per project):

// src/lib/apiClient.ts
import axios, { AxiosError, AxiosInstance } from 'axios';

const apiClient: AxiosInstance = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL,
  timeout: 10000,
});

apiClient.interceptors.request.use((config) => {
  const token = localStorage.getItem('authToken');
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

apiClient.interceptors.response.use(
  (response) => response,
  (error: AxiosError) => {
    if (error.response?.status === 401) {
      localStorage.removeItem('authToken');
      window.location.href = '/login';
    }
    return Promise.reject(error);
  }
);

export default apiClient;
Enter fullscreen mode Exit fullscreen mode

This handles token injection and 401 redirects automatically — no more repeating auth logic in every request.

Next, a reusable data-fetching hook:

// src/hooks/useFetch.ts
import { useState, useEffect } from 'react';
import apiClient from '../lib/apiClient';

export function useFetch<T>(url: string) {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    let isMounted = true;

    apiClient
      .get<T>(url)
      .then((res) => {
        if (isMounted) setData(res.data);
      })
      .catch((err) => {
        if (isMounted) setError(err.message);
      })
      .finally(() => {
        if (isMounted) setLoading(false);
      });

    return () => {
      isMounted = false;
    };
  }, [url]);

  return { data, loading, error };
}
Enter fullscreen mode Exit fullscreen mode

Notice the isMounted guard — it prevents state updates on unmounted components, a common source of React warnings.

Step 4: Final Integration

Using the hook in a component:

// src/components/UserList.tsx
import { useFetch } from '../hooks/useFetch';

interface User {
  id: number;
  name: string;
  email: string;
}

export function UserList() {
  const { data: users, loading, error } = useFetch<User[]>('/users');

  if (loading) return <p>Loading users...</p>;
  if (error) return <p>Error: {error}</p>;

  return (
    <ul>
      {users?.map((user) => (
        <li key={user.id}>{user.name} — {user.email}</li>
      ))}
    </ul>
  );
}
Enter fullscreen mode Exit fullscreen mode

Clean, typed, and reusable across any endpoint in the app.

Common Mistakes to Avoid

1. Blindly copying AI output without reviewing it.
AI-generated code often misses edge cases specific to your app. Always read it line by line before merging.

2. Not typing your API responses.
Skipping TypeScript interfaces defeats the purpose of using TypeScript at all. Always define your shapes.

3. Forgetting cleanup functions in useEffect.
This causes memory leaks and console warnings in larger apps.

4. Over-relying on AI for business logic.
AI is great at patterns, not at understanding your product's unique rules. Keep that logic human-written.

Best Practices and Tips

  • Keep API clients centralized in one file — never scatter fetch calls across components
  • Use Zod or Yup schemas to validate both forms and API responses
  • Generate boilerplate with AI, but always customize error messages and edge-case handling
  • Standardize your folder structure early: hooks/, lib/, components/, types/

Visual Explanation Section

Here you should show a folder structure screenshot: src/lib, src/hooks, src/components, src/types side by side in VS Code's file explorer.

Here you should show a diagram: Component → useFetch hook → apiClient → Backend API, with arrows indicating request/response flow.

Real-World Use Case

This exact pattern is used across:

  • SaaS dashboards — where every page needs authenticated, typed API calls
  • Admin panels — where consistent CRUD patterns save massive dev time
  • Mobile-first web apps — where fast iteration matters more than custom architecture
  • Production systems — where predictable error handling prevents silent failures in the field

Conclusion

Boilerplate isn't the hard part of building React apps — but it is the part that eats your time. By using AI to generate the repetitive, pattern-based scaffolding (API clients, hooks, form logic), you free yourself to focus on what actually makes your product unique.

The key takeaway: let AI handle the predictable, and keep your brain for the parts that require real thinking.


Want to Build React Apps Faster with AI?

Learning React is one thing. Building real-world applications efficiently is another.

You can use ChatGPT, Claude, and Cursor to write code, debug issues, refactor components, generate features, and speed up your development but getting useful results depends heavily on how you prompt AI.

That’s why I created The Ultimate React + Cursor Prompt Library (1000+ AI Prompts) a practical collection of AI prompts designed specifically for React developers.

Inside the library, you’ll find 1,000+ practical prompts covering React development, UI components, debugging, refactoring, performance optimization, API integration, state management, testing, architecture, and more.

Each prompt is designed to help you get better results from AI coding assistants like Cursor, ChatGPT, and Claude, so you can spend less time figuring out what to ask and more time building.

Instead of staring at a blank Cursor chat wondering what prompt to write, you can start with proven prompts and adapt them to your own projects.

Whether you’re building a SaaS, freelance project, startup, dashboard, or personal application, this library can help you code faster, solve problems quicker, and get more out of AI-assisted development.

👉 The Ultimate React + Cursor Prompt Library: 1000+ AI Prompts →

Top comments (1)

Collapse
 
citedy profile image
Dmitry Sergeev •

We need to write a casual YouTube comment as a regular developer, following the developer instructions. Must be short, one or two sentences, maybe a fragment. Should start with a specific reaction or question about this video, not generic praise. Should avoid marketing phrases. No URLs, no double hyphens, no em-dash, no curly quotes. Must be plain ASCII. Use casual voice. Should reflect something about the video: AI workflow, stopped writing React boilerplate by hand. Maybe ask about which AI tool, or comment