Quick Start

Get up and running with UI Builder in minutes. This guide covers installation, basic setup, and your first working editor.

Compatibility Notes

⚠️ Tailwind 4 + React 19: Migration coming soon. Currently blocked by 3rd party component compatibility. If using latest shadcn/ui CLI fails, try: npx shadcn@2.1.8 add ...

⚠️ Server Components: Not supported. RSC can't be re-rendered client-side for live preview. A separate RSC renderer for final page rendering is possible.

Installation

If you are using shadcn/ui in your project, install the component directly from the registry:

bash
1npx shadcn@latest add https://raw.githubusercontent.com/olliethedev/ui-builder/main/registry/block-registry.json

Or start a new project with UI Builder:

bash
1npx shadcn@latest init https://raw.githubusercontent.com/olliethedev/ui-builder/main/registry/block-registry.json

Note: You need to use style variables to have page theming working correctly.

Fix Dependencies

Add dev dependencies (current shadcn/ui registry limitation):

bash
1npm install -D @types/lodash.template @tailwindcss/typography @types/react-syntax-highlighter tailwindcss-animate @types/object-hash

Basic Setup

The minimal setup requires just a component registry:

tsx
1import UIBuilder from "@/components/ui/ui-builder"; 2import { primitiveComponentDefinitions } from "@/lib/ui-builder/registry/primitive-component-definitions"; 3import { complexComponentDefinitions } from "@/lib/ui-builder/registry/complex-component-definitions"; 4 5const componentRegistry = { 6 ...primitiveComponentDefinitions, // div, span, img, etc. 7 ...complexComponentDefinitions, // Button, Badge, Card, etc. 8}; 9 10export function App() { 11 return ( 12 <UIBuilder componentRegistry={componentRegistry} /> 13 ); 14}

This gives you a full visual editor with pre-built shadcn/ui components.

Try it now

Adding State Management

For real applications, you'll want to control the initial state and persist changes:

tsx
1import UIBuilder from "@/components/ui/ui-builder"; 2import { ComponentLayer, Variable } from "@/components/ui/ui-builder/types"; 3 4// Initial page structure 5const initialLayers: ComponentLayer[] = [ 6 { 7 id: "welcome-page", 8 type: "div", 9 name: "Welcome Page", 10 props: { 11 className: "p-8 min-h-screen flex flex-col gap-6", 12 }, 13 children: [ 14 { 15 id: "title", 16 type: "h1", 17 name: "Page Title", 18 props: { 19 className: "text-4xl font-bold text-center", 20 }, 21 children: "Welcome to UI Builder!", 22 }, 23 { 24 id: "cta-button", 25 type: "Button", 26 name: "CTA Button", 27 props: { 28 variant: "default", 29 className: "mx-auto w-fit", 30 }, 31 children: [{ 32 id: "button-text", 33 type: "span", 34 name: "Button Text", 35 props: {}, 36 children: "Get Started", 37 }], 38 }, 39 ], 40 }, 41]; 42 43// Variables for dynamic content 44const initialVariables: Variable[] = [ 45 { 46 id: "welcome-msg", 47 name: "welcomeMessage", 48 type: "string", 49 defaultValue: "Welcome to UI Builder!" 50 } 51]; 52 53export function AppWithState() { 54 const handleLayersChange = (updatedLayers: ComponentLayer[]) => { 55 // Save to database, localStorage, etc. 56 console.log("Layers updated:", updatedLayers); 57 }; 58 59 const handleVariablesChange = (updatedVariables: Variable[]) => { 60 // Save to database, localStorage, etc. 61 console.log("Variables updated:", updatedVariables); 62 }; 63 64 return ( 65 <UIBuilder 66 componentRegistry={componentRegistry} 67 initialLayers={initialLayers} 68 onChange={handleLayersChange} 69 initialVariables={initialVariables} 70 onVariablesChange={handleVariablesChange} 71 /> 72 ); 73}

UIBuilder Props Reference

Required Props

  • componentRegistry - Maps component names to their definitions (see Components Intro)

Optional Props

  • initialLayers - Set initial page structure (e.g., from database)
  • onChange - Callback when pages change (for persistence)
  • initialVariables - Set initial variables for dynamic content
  • onVariablesChange - Callback when variables change
  • panelConfig - Customize editor panels (see Panel Configuration)
  • persistLayerStore - Enable localStorage persistence (default: true)
  • allowVariableEditing - Allow users to edit variables (default: true)
  • allowPagesCreation - Allow users to create pages (default: true)
  • allowPagesDeletion - Allow users to delete pages (default: true)

Note: Only componentRegistry is required. All other props are optional and have sensible defaults.

Rendering Without the Editor

To display pages in production without the editor interface, use LayerRenderer:

tsx
1import LayerRenderer from "@/components/ui/ui-builder/layer-renderer"; 2 3// Basic rendering 4export function MyPage({ page }) { 5 return ( 6 <LayerRenderer 7 page={page} 8 componentRegistry={componentRegistry} 9 /> 10 ); 11} 12 13// With variables for dynamic content 14export function DynamicPage({ page, userData }) { 15 const variableValues = { 16 "welcome-msg": `Welcome back, ${userData.name}!` 17 }; 18 19 return ( 20 <LayerRenderer 21 page={page} 22 componentRegistry={componentRegistry} 23 variables={variables} 24 variableValues={variableValues} 25 /> 26 ); 27}

🎯 Try it: Check out the Renderer Demo and Variables Demo to see LayerRenderer in action.

Full Featured Editor

Next Steps

Now that you have UI Builder running, explore these key areas:

Essential Concepts

  • Components Intro - Understand the component registry system
  • Variables - Add dynamic content with typed variables
  • Rendering Pages - Use LayerRenderer in your production app

Customization

  • Custom Components - Add your own React components to the registry
  • Panel Configuration - Customize the editor interface for your users

Advanced Use Cases

  • Variable Binding - Auto-bind components to system data
  • Immutable Pages - Create locked templates for consistency