Local Development

Set up the registry locally and iterate on Airy themes and components.

Local Development

Run the docs site and registry from this repo:

bun install
bun run dev

Or with npm:

npm install
npm run dev

Generate registry JSON output and MCP data:

bun run registry:build

Or with npm:

npm run registry:build

This writes shadcn registry output to public/r/ and MCP data to public/mcp-data/. Both directories are generated and gitignored.

The MCP runtime itself is developed in the sibling levco/airy-mcp repo. This repo only publishes the data that runtime consumes.

Create a new app using the local preset:

# Run the docs site/registry locally
bun run dev

# In a separate terminal
bunx shadcn@latest create --preset "http://localhost:4000/presets/airy-local.json" --template next --src-dir

Or with npm:

# Run the docs site/registry locally
npm run dev

# In a separate terminal
npx shadcn@latest create --preset "http://localhost:4000/presets/airy-local.json" --template next --src-dir

Test installs from a local app:

bunx shadcn@latest registry add @airy=http://localhost:4000/r/{name}.json
bunx shadcn@latest add @airy/button

Or with npm:

npx shadcn@latest registry add @airy=http://localhost:4000/r/{name}.json
npx shadcn@latest add @airy/button

Developing with a Consuming App

When iterating on Airy's theme alongside a consuming application, you can symlink the theme files so changes in Airy are immediately reflected in the consumer.

1. Create a Symlink

In your consuming app, create a symlink from the app's styles directory to Airy's theme folder:

# From the consuming app's styles directory
cd apps/website/styles

# Remove existing airy-theme folder if present
rm -rf airy-theme

# Create symlink to local airy theme
ln -s /path/to/airy/registry/airy-theme airy-theme

For example, if your repos are siblings:

ln -s ../../../airy/registry/airy-theme airy-theme

2. Import Theme Files

In your consuming app's globals.css, import the symlinked files:

@import '../styles/airy-theme/primitives.css';
@import '../styles/airy-theme/airy.css';

3. Live Updates

With the symlink in place:

  • Changes to airy.css variables will reflect immediately in the consuming app
  • The Next.js dev server watches through the symlink
  • No build step required for CSS variable changes

4. Using the App Theme in Demos

If your consuming app uses a different theme (e.g., .theme-marketing) but you want certain components to use Airy's root/app theme:

// Apply class="app" to use :root theme values
<div className="app">
  <DemoComponent />
</div>

The .app class is defined alongside :root in airy.css:

:root, .app {
  --background: ...;
  --primary: ...;
}

.dark, .app.dark, .dark .app {
  --background: ...;
  --primary: ...;
}

This ensures:

  • .app elements use the app theme, not the page's marketing theme
  • Dark mode is inherited from the page (.dark .app selector)

Troubleshooting

Changes not reflecting?

  1. Hard refresh the browser (Cmd+Shift+R)
  2. Touch the importing file to trigger a rebuild:
    touch apps/website/app/globals.css
    
  3. Restart the dev server if needed

Symlink not being followed?

Ensure your consuming app's bundler follows symlinks. For Next.js, this is typically handled automatically, but you may need to verify webpack config if issues persist.


Removing the Symlink

When you're done developing locally and want to switch back to the installed registry version:

1. Remove the Symlink

# From the consuming app's styles directory
cd apps/website/styles

# Remove the symlink
rm airy-theme

2. Reinstall from Registry

Run the shadcn CLI to reinstall the theme from the remote registry:

bunx shadcn@latest registry add @airy=https://airy.lev.com/r/{name}.json
bunx shadcn@latest add @airy/airy-theme

Or with npm:

npx shadcn@latest registry add @airy=https://airy.lev.com/r/{name}.json
npx shadcn@latest add @airy/airy-theme

Or copy the theme files manually from the published registry.

3. Verify

Restart your dev server and confirm the app is using the installed version:

# Check that airy-theme is now a regular directory, not a symlink
ls -la apps/website/styles/airy-theme

If you see -> pointing to another path, the symlink is still in place. If you see a regular directory listing, you're using the installed version.