# Ant Design Pro Cheatsheet
[](https://github.com/ant-design/ant-design-pro) [](https://github.com/ant-design/ant-design-pro) [](https://github.com/ant-design/ant-design-pro/releases) [](https://nodejs.org/) [](https://react.review/repo/ant-design/ant-design-pro)

## ๐ What's New in v6
- **React 19 + antd 6 + Umi Max 4**: Full upgrade to the latest stack, powered by utoopack (Turbopack)
- **Style Overhaul**: Less โ Tailwind CSS v4 + antd-style + CSS Modules, CSS variable theming enabled
- **AI Assistant Page**: Chat interface example built with Ant Design X
- **React Query**: Migrated from useRequest to @tanstack/react-query
- **Biome**: Replaces ESLint + Prettier for unified linting and formatting
- **Cloudflare Worker Backend**: Standalone demo API deployment using Hono
- **And more**: Route prefetch, skeleton Loading, D3 map, Cheatsheet docs, moment โ dayjs, class โ functional components
โ [View full changelog](https://github.com/ant-design/ant-design-pro/releases/tag/v6.0.0)
## Getting Started
**Create a project:**
```bash
git clone --depth 1 https://github.com/ant-design/ant-design-pro.git my-project
cd my-project
npm install
```
The project offers two modes:
- **Full mode**: Includes all demo pages (Dashboard, Forms, Lists, Access, etc.), great for reference and learning
- **Simple mode**: Only keeps login page and basic layout, ideal for starting from scratch
Switch to simple mode:
```bash
git add -A && git commit -m "chore: save before simple" # Commit first to allow revert
npm run simple # Remove demo pages and unused deps
npm install # Update dependencies
```
> ๐ก Start with full mode to learn the project structure, then switch to simple mode for development.
**Directory structure:**
```
โโโ config/ # Configuration (routes, proxy, theme)
โ โโโ config.ts # Main config
โ โโโ routes.ts # Route definitions
โ โโโ defaultSettings.ts # Layout & theme settings
โ โโโ proxy.ts # Dev proxy config
โโโ mock/ # Mock data
โโโ src/
โ โโโ components/ # Shared components
โ โโโ locales/ # i18n resources
โ โโโ models/ # Global data models
โ โโโ services/ # API service layer
โ โโโ utils/ # Utility functions
โ โโโ access.ts # Permission definitions
โ โโโ app.tsx # Runtime configuration
โโโ docs/ # Project documentation
โโโ types/ # Type declarations
```
**Common commands:**
| Command | Description |
|---------|-------------|
| `npm start` | Start dev server (UMI_ENV=dev, with Mock) |
| `npm run dev` | Start dev server (UMI_ENV=dev, no Mock) |
| `npm run start:no-mock` | Start without Mock |
| `npm run start:pre` | Pre-production environment |
| `npm run start:test` | Test environment |
| `npm run build` | Build for production |
| `npm run preview` | Preview built output (run `npm run build` first, port 8000) |
| `npm run preview:build` | Build and preview (port 8000) |
| `npm run deploy` | Build and deploy to GitHub Pages |
| `npm run analyze` | Analyze bundle size |
| `npm run lint` | Lint (Biome + TypeScript) |
| `npm run biome` | Auto-fix with Biome |
| `npm test` | Run tests |
| `npm run test:coverage` | Test with coverage |
| `npm run test:update` | Update test snapshots |
| `npm run tsc` | Type check without emitting |
| `npm run i18n-remove` | Remove i18n wrappers (locale=zh-CN) |
| `npm run record` | Record request data for login scene |
| `npm run openapi` | Generate API code from OpenAPI schema |
| `npm run simple` | Strip demo pages and unused deps |
> ๐ก `UMI_ENV` switches environment configs, mapping to different proxy rules in `config/proxy.ts`.
> ๐ก `npm run simple` removes demo pages (dashboard, form, list etc.) and unused dependencies (plots, etc.), replacing with minimal routes. Ideal for starting from scratch. **Commit your code first so you can revert if needed.**
**Build tool:** This project uses [utoopack](https://github.com/utooland/utoo) (a next-gen bundler powered by Turbopack) as the default build tool, configured via the `utoopack` field in `config/config.ts`. utoopack is Webpack-compatible and supports `module.rules` for custom loaders.
โ See [umi Getting Started](https://umijs.org/en-US/docs/guides/getting-started), [utoo Docs](https://utoo.land)
## Routes & Menu
**Route config** is in `config/routes.ts`:
```ts
// File: config/routes.ts
export default [
{
path: '/welcome',
name: 'welcome', // maps to menu.welcome i18n key
icon: 'home',
component: './Welcome',
},
{
path: '/admin',
name: 'admin',
icon: 'crown',
access: 'canAdmin', // route-level access control
routes: [...],
},
{ path: '/', redirect: '/dashboard/analysis' },
{ component: '404', path: './*' },
];
```
**Route navigation:**
```tsx
import { useNavigate, useParams, useLocation } from '@umijs/max';
const navigate = useNavigate();
navigate('/dashboard'); // navigate
navigate(-1); // go back
const { id } = useParams(); // dynamic param /user/:id
const location = useLocation(); // current route info
```
**Menu & access:** The `access` field in route config controls menu visibility โ unauthorized routes won't appear in the menu.
> ๐ก The `name` field is automatically mapped to `menu.xxx` i18n keys. Configure translations in `src/locales/`.
โ See [umi Routes](https://umijs.org/en-US/docs/guides/routes), [Umi Max Layout & Menu](https://umijs.org/en-US/docs/max/layout-menu)
## Layout
**ProLayout config** is in `config/defaultSettings.ts`:
```ts
// File: config/defaultSettings.ts
export default {
navTheme: 'light', // nav theme: light / dark
colorPrimary: '#1890ff', // primary color
layout: 'mix', // layout mode: side / top / mix
contentWidth: 'Fluid', // content width: Fluid / Fixed
fixedHeader: false, // fixed header
fixSiderbar: true, // fixed sidebar
colorWeak: false, // color weak mode
title: 'Ant Design Pro', // site title
logo: 'https://...', // logo URL
iconfontUrl: '', // iconfont URL
token: {}, // ProLayout token for fine-grained style customization
};
```
**Layout modes:**
- `side` โ Side navigation
- `top` โ Top navigation
- `mix` โ Top + side mixed navigation
**Page container:**
```tsx
import { PageContainer } from '@ant-design/pro-components';
const Page = () => (
{/* Page content */}
);
```
**Custom areas:** Top-right `src/components/RightContent`, footer `src/components/Footer`.
โ See [Umi Max Layout & Menu](https://umijs.org/en-US/docs/max/layout-menu)
## Data Flow
**useModel โ lightweight global state:** Create a file in `src/models/` to auto-register:
```ts
// File: src/models/counter.ts
import { useState } from 'react';
export default function useCounter() {
const [count, setCount] = useState(0);
const increment = () => setCount(c => c + 1);
return { count, increment };
}
```
```tsx
// Use in any component
import { useModel } from '@umijs/max';
const { count, increment } = useModel('counter');
```
**useRequest โ data fetching:**
```tsx
import { useRequest } from '@umijs/max';
const { data, loading, error } = useRequest(getUserInfo);
```
**React Query โ server state management:**
```tsx
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
// Query
const { data, isLoading } = useQuery({
queryKey: ['user', id],
queryFn: () => getUser(id),
});
// Mutation
const mutation = useMutation({
mutationFn: updateUser,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['user'] });
},
});
```
**Initial state โ getInitialState:** Define in `src/app.tsx`, accessible globally:
```tsx
// File: src/app.tsx
export async function getInitialState() {
const currentUser = await fetchUserInfo();
return { currentUser };
}
// Use in components
import { useModel } from '@umijs/max';
const { initialState } = useModel('@@initialState');
```
> ๐ก `getInitialState` runs once on app startup, ideal for fetching global info (user identity, permissions).
โ See [Umi Max Data Flow](https://umijs.org/en-US/docs/max/data-flow)
## Request
**Request config** is in `src/app.tsx`:
```ts
// File: src/app.tsx
export const request: RequestConfig = {
baseURL: 'https://api.example.com',
timeout: 10000,
requestInterceptors: [], // request interceptors
responseInterceptors: [], // response interceptors
};
```
**Error handling** is in `src/requestErrorConfig.ts`, customize error code mapping and notification logic.
**Using request:**
```tsx
import { request } from '@umijs/max';
// GET
const data = await request('/api/users', { params: { page: 1 } });
// POST
await request('/api/users', { method: 'POST', data: { name: 'test' } });
```
**OpenAPI code generation:**
```bash
npm run openapi
```
Auto-generates API calling code under `src/services/` based on `config/oneapi.json`.
> ๐ก Generated code uses `import { request } from '@umijs/max'` directly โ no manual wrapping needed.
โ See [Umi Max Request](https://umijs.org/en-US/docs/max/request)
## Permissions
**Define permissions** in `src/access.ts`:
```ts
// File: src/access.ts
export default function access(initialState: { currentUser?: API.CurrentUser }) {
const { currentUser } = initialState;
return {
canAdmin: currentUser?.access === 'admin',
canUser: !!currentUser,
};
}
```
**Route-level access:** Add `access` field in route config:
```ts
{ path: '/admin', access: 'canAdmin' }
```
**Component-level access:**
```tsx
import { Access, useAccess } from '@umijs/max';
// Declarative
// Imperative
const access = useAccess();
if (access.canAdmin) { /* ... */ }
```
โ See [Umi Max Permissions](https://umijs.org/en-US/docs/max/access)
## Internationalization
**Config** in `config/config.ts`:
```ts
locale: {
default: 'zh-CN',
antd: true, // sync antd component locale
baseNavigator: true, // follow browser language
},
```
**File structure:**
```
src/locales/
โโโ zh-CN.ts # Chinese entry
โโโ zh-CN/
โ โโโ menu.ts # Menu translations
โ โโโ pages.ts # Page translations
โ โโโ ...
โโโ en-US.ts # English entry
โโโ en-US/
โโโ ...
```
**Usage:**
```tsx
import { useIntl, FormattedMessage } from '@umijs/max';
// Hook
const intl = useIntl();
intl.formatMessage({ id: 'menu.welcome' });
// Component
```
**Switch locale:**
```tsx
import { setLocale } from '@umijs/max';
setLocale('en-US', false); // false = no page reload
```
โ See [Umi Max i18n](https://umijs.org/en-US/docs/max/i18n)
## Styling
**CSS Modules:** Name files `*.module.less` or `*.module.css`:
```css
/* example.module.less */
.container { padding: 24px; }
.title { font-size: 16px; }
```
```tsx
import styles from './example.module.less';
```
**antd-style (CSS-in-JS):**
```tsx
import { createStyles } from 'antd-style';
const useStyles = createStyles(({ token, css }) => ({
card: css`
background: ${token.colorBgContainer};
border-radius: ${token.borderRadiusLG}px;
`,
}));
const { styles } = useStyles();
```
**Tailwind CSS (v4):** Use directly in className:
```tsx
```
**Dynamic theme:** Set in `config/config.ts` `antd` config:
```ts
antd: {
configProvider: {
theme: {
token: {
colorPrimary: '#1890ff',
borderRadius: 6,
},
},
},
},
```
Use SettingDrawer in dev mode to switch themes in real-time.
> ๐ก Three styling approaches can coexist: Tailwind for layout, CSS Modules for component styles, antd-style when consuming theme tokens.
โ See [umi Styling](https://umijs.org/en-US/docs/guides/styling), [Umi Max antd Dynamic Theme](https://umijs.org/en-US/docs/max/antd#dynamically-switch-global-configuration)
## Testing & Debugging
**Jest testing:**
```bash
npm test # Run all tests
npm run test:coverage # With coverage report
npm run test:update # Update snapshots
```
Test files go next to the component, named `*.test.ts(x)`.
**Mock data:** Create files in `mock/`:
```ts
// File: mock/user.ts
export default {
'GET /api/currentUser': { name: 'Serati Ma', access: 'admin' },
'POST /api/login': (req, res) => { res.end('ok'); },
};
```
Umi auto-registers mocks, active in dev mode.
**Proxy config** is in `config/proxy.ts`:
```ts
// File: config/proxy.ts
export default {
dev: {
'/api/': {
target: 'http://localhost:8080',
changeOrigin: true,
},
},
};
```
> ๐ก Use `MOCK=none` to skip mock and proxy to backend: `npm run start:no-mock`.
โ See [umi Testing](https://umijs.org/en-US/docs/guides/test), [umi Mock](https://umijs.org/en-US/docs/guides/mock)
## FAQ
**Q: How to disable Mock?**
`npm run start:no-mock` or `cross-env MOCK=none max dev`
**Q: How to change the primary color?**
Edit `colorPrimary` in `config/defaultSettings.ts`. Use SettingDrawer for live preview in dev mode.
**Q: How to add a new page?**
1. Create component in `src/pages/` 2. Add route in `config/routes.ts` 3. Add menu translation in `src/locales/` (if needed)
**Q: How to add global state?**
Create a file in `src/models/` exporting a custom Hook, then use `useModel('filename')` in components.
**Q: How to upgrade the project?**
First, install the pro-upgrade skill into your project:
```bash
npx skills add ant-design/ant-design-pro
```
Then run `/pro-upgrade` in Claude Code at the project root โ AI will auto-diff the latest template and assist your upgrade (deps, config, code patterns, etc.), with conservative handling for ambiguous merges. For other AI assistants, paste the content of `.claude/skills/pro-upgrade/SKILL.md` to them.
**Q: How to deploy?**
`npm run build` generates `dist/`. Deploy to any static file server. Set `publicPath` for non-root deployments. `npm run deploy` builds and publishes to GitHub Pages automatically (pushes to gh-pages branch).
**Q: How to use OpenAPI code generation?**
1. Configure `openAPI` in `config/config.ts` 2. Run `npm run openapi` 3. Code is auto-generated under `src/services/`
โ See [umi FAQ](https://umijs.org/en-US/docs/introduce/faq)
## Common Tasks
### Add a New Page
```bash
# 1. Create the page component
# File: src/pages/my-page/index.tsx
# 2. Register in route config
# File: config/routes.ts
# { path: '/my-page', name: 'myPage', icon: 'file', component: './my-page' }
# 3. Add i18n translations (for menu display)
# File: src/locales/zh-CN/menu.ts โ menu.myPage: 'ๆ็้กต้ข'
# File: src/locales/en-US/menu.ts โ menu.myPage: 'My Page'
```
### Add Global State
```bash
# 1. Create a model file (filename becomes the model key)
# File: src/models/myModel.ts
# Export a custom Hook: export default function useMyModel() { ... }
# 2. Use in components
# import { useModel } from '@umijs/max';
# const { data } = useModel('myModel'); // 'myModel' matches filename
```
### Add a Mock API
```bash
# Global mock: mock/api.ts (applies to all environments)
# Page-level mock: src/pages/my-page/_mock.ts (auto-discovered by Umi)
# Mock format:
# export default { 'GET /api/my-data': { data: [] } }
```
### Generate API Service Code
```bash
# 1. Edit OpenAPI config: config/oneapi.json
# 2. Run generation (overwrites src/services/ant-design-pro/)
npm run openapi
# 3. Never edit generated code manually โ modify oneapi.json and regenerate
```
### Switch to Simple Mode
```bash
git add -A && git commit -m "chore: save before simple" # Must commit first
npm run simple # Irreversible
npm install # Update dependencies
```
## AI Skills (Claude Code)
This project includes two built-in [Claude Code Skills](https://docs.anthropic.com/en/docs/claude-code/skills) (`.claude/skills/`):
### `/pro-upgrade` โ Project Upgrade Assistant
Auto-upgrade to the latest Ant Design Pro version. Diffs the latest template against your project and merges framework changes while preserving business code.
```bash
# In Claude Code, just run:
/pro-upgrade
```
What it does:
1. Clones the latest Pro template
2. Classifies framework vs. business files
3. Merges dependency updates, config changes, and code pattern migrations
4. Runs `npx antd lint` to catch antd-specific issues
5. Verifies with `npm run lint && npm run build`
### `/antd` โ Ant Design CLI Helper
Query antd component APIs, debug issues, lint for deprecated usage, and assist migrations โ all via `@ant-design/cli` with offline bundled metadata.
```bash
# In Claude Code, just run:
/antd
```
Key commands available:
- `npx antd info ` โ props, types, version info
- `npx antd demo ` โ working code examples
- `npx antd lint ./src` โ check for deprecated/problematic usage
- `npx antd migrate ` โ migration checklist between versions
- `npx antd doc ` โ full component documentation
### Installation & Updates
> ๐ก If your project was cloned from this repo, these skills are already included โ no installation needed.
To get the latest skill definitions (or add them to an existing project):
```bash
npx skills add ant-design/ant-design-pro
```
For other AI assistants (Cursor, etc.), paste the content of `.claude/skills/pro-upgrade/SKILL.md` or `.claude/skills/antd/SKILL.md` into the assistant's context.
## Constraints & Gotchas
- **`src/services/ant-design-pro/`** is auto-generated code. Do NOT edit manually. Modify `config/oneapi.json` and run `npm run openapi` to regenerate.
- **`npm run simple` is irreversible**: It deletes demo pages and unused dependencies. Always commit before running.
- **`.umi` temp directory**: `src/.umi` is auto-generated by Umi. Delete it and restart the dev server if you encounter unexpected behavior.
- **Biome over ESLint**: This project uses Biome for linting and formatting. Do not install ESLint or Prettier plugins.
- **Commit convention**: Must follow [Conventional Commits](https://www.conventionalcommits.org/) (e.g., `feat:`, `fix:`, `chore:`).
- **`npx antd lint ./src`**: Must pass with zero errors and warnings before committing.
- **Mock priority**: `mock/` directory for global mocks, `src/pages/**/_mock.ts` for page-level mocks. Both are auto-registered by Umi.
- **Styling priority**: Tailwind (layout) > antd-style (theme tokens) > CSS Modules (component styles) > Less (legacy global styles only).
- **Path aliases**: `@/*` โ `./src/*`, `@@/*` โ `./src/.umi/*`