Adding Components
Step-by-step workflows for extending the design system
Ejecting Components
When to Eject
Ejecting copies a component's source code into your project so you can modify it freely. The ejected component still works with Sage themes and CSS variables — you just own the code. Only eject when you need deep customization beyond what props and CSS variables offer.
Three Ways to Eject
1CLI (Recommended)
The fastest way to eject. Run from your project root:
# Eject a single component
npx @thesage/ui eject Button
# Eject to a custom directory
npx @thesage/ui eject Dialog --dir components/sage
# List all available components
npx @thesage/ui eject --listThe CLI automatically transforms internal imports, scaffolds a utils.ts file with the cn() utility, and lists any npm dependencies you need to install.
2Eject Button (This Site)
Every component page on this site has an Eject button. Click it to view the transformed source code, then copy or download it directly into your project.
3AI Assistant (MCP)
If you have the @thesage/mcp server configured, ask your AI assistant to eject a component. It will return the full transformed source code ready to save.
// Example prompts for your AI assistant:
"Eject the Button component so I can customize it"
"I need the Dialog source code in my project"What Happens When You Eject
Import Transformation
Internal relative imports are automatically rewritten to use package-level imports:
// Before (internal source):
import { cn } from '../../lib/utils'
import { useMotionPreference } from '../../hooks/use-motion-preference'
import { Button } from '../actions/Button'
// After (ejected):
import { cn } from './utils'
import { useMotionPreference } from '@thesage/ui/hooks'
import { Button } from '@thesage/ui'cn() Utility
A utils.ts file is scaffolded alongside your ejected component containing the cn() utility (clsx + tailwind-merge). If the file already exists, it won't be overwritten.
Theme Compatibility
Ejected components continue to use CSS variables (var(--color-primary), etc.) and work with all three Sage themes (Studio, Terra, Volt) and light/dark modes — no additional configuration needed.
Dependencies
External dependencies (Radix UI primitives, lucide-react, etc.) are listed after ejecting. Install them with the provided pnpm add command. You still need @thesage/ui installed for hooks, utilities, and any non-ejected sibling components.
Example: Ejecting the Button
$ npx @thesage/ui eject Button
Ejected Button successfully!
src/components/ui/Button.tsx
src/components/ui/utils.ts (cn utility)
Required dependencies:
pnpm add @radix-ui/react-slot class-variance-authority
Update your imports:
import { Button } from './src/components/ui/Button'
The ejected component still works with @thesage/ui themes and CSS variables.
You now own it — modify freely.