Adding a New Block
Step-by-step guide for adding a new block component to Star Forge.
Adding a New Block
Blocks are the high-level components users copy into their projects. A block depends on primitives (via barrel files) and may have its own styling logic.
Prerequisites
- The primitive(s) the block depends on already exist in
src/components/ui/. - You understand the Registry System.
Step-by-Step
Create the block source
Create src/components/star-forge/<category>/<name>.tsx.
Import primitives from the barrel files, never from @radix-ui/react-* or @base-ui/react directly:
import { Button } from '@/components/ui/button';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';Keep the component focused on a single responsibility. Export a named function at the end.
Create the preview
Create src/components/star-forge-preview/<category>/<name>.tsx.
The preview is a demo page that wraps the block in a realistic context (e.g., a form, a card). It must have a default export that renders the component.
import MyBlock from '@/components/star-forge/<category>/<name>';
export default function Preview() {
return (
<div className="p-8">
<MyBlock />
</div>
);
}Register in registry-ui.ts
Open src/registry/registry-ui.ts and add an entry:
{
name: '<name>',
author: 'EuMotta',
type: 'registry:ui',
registryDependencies: ['button', 'select'],
dependencies: ['lucide-react'],
description: 'Short description of what this block does.',
files: [
{
path: 'src/components/star-forge/<category>/<name>.tsx',
type: 'registry:ui'
}
],
example: 'src/components/star-forge-preview/<category>/<name>.tsx',
component: React.lazy(() =>
import('@/components/star-forge-preview/<category>/<name>').then((mod) => ({
default: mod.default
}))
)
}Important:
- Use primitive aliases (no prefix) in
registryDependencies(e.g.,select, notradix-select). - Use the preview path in
example, not the source path. - Add
dependenciesfor any npm packages the block uses (e.g.,lucide-react,framer-motion).
Add to documentation
Create or update the MDX page in content/docs/<category>/<page>.mdx.
Use ComponentPreview or DrawerCodePreview with hasEngineChoice={true} if the block depends on dual primitives:
<ComponentPreview
name="<name>"
code={(await extractSourceCode('<name>')).code}
sourceCode={(await extractSourceCode('<name>')).sourceCode}
lang="tsx"
hasEngineChoice={true}
/>For blocks that do NOT depend on dual primitives (e.g., pure CSS components), omit hasEngineChoice.
Build and validate
npm run build:components
npm run audit:registryChecklist
- Block source created in
src/components/star-forge/<category>/<name>.tsx - Preview created in
src/components/star-forge-preview/<category>/<name>.tsx - Block uses barrel imports (
@/components/ui/*) for primitives - Block registered in
src/registry/registry-ui.ts -
registryDependenciesuse alias names (no prefix) - MDX documentation page created/updated
-
npm run build:componentssucceeds -
npm run audit:registrypasses -
npx tsc --noEmithas 0 errors