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
πΊπΈ
More news from United StatesUnited States
NORTH AMERICA
Related News

Master Local Fine-Tuning with "gemma-trainer"
8h ago
Building a Plugin-Free Newsletter Popup on WordPress: Custom REST Endpoint Mailchimp API v3
8h ago
ΰΈ ΰΈ²ΰΈ©ΰΈ²ΰΉΰΈΰΈ£ΰΉΰΈΰΈ£ΰΈ‘ΰΈ‘ΰΈ΄ΰΉΰΈΰΈΰΈ΅ΰΉ syntax ΰΈΰΉΰΈ²ΰΈ’ ΰΈΰΈ³ΰΉΰΈ«ΰΉ AI ΰΈ«ΰΈ₯ΰΈΰΈΰΈΰΉΰΈΰΈ’ΰΈ₯ΰΈ ΰΈΰΈ£ΰΈ΄ΰΈΰΈ«ΰΈ£ΰΈ·ΰΈ?
8h ago
How I Built a File-Timestamp-Based Feedback Loop to Enforce AI Output Quality
8h ago
GitHub Trending Digest β 2026-07-07
9h ago