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.cssvariables 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:
.appelements use the app theme, not the page's marketing theme- Dark mode is inherited from the page (
.dark .appselector)
Troubleshooting
Changes not reflecting?
- Hard refresh the browser (Cmd+Shift+R)
- Touch the importing file to trigger a rebuild:
touch apps/website/app/globals.css - 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.