How-to

Wiring FramingUI Design Tokens into Cursor

Step-by-step guide to integrate FramingUI design tokens with Cursor IDE for AI-powered UI generation.

FramingUI Team4 min read

Cursor generates a notification card in five seconds. You spend five minutes correcting the colors, padding, and border radius to match your design system. That ratio — five seconds to generate, five minutes to fix — is the problem this guide solves.

The fix is a .cursorrules file. It takes fifteen minutes to set up and eliminates most of the manual correction work.

Why Cursor Guesses Wrong

Without explicit rules, Cursor pulls from its training data: popular open-source repos, public component libraries, generic Tailwind patterns. It has no idea that your project uses indigo-600 not blue-600, p-6 not p-4, or bg-neutral-50 not bg-white.

FramingUI's design tokens are CSS variables — var(--bg-primary-default), var(--foreground-primary), var(--foreground-accent) — not JavaScript objects or hardcoded hex values. Cursor won't use them unless you tell it to.

Installation

Install the packages with pnpm:

pnpm add @framingui/ui @framingui/core @framingui/tokens tailwindcss-animate

Import the styles in your app's global layout:

// app/layout.tsx (Next.js App Router)
import '@framingui/ui/styles';
import './globals.css';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

Cursor Configuration

Create .cursorrules

Create .cursorrules in your project root. This file is Cursor's instruction manual for your codebase.

# Design System: FramingUI

## Component Library
Always import UI components from @framingui/ui:
- Button, Input, Card, Form, Dialog, Sheet, Tabs
- Label, Checkbox, RadioGroup, Select, Switch
- Table, Avatar, Badge, Tooltip, Popover

## Design Tokens
Use CSS custom properties for all styling. Never hardcode colors or spacing.

### Colors
- Primary background: var(--background-page)
- Primary text: var(--foreground-primary)
- Action primary: var(--foreground-accent)
- Muted text: var(--foreground-muted)

### Spacing
Use Tailwind classes that reference tokens:
- bg-[var(--background-page)]
- text-[var(--foreground-primary)]

## Code Generation Rules
1. Never hardcode colors — always use var(--*)
2. Import components from @framingui/ui, not local files
3. Use semantic token names, not color names (blue, red)
4. Prefer FramingUI components over raw HTML elements

## Example Component
```tsx
import { Button, Card, CardHeader, CardTitle, CardContent } from '@framingui/ui';

export function ExampleCard() {
  return (
    <Card>
      <CardHeader>
        <CardTitle>Example</CardTitle>
      </CardHeader>
      <CardContent>
        <Button variant="default">Click me</Button>
      </CardContent>
    </Card>
  );
}

### VSCode Settings for Token Autocomplete

Add to `.vscode/settings.json`:

```json
{
  "editor.quickSuggestions": {
    "strings": true
  },
  "css.customData": [".vscode/css-custom-data.json"]
}

Create .vscode/css-custom-data.json:

{
  "version": 1.1,
  "properties": [
    {
      "name": "--background-page",
      "description": "Primary canvas background"
    },
    {
      "name": "--foreground-primary",
      "description": "Primary text color"
    },
    {
      "name": "--foreground-accent",
      "description": "Primary action / brand color"
    }
  ]
}

Restart Cursor after creating this file.

Testing the Integration

Ask Cursor: "Create a login form using FramingUI components with email and password fields."

A correctly configured Cursor should produce something like this:

import { Button, Input, Label, Card, CardHeader, CardTitle, CardContent } from '@framingui/ui';

export function LoginForm() {
  return (
    <Card className="w-full max-w-md">
      <CardHeader>
        <CardTitle>Sign In</CardTitle>
      </CardHeader>
      <CardContent className="space-y-4">
        <div className="space-y-2">
          <Label htmlFor="email">Email</Label>
          <Input id="email" type="email" placeholder="[email protected]" />
        </div>
        <div className="space-y-2">
          <Label htmlFor="password">Password</Label>
          <Input id="password" type="password" />
        </div>
        <Button className="w-full" variant="default">
          Sign In
        </Button>
      </CardContent>
    </Card>
  );
}

Verify: no hardcoded hex values, components imported from @framingui/ui, no arbitrary Tailwind color classes.

Troubleshooting

Cursor generates raw Tailwind without tokens: Update your .cursorrules and add explicit examples. Be specific: "Use bg-[var(--background-page)] not bg-white."

Token autocomplete not working: Restart Cursor after adding .vscode/css-custom-data.json. The file must exist before Cursor starts.

Components not found: Verify installation with pnpm list @framingui/ui. If missing, rerun the install command.

Extending the Token System

You can layer project-specific tokens on top of the FramingUI base:

/* globals.css */
@import '@framingui/ui/styles';

:root {
  --my-app-header-height: 64px;
  --my-app-sidebar-width: 280px;
}

Add these to your .cursorrules and .vscode/css-custom-data.json so Cursor knows about them.

The fifteen-minute setup pays back on the first complex component Cursor generates correctly. Every component after that is compounding return.

Ready to build with FramingUI?

Build consistent UI with AI-ready design tokens. No more hallucinated colors or spacing.

Try FramingUI
Share

Related Posts