ant design
Definitive guidelines for building consistent, performant, and maintainable UIs with Ant Design v6.x, focusing on design tokens, layout, and component usage.
The skill
# ant-design Best Practices
This guide outlines the definitive best practices for using Ant Design v6.x in our projects. Adhering to these standards ensures consistency, accessibility, and maintainability across our codebase.
## 1. Theming: Design Token Driven
Always customize Ant Design's appearance using its design token system via `ConfigProvider`. Avoid direct CSS overrides for visual properties that can be controlled by tokens.
### ✅ GOOD: Centralized Token Customization
Create a `theme.ts` file to export your theme configuration and apply it at the root of your application. Prefer `seedToken` adjustments for global changes and `componentToken` for specific component overrides. Utilize preset algorithms for light/dark mode.
```typescript
// src/theme.ts
import { theme } from 'antd';
import type { ThemeConfig } from 'antd';
export const appTheme: ThemeConfig = {
algorithm: theme.defaultAlgorithm, // Or theme.darkAlgorithm, [theme.defaultAlgorithm, theme.darkAlgorithm]
token: {
colorPrimary: '#0050B3', // Our primary brand color
colorSuccess: '#52C41A',
fontSize: 14,
borderRadius: 4,
// Disable motion globally for accessibility/performance
motion: false,
},
components: {
Button: {
colorPrimary: '#1890FF', // Override primary button color
algorithm: true, // Enable algorithm for component token derivation
},
Layout: {
headerBg: '#001529',
footerBg: '#F0F2F5',
},
},
};
```
```tsx
// src/App.tsx (or root layout)
import React from 'react';
import { ConfigProvider, App as AntdApp } from 'antd';
import { appTheme } from './theme';
import HomePage from './pages/HomePage';
const App: React.FC = () => {
return (
<ConfigProvider theme={appTheme}>
{/* Use AntdApp for context-aware static methods (message, Modal, notification) */}
<AntdApp>
<HomePage />
</AntdApp>
</ConfigProvider>
);
};
export default App;
```
### ❌ BAD: Direct CSS Overrides
Avoid overriding Ant Design component styles with custom CSS classes or inline styles for properties that are themeable. This leads to inconsistent UIs and breaks theme updates.
```css
/* ❌ BAD: Avoid this for themeable properties */
.ant-btn-primary {
background-color: #f00 !important; /* Breaks theme */
border-color: #f00 !important;
}
```
## 2. Layout: Unified Grid System
Adhere to Ant Design's 8-pixel grid unit and the unified 1440px canvas width. Use `Row` and `Col` components for structural layout, leveraging their `span` and `gutter` props.
### ✅ GOOD: Responsive Layout with Grid
```tsx
import React from 'react';
import { Layout, Row, Col } from 'antd';
const { Header, Content, Footer } = Layout;
const MyLayout: React.FC = () => (
<Layout style={{ minHeight: '100vh' }}>
<Header style={{ backgroundColor: '#001529' }}>
{/* Header content */}
</Header>
<Content style={{ padding: '0 50px', maxWidth: 1440, margin: '16px auto' }}>
<Row gutter={[16, 16]}> {/* 16px horizontal and vertical gutter */}
<Col span={24}>
<h1>Welcome to our Application</h1>
</Col>
<Col xs={24} sm={12} md={8}> {/* Responsive columns */}
<div style={{ background: '#fff', padding: 24, minHeight: 120 }}>
Card 1
</div>
</Col>
<Col xs={24} sm={12} md={8}>
<div style={{ background: '#fff', padding: 24, minHeight: 120 }}>
Card 2
</div>
</Col>
<Col xs={24} sm={24} md={8}>
<div style={{ background: '#fff', padding: 24, minHeight: 120 }}>
Card 3
</div>
</Col>
</Row>
</Content>
<Footer style={{ textAlign: 'center' }}>
Ant Design ©{new Date().getFullYear()} Created by Ant UED
</Footer>
</Layout>
);
export default MyLayout;
```
### ❌ BAD: Hardcoding Layout Dimensions
Avoid using fixed pixel values or custom CSS for spacing and alignment that should be handled by the grid system or design tokens.
```tsx
// ❌ BAD: Avoid custom margins for layout
<div style={{ marginLeft: '20px', paddingRight: '30px' }}>
{/* Content */}
</div>
```
## 3. Component Usage: Standardized & Accessible
Import components directly from `antd`. Always use TypeScript and configure ESLint with `eslint-plugin-antd` to enforce best practices. Prioritize accessibility by providing necessary `aria-*` attributes.
### ✅ GOOD: Proper Imports and Accessibility
```tsx
import React from 'react';
import { Button, Space, Typography } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
const { Text } = Typography;
const MyComponent: React.FC = () => {
const handleClick = () => {
console.log('Button clicked');
};
return (
<Space>
<Button type="primary" onClick={handleClick} icon={<PlusOutlined />} aria-label="Add new item">
Add Item
</Button>
<Text strong>Important information.</Text>
</Space>
);
};
export default MyComponent;
```
### ❌ BAD: Missing Accessibility Attributes
Interactive components must have appropriate `aria-*` attributes for screen reader users.
```tsx
// ❌ BAD: Missing aria-label for icon-only button
<Button icon={<PlusOutlined />} onClick={() => {}} />
```
## 4. Internationalization & SSR
Wrap your root component with `ConfigProvider` to set the locale and theme. For Server-Side Rendering (SSR), follow the official Ant Design SSR guide to prevent hydration mismatches.
### ✅ GOOD: Global Locale Configuration
```tsx
// src/main.tsx (or root entry)
import React from 'react';
import { createRoot } from 'react-dom/client';
import { ConfigProvider } from 'antd';
import enUS from 'antd/locale/en_US'; // Import desired locale
import App from './App';
import { appTheme } from './theme';
const container = document.getElementById('root');
const root = createRoot(container!);
root.render(
<React.StrictMode>
<ConfigProvider locale={enUS} theme={appTheme}>
<App />
</ConfigProvider>
</React.StrictMode>
);
```
## 5. Performance: Zero Runtime & Tree Shaking
Leverage Ant Design's `zeroRuntime` mode (v6.0.0+) in production for improved performance by pre-generating styles. Ensure your build setup supports tree shaking for `antd` to minimize bundle size.
### ✅ GOOD: Zero Runtime Mode in Production
For production builds, enable `zeroRuntime` and import the pre-generated CSS.
```tsx
// src/App.tsx
import React from 'react';
import { ConfigProvider, App as AntdApp } from 'antd';
import { appTheme } from './theme';
import HomePage from './pages/HomePage';
// In production, import the static CSS generated by @ant-design/static-style-extract
// import 'antd/dist/antd.css'; // Or your custom extracted CSS file
const App: React.FC = () => {
// In a real app, you'd conditionally apply zeroRuntime based on NODE_ENV
const isProduction = process.env.NODE_ENV === 'production';
return (
<ConfigProvider theme={{ ...appTheme, zeroRuntime: isProduction }}>
<AntdApp>
<HomePage />
</AntdApp>
</ConfigProvider>
);
};
export default App;
```
### ❌ BAD: Importing Full CSS with Runtime Styling
If `zeroRuntime` is `false` (default for development), avoid importing `antd/dist/antd.css` as it will lead to duplicate styles and larger bundle sizes.
```tsx
// ❌ BAD: If zeroRuntime is false, this is redundant and harmful
import 'antd/dist/antd.css';
```
## 6. Hooks Best Practices
Utilize Ant Design's hooks for accessing theme tokens and managing context-aware static methods.
### ✅ GOOD: Using `useToken` and `App` Component
```tsx
import React from 'react';
import { Button, theme, message } from 'antd';
import { App as AntdApp } from 'antd'; // Import App component for static methods
const MyThemedComponent: React.FC = () => {
const { token } = theme.useToken(); // Access current theme tokens
const [messageApi, contextHolder] = message.useMessage(); // For context-aware message
const showInfo = () => {
messageApi.info(`Primary color: ${token.colorPrimary}`);
};
return (
<div>
{contextHolder} {/* Important: Render contextHolder */}
<Button onClick={showInfo} style={{ backgroundColor: token.colorPrimary, color: token.colorTextLightSolid }}>
Show Primary Color
</Button>
</div>
);
};
// Wrap components that use static methods or useToken inside <AntdApp>
const RootComponent: React.FC = () => (
<AntdApp>
<MyThemedComponent />
</AntdApp>
);
export default RootComponent;
```
### ❌ BAD: Static Methods Without Context
Calling `message.info()` or `Modal.confirm()` directly without `App` component or `useMessage`/`useModal` hooks will result in them not inheriting `ConfigProvider` context (e.g., theme, locale).
```tsx
// ❌ BAD: This message will not inherit ConfigProvider context
import { message, Button } from 'antd';
const BadComponent: React.FC = () => (
<Button onClick={() => message.info('Hello')}>
Show Message
</Button>
);
```
How to install it
1. Open the tool and start a new conversation, project or template. 2. Paste the text below wherever the tool keeps standing instructions — usually called system prompt, instructions, or persona. 3. Save it so it applies to every run rather than a single message.