Implement frontend designs from figma using Chakra UI v3 and Storybook
92
92%
Does it follow best practices?
Impact
92%
1.64xAverage score across 6 eval scenarios
Advisory
Suggest reviewing before use
Translate Figma designs into Chakra UI v3 components with pixel-perfect fidelity. Validate with Storybook, Playwright CLI, and Chrome DevTools MCP. Every color, spacing value, font size, and border radius must come from design tokens, not hardcoded values.
fileKey and nodeId (format: https://figma.com/design/:fileKey/:fileName?node-id=1-2). With figma-desktop MCP, only nodeId is needed.get_design_context(fileKey, nodeId) — returns layout, typography, colors, spacing, and component structure. If truncated, use get_metadata first, then fetch child nodes individually.get_screenshot(fileKey, nodeId) — this is the visual source of truth throughout implementation.localhost asset URLs directly; do not substitute icon packages or placeholders.Extract every specific value from the design data: exact colors, font sizes, font weights, line heights, letter spacing, padding, margin, gap, border radius, and opacity. These values must map to Chakra tokens in your implementation.
The Figma MCP output is typically React + Tailwind — treat it as a design spec, not final code.
@chakra-ui/react.~/* alias for project-internal imports (e.g., import { MyComponent } from '~/components/MyComponent').Translate all Tailwind utility classes into Chakra style props. Never mix Tailwind and Chakra. Common mappings:
| Tailwind | Chakra v3 |
|---|---|
className="flex" | <Flex> / <HStack> / <VStack> |
className="space-y-4" | <Stack gap="4"> |
className="text-sm text-gray-500" | <Text fontSize="sm" color="fg.muted"> |
| Padding/margin classes | Style props: p, px, py, m, mx, my |
See TOKENS.md for the full Tailwind-to-Chakra mapping and all available tokens.
Every visual property must use design tokens — never hardcode hex codes, pixel values, or font names. See TOKENS.md for the complete token reference covering colors, spacing, typography, and border radius.
Key rules:
fg, fg.muted, bg.muted, border.muted, etc.). When a Figma color has no matching token, add a new semantic token to src/components/ui/Provider.tsx."1" = 4px, "2" = 8px, "4" = 16px, etc.).fontSize, fontWeight, and lineHeight props with named scale values. Use fontFamily="mono" for code — never specify font names directly.l1 (4px) and l2 (6px).createSystem(defaultConfig, customConfig) via ChakraProvider. Dark mode by default.Before creating anything new:
src/components/ui/ for shared primitives (Provider, ColorMode, Prose, Toaster).src/components/form/ for form components.src/components/ for feature-level components that may already exist.All new or modified components require a .stories.tsx file, co-located next to the component. Use satisfies Meta<typeof Component> for type safety and the Components/ title prefix matching the folder structure.
import { Box } from '@chakra-ui/react';
import type { Meta, StoryObj } from '@storybook/react-vite';
import { MyComponent } from './MyComponent';
const meta = {
title: 'Components/Category/MyComponent',
component: MyComponent,
parameters: {
layout: 'centered',
backgrounds: { default: 'dark' },
},
decorators: [
(Story) => (
<Box padding="40px">
<Story />
</Box>
),
],
} satisfies Meta<typeof MyComponent>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
args: {
// representative default props
},
};
export const Loading: Story = {
args: {
// loading state props
},
};
export const Empty: Story = {
args: {
// empty/null data props
},
};Loading, Error, Empty, WithData, Disabled, etc.args for prop variations. Use render only when custom JSX wrapping is needed.Box in decorators — do NOT use raw HTML elements.parameters.backgrounds to { default: 'dark' }.bun run storybook -- -p 6XXX from apps/frontend, where 6XXX is a random port in the 6000–6999 range (e.g., 6042). Use a random port because multiple agents may be running Storybook in parallel.bun run build-storybookUse @playwright/cli for browser-based verification. It saves snapshots and screenshots to disk rather than streaming into context.
Setup: npx @playwright/cli@latest if not already available.
Key commands:
playwright-cli snapshot <url> — accessibility snapshot of the page.playwright-cli screenshot <url> — screenshot saved to disk.playwright-cli click <selector> — click an element to test interactions.Workflow:
playwright-cli snapshot on specific story URLs to verify rendered structure.playwright-cli screenshot to capture visual output and compare against the Figma screenshot.playwright-cli click and other interaction commands to test interactive states.Use Chrome DevTools MCP to inspect live rendered output and verify design token accuracy.
Capabilities:
var(--chakra-colors-fg-muted)) are used, not hardcoded values.Workflow:
getStyles to inspect computed styles — verify against Figma design data.evaluate to read CSS custom property values and confirm tokens are used.Design Token Compliance:
Provider.tsx theme if needed (not hardcoded)Visual Fidelity:
Testing:
src/components/ with individual PascalCase folders: src/components/MyComponent/MyComponent.tsx.-components/ directory next to the route file that uses them, inside src/routes/. For example, a component only used by src/routes/$workspace/$tile/index.tsx would go in src/routes/$workspace/$tile/-components/TileHeader.tsx.MyComponent.stories.tsx next to MyComponent.tsx..tsx for files with React code, .ts for everything else.Provider and a StorybookRouter (TanStack Router context via createMemoryHistory). This means components that use useNavigate, Link, or other TanStack Router hooks will work in stories without additional setup. @tanstack/react-start is also mocked — components that use ClientOnly, createServerFn, createMiddleware, createIsomorphicFn, or useServerFn will work in stories without extra setup. Use Box in decorators for layout. Check component dependencies are available.