Loading...
Loading...
Frontend implementation guide for React 19 + TypeScript + Vite 8 monorepo projects. Covers tech stack, project structure (bun workspaces), state management (TanStack Query for async requests + Zustand for client state), UI (shadcn/ui + Tailwind CSS 4.2), theming (light/dark/system), i18n (react-i18next), routing (React Router 7), and coding conventions. Use when scaffolding, developing, or reviewing frontend web applications.
npx skill4agent add zzci/skills pma-web| Category | Technology | Version | Notes |
|---|---|---|---|
| Core | |||
| Framework | React | 19.2 | |
| Language | TypeScript | 5.9 | strict mode |
| Build tool | Vite | 8 | host: |
| Package manager | bun workspaces | — | monorepo |
| Routing & State | |||
| Router | React Router | 7 | lazy routes for code splitting |
| Async state | TanStack Query | 5.90 | request caching, refetch, sync |
| Client state | Zustand | 5.0 | UI-only state |
| UI & Styling | |||
| Component library | shadcn/ui + Base UI | — | |
| CSS | Tailwind CSS | 4.2 | |
| Theming | shadcn/ui ThemeProvider | — | official Vite guide, light / dark / system |
| i18n | |||
| Internationalization | react-i18next | — | i18next-http-backend for lazy loading |
| Tooling | |||
| Lint / format | ESLint + @antfu/eslint-config | 10 / 7.7 |
bunfig.toml
bun.lock
package.json # workspaces: ["apps/*", "packages/*"]
apps/
web/
src/
app/
providers.tsx # compose all Providers
router.tsx # React Router 7 route config
i18n.ts # i18n initialization
features/ # organized by business domain
auth/
components/
hooks/
api.ts # TanStack Query hooks
store.ts # Zustand store (if needed)
routes.tsx
dashboard/
...
shared/
components/
ui/ # shadcn/ui components
theme-provider.tsx # shadcn/ui official ThemeProvider
mode-toggle.tsx # shadcn/ui official ModeToggle
hooks/
lib/
http.ts # fetch wrapper
query-client.ts # TanStack Query client
types/
styles/
theme.css # CSS variables & design tokens
index.html
vite.config.ts
tsconfig.json
package.json
packages/
config/ # @repo/config — shared configs
tsconfig/
base.json # module: NodeNext, strict: true, target: ES2022
react.json # extends base, module: ESNext, jsx: react-jsx
utils.json # extends base, declaration: true
package.json
shared/ # @repo/shared — cross-workspace types
src/
index.ts # domain types, API types, shared constants
package.json
eslint.config.tspackage.json"workspaces": ["apps/*", "packages/*"]bunfig.tomlbun installpnpm installbun run --filter apps/web dev"@repo/config": "workspace:*""@repo/shared": "workspace:*"| File | Purpose |
|---|---|
| Base: |
| Extends base: |
| Extends base: |
tsconfig.json{
"extends": "@repo/config/tsconfig/react.json",
"compilerOptions": {
"baseUrl": ".",
"paths": { "@/*": ["./src/*"] }
}
}ApiResponse<T>import type| Data type | Solution |
|---|---|
| Async/request state | TanStack Query |
| Client UI state | Zustand |
| Theme | shadcn/ui ThemeProvider (single source of truth) |
| Forms | Controlled components or react-hook-form |
localStorage@theme.darkpublic/locales/{{lng}}/{{ns}}.jsonI18nextProvider
└─ QueryClientProvider
└─ ThemeProvider
└─ App| Area | Convention |
|---|---|
| API layer | Each feature exports |
| Routing | Feature-level |
| Components | shadcn/ui → |
| Naming | Files: kebab-case; Components: PascalCase; Hooks: |
| Path alias | |
| Imports | |
| Styling | |
@antfu/eslint-configtype: 'app'src/components/ui/**// vite.config.ts
export default defineConfig({
plugins: [
tailwindcss(), // @tailwindcss/vite
tsConfigPaths(), // vite-tsconfig-paths
react(), // @vitejs/plugin-react
],
server: {
host: '0.0.0.0',
allowedHosts: true,
},
})cd apps/web
bunx shadcn@latest initbase-novaneutrallucidecomponents.json{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "base-nova",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/index.css",
"baseColor": "neutral",
"cssVariables": true
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
}
}# Add individual components
bunx shadcn@latest add button card dialog
# Add theme components for dark mode
bunx shadcn@latest add sonnersrc/shared/components/theme-provider.tsxsrc/shared/components/mode-toggle.tsx<ThemeProvider defaultTheme="system" storageKey="ui-theme">src/shared/components/ui/src/shared/components/ui/**bunx shadcn@latest add/* src/index.css */
@import 'tailwindcss';
@import 'tw-animate-css';
@custom-variant dark (&:is(.dark *));
@theme inline {
/* map CSS variables to Tailwind color tokens */
--color-background: var(--background);
--color-foreground: var(--foreground);
/* ... */
}