Fetching latest headlinesโ€ฆ
Industry-Standard React + TypeScript Folder Structure
NORTH AMERICA
๐Ÿ‡บ๐Ÿ‡ธ United Statesโ€ขJuly 2, 2026

Industry-Standard React + TypeScript Folder Structure

0 views0 likes0 comments
Originally published byDev.to

Same architecture as before, adapted for TypeScript conventions โ€” .tsx/.ts extensions, a dedicated types/ system, strict config files, and typed everything.

my-app/
โ”œโ”€โ”€ public/
โ”‚   โ”œโ”€โ”€ favicon.ico
โ”‚   โ”œโ”€โ”€ robots.txt
โ”‚   โ””โ”€โ”€ index.html
โ”‚
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ assets/
โ”‚   โ”‚   โ”œโ”€โ”€ images/
โ”‚   โ”‚   โ”œโ”€โ”€ fonts/
โ”‚   โ”‚   โ””โ”€โ”€ icons/
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ components/
โ”‚   โ”‚   โ”œโ”€โ”€ common/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ Button/
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ Button.tsx
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ Button.module.css
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ Button.types.ts
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ Button.test.tsx
โ”‚   โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ index.ts
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ Modal/
โ”‚   โ”‚   โ””โ”€โ”€ layout/
โ”‚   โ”‚       โ”œโ”€โ”€ Header/
โ”‚   โ”‚       โ””โ”€โ”€ Footer/
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ features/                     # Feature-based modules
โ”‚   โ”‚   โ”œโ”€โ”€ auth/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ components/
โ”‚   โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ LoginForm.tsx
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ hooks/
โ”‚   โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ useAuth.ts
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ services/
โ”‚   โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ authService.ts
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ types/
โ”‚   โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ auth.types.ts
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ authSlice.ts          # Redux Toolkit slice / Zustand store
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ index.ts
โ”‚   โ”‚   โ”œโ”€โ”€ dashboard/
โ”‚   โ”‚   โ””โ”€โ”€ profile/
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ pages/
โ”‚   โ”‚   โ”œโ”€โ”€ Home/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ Home.tsx
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ Home.module.css
โ”‚   โ”‚   โ”œโ”€โ”€ About/
โ”‚   โ”‚   โ””โ”€โ”€ NotFound/
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ routes/
โ”‚   โ”‚   โ”œโ”€โ”€ AppRoutes.tsx
โ”‚   โ”‚   โ”œโ”€โ”€ ProtectedRoute.tsx
โ”‚   โ”‚   โ””โ”€โ”€ routes.types.ts
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ hooks/                        # Global/shared custom hooks
โ”‚   โ”‚   โ”œโ”€โ”€ useDebounce.ts
โ”‚   โ”‚   โ”œโ”€โ”€ useFetch.ts
โ”‚   โ”‚   โ””โ”€โ”€ useLocalStorage.ts
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ context/
โ”‚   โ”‚   โ”œโ”€โ”€ ThemeContext.tsx
โ”‚   โ”‚   โ””โ”€โ”€ AuthContext.tsx
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ store/                        # Global state management
โ”‚   โ”‚   โ”œโ”€โ”€ index.ts
โ”‚   โ”‚   โ”œโ”€โ”€ hooks.ts                  # Typed useDispatch/useSelector
โ”‚   โ”‚   โ””โ”€โ”€ slices/
โ”‚   โ”‚       โ””โ”€โ”€ userSlice.ts
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ services/                     # API layer
โ”‚   โ”‚   โ”œโ”€โ”€ api.ts                    # Axios instance/config (typed)
โ”‚   โ”‚   โ”œโ”€โ”€ authService.ts
โ”‚   โ”‚   โ””โ”€โ”€ userService.ts
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ utils/
โ”‚   โ”‚   โ”œโ”€โ”€ formatDate.ts
โ”‚   โ”‚   โ”œโ”€โ”€ validators.ts
โ”‚   โ”‚   โ””โ”€โ”€ constants.ts
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ types/                        # Global/shared TypeScript types
โ”‚   โ”‚   โ”œโ”€โ”€ index.ts                  # Re-exports
โ”‚   โ”‚   โ”œโ”€โ”€ user.types.ts
โ”‚   โ”‚   โ”œโ”€โ”€ api.types.ts
โ”‚   โ”‚   โ”œโ”€โ”€ env.d.ts                  # Typed process.env / import.meta.env
โ”‚   โ”‚   โ””โ”€โ”€ global.d.ts               # Ambient/global declarations
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ styles/
โ”‚   โ”‚   โ”œโ”€โ”€ globals.css
โ”‚   โ”‚   โ”œโ”€โ”€ variables.css
โ”‚   โ”‚   โ””โ”€โ”€ theme.ts                  # Typed theme object (MUI/styled-components)
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ config/
โ”‚   โ”‚   โ”œโ”€โ”€ env.ts                    # Typed env config
โ”‚   โ”‚   โ””โ”€โ”€ appConfig.ts
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ App.tsx
โ”‚   โ”œโ”€โ”€ App.css
โ”‚   โ”œโ”€โ”€ main.tsx                      # Entry point (Vite) / index.tsx (CRA)
โ”‚   โ””โ”€โ”€ vite-env.d.ts                 # Vite's built-in type reference
โ”‚
โ”œโ”€โ”€ tests/
โ”‚
โ”œโ”€โ”€ .env
โ”œโ”€โ”€ .env.example
โ”œโ”€โ”€ .eslintrc.cjs
โ”œโ”€โ”€ .prettierrc
โ”œโ”€โ”€ .gitignore
โ”œโ”€โ”€ tsconfig.json                     # TS compiler config
โ”œโ”€โ”€ tsconfig.node.json                # For vite.config.ts itself
โ”œโ”€โ”€ package.json
โ”œโ”€โ”€ vite.config.ts
โ””โ”€โ”€ README.md

What Changes vs. the JS Version

1. Every file gets typed extensions
.jsx โ†’ .tsx (files with JSX), .js โ†’ .ts (pure logic files like utils, services, hooks without JSX).

2. Dedicated types/ folders, at two levels
Global types (src/types/) โ€” shared across the app: API response shapes, User model, env typings.
Feature-local types (features/auth/types/) โ€” scoped to that domain only.

3. tsconfig.json is critical

{
  "compilerOptions": {
    "target": "ES2020",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "skipLibCheck": true,
    "moduleResolution": "bundler",
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "jsx": "react-jsx",
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  },
  "include": ["src"]
}

4. Typed component pattern

// Button.types.ts
export interface ButtonProps {
  label: string;
  variant?: 'primary' | 'secondary';
  onClick?: () => void;
  disabled?: boolean;
}

// Button.tsx
import { FC } from 'react';
import { ButtonProps } from './Button.types';

const Button: FC<ButtonProps> = ({ label, variant = 'primary', onClick, disabled }) => {
  return (
    <button className={`btn btn-${variant}`} onClick={onClick} disabled={disabled}>
      {label}
    </button>
  );
};

export default Button;

5. Typed API service layer

// services/api.ts
import axios, { AxiosInstance } from 'axios';

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

export default api;

// services/userService.ts
import api from './api';
import { User } from '@/types/user.types';

export const getUser = async (id: string): Promise<User> => {
  const { data } = await api.get<User>(`/users/${id}`);
  return data;
};

6. Typed Redux store (if using Redux Toolkit)

// store/index.ts
import { configureStore } from '@reduxjs/toolkit';
import authReducer from '@/features/auth/authSlice';

export const store = configureStore({
  reducer: { auth: authReducer },
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

// store/hooks.ts โ€” typed versions of useDispatch/useSelector
import { useDispatch, useSelector, TypedUseSelectorHook } from 'react-redux';
import type { RootState, AppDispatch } from './index';

export const useAppDispatch: () => AppDispatch = useDispatch;
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;

Essential Packages for This Setup

npm install -D typescript @types/react @types/react-dom @types/node
npm install -D @typescript-eslint/parser @typescript-eslint/eslint-plugin

Comments (0)

Sign in to join the discussion

Be the first to comment!