You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+55-68Lines changed: 55 additions & 68 deletions
Original file line number
Diff line number
Diff line change
@@ -1,46 +1,30 @@
1
-
# 🧩 Open-source Visual UI Builder — Build apps like Figma, Framer, and Webflow
1
+
# 🧩 UI Builder — The Open-Source Visual Interface Builder for React
2
2
3
-
UI Builder is a React component that lets you create and edit user interfaces through a fast, flexible no-code editor — powered by your own components or primitives.
3
+
**UI Builder solves the fundamental problem of UI creation tools: they ignore your existing React component library and force you to rebuild from scratch.**
4
4
5
-
- Visual no-code editor
6
-
- Extensible with your components
7
-
- Customizable user interface
8
-
- Integrates with existing projects
9
-
- Export pages as React code
10
-
- Live preview of changes
11
-
- Tailwind CSS support
5
+
UI Builder is a shadcn/ui package that adds a Figma‑style editor to your own product, letting non‑developers compose pages, emails, dashboards, and white‑label views with the exact React components you already ship.
12
6
13
-
Perfect for building landing pages, email templates, forms, admin dashboards, or giving your users no-code superpowers inside your product — without locking into closed platforms like Figma, Framer, Webflow, or Builder.io.
7
+
Layouts are saved as plain JSON for easy versioning and can be rendered instantly allowing:
8
+
9
+
- your marketing team to update a landing page without waiting on engineering.
10
+
- a customer to tweak a branded portal.
11
+
- a product manager to modify email templates.
12
+
- add a visual "head" to your headless CMS, connecting your content API with your component library.
14
13
15
-
🛠 Extend it. 🎨 Style it. 🚀 Own it.
16
14
15
+
How it unlocks novel product features:
17
16
18
-
See the [demo](https://uibuilder.app/) to get an idea of how it works.
17
+
- Give users no‑code superpowers — add a full visual builder to your SaaS with one install.
18
+
- Design with components you already ship — nothing new to build or maintain.
19
+
- Store layouts as human‑readable JSON — render inside your product to ship changes immediately.
19
20
20
-

21
-
22
-
## How it Works
23
-
24
-
UI Builder empowers you to visually construct and modify user interfaces by leveraging your own React components. Here's a breakdown of its core principles:
25
-
26
-
***Component-Driven Foundation**: At its heart, UI Builder operates on your existing React components. You provide a `componentRegistry` detailing the components you want to make available in the editor. This registry includes the component itself, its Zod schema for props, its import path for code generation, and optional UI customizations for the editor.
27
-
28
-
***Layer-Based Canvas**: The user interface is constructed as a tree of "layers." Each layer represents an instance of a component from your registry. Users can visually add, remove, reorder, and nest these layers on an interactive canvas, offering a direct manipulation experience. Any component type, like `div`, `main`, or custom containers, can serve as the root page layer.
29
-
30
-
***Dynamic Props Editing**: Each component in the registry is defined with a Zod schema that outlines its props, their types, and default values. UI Builder utilizes this schema to automatically generate a properties panel (using [Auto-Form](https://github.com/vantezzen/autoform/tree/pure-shadcn)). This allows users to configure component instances in real-time, with changes immediately reflected on the canvas. Default values in the Zod schema are crucial for ensuring components render correctly when first added.
31
-
32
-
***Centralized `componentRegistry`**: The `componentRegistry` prop passed to the `UIBuilder` component is central to its operation. It's a JavaScript object where you map a unique string identifier (e.g., "Button", "FancyComponent") to each component's detailed definition.
33
-
34
-
***Flexible State Management**: By default, the editor's state (the arrangement and configuration of layers) is persisted in the browser's local storage for convenience across sessions. For more robust or backend-integrated solutions, you can provide `initialLayers` to seed the editor (e.g., from a database) and use the `onChange` callback to capture state changes and persist them as needed.
21
+
See the [docs site](https://uibuilder.app/) for more information.
35
22
36
-
***React Code Generation**: A key feature is the ability to export the visually designed page structure as clean, readable React code. This process uses the import paths (`from` property) specified in your component registry, ensuring the generated code correctly references your components.
23
+

37
24
38
-
***Extensibility and Customization**: The system is designed for deep integration with your project:
39
-
* Customize the properties form for each component using `fieldOverrides` to enhance the editing experience (e.g., custom labels, input types, or conditional visibility).
40
-
* Provide custom React components via the `panelConfig` prop to provide custom components for the editor panels.
41
-
* If you only need to display a UI Builder page without the editor, the `LayerRenderer` component can render it using the same `componentRegistry` and page data.
25
+
---
42
26
43
-
This section aims to give a clearer picture of the UI Builder's architecture and how its different parts interact.
27
+
# Quick Start
44
28
45
29
## Installation
46
30
@@ -74,19 +58,18 @@ And that's it! You have a UI Builder that you can use to build your UI.
74
58
75
59
### Basic Example
76
60
77
-
To use the UI Builder, you need to provide a component registry and a form component for editing page-level properties.
61
+
To use the UI Builder, you just need to provide a component registry.
const myComponentRegistry:ComponentRegistry= {...}; // Your component registry
119
94
120
95
// Static initial layers or you can fetch from database
121
96
const initialLayers:ComponentLayer[] = [
@@ -192,19 +167,16 @@ export default App;
192
167
-`persistLayerStore`: Optional boolean (defaults to `true`). Determines whether the editor's state (layers and their configurations) is persisted in the browser's local storage across sessions. Set to `false` to disable local storage persistence, useful if you are managing state entirely through `initialLayers` and `onChange`.
193
168
194
169
170
+
## Rendering from Serialized Layer Data
171
+
195
172
You can also render the page layer without editor functionality by using the LayerRenderer component:
import { primitiveComponentDefinitions } from"@/lib/ui-builder/registry/primitive-component-definitions"; // Example registry
202
178
203
-
// Component registry is needed for the renderer too
204
-
const myComponentRegistry:ComponentRegistry= {
205
-
...primitiveComponentDefinitions,
206
-
// ...add your custom components here
207
-
};
179
+
const myComponentRegistry:ComponentRegistry= {...}; // Your component registry
208
180
209
181
const page:ComponentLayer= {...} // Fetch or define your page layer
210
182
@@ -213,8 +185,6 @@ export function MyPage() {
213
185
}
214
186
```
215
187
216
-
`LayerRenderer` is useful when you want to render the finished page without any editor functionality. It also requires the `componentRegistry` to know how to render the components.
217
-
218
188
## Add your custom components to the registry
219
189
220
190
You add custom components by defining them in a `ComponentRegistry` object and passing that object to the `UIBuilder` component via the `componentRegistry` prop. The registry maps a unique component type name (string) to its definition.
@@ -223,16 +193,15 @@ Here is an example of how to define a custom component within the registry objec
223
193
224
194
```tsx
225
195
import { z } from'zod';
226
-
import { FancyComponent } from'@/components/ui/fancy-component'; // Example custom component
196
+
import { FancyComponent } from'@/components/ui/fancy-component'; // Example custom component with className, children, title, count, disabled, timestamp, mode props
- This schema powers the automatic generation of a properties form in the editor using [Auto-Form](https://github.com/vantezzen/autoform/tree/pure-shadcn).
276
243
- Currently supported Zod types for auto-form generation include: `boolean`, `date`, `number`, `string`, `enum` (of supported types), `object` (with supported property types), and `array` (of objects with supported property types).
277
244
-`from`: **Required**. The source import path for the component. This is used when generating React code.
245
+
-`isFromDefaultExport`: Optional. If true, indicates the component should be imported as a default export when generating React code.
278
246
-`fieldOverrides`: Optional. An object to customize the auto-generated form fields for the component's properties in the editor's sidebar.
279
247
- The keys of this object correspond to the prop names defined in the Zod schema.
280
248
- The values are typically functions that receive the current `layer` object and return configuration options for the `AutoForm` field. These options can control the field's label, input type (`fieldType`), visibility (`isHidden`), placeholder text, render logic, and more. See the AutoForm documentation for available options.
* Implementing conditional logic (e.g., showing/hiding a field based on another prop's value).
286
254
- The example uses `classNameFieldOverrides` and `childrenFieldOverrides` from `@/lib/ui-builder/registry/form-field-overrides` to provide standardized handling for common props like `className` (using a auto suggest text input) and `children` (using a custom component). You can create your own override functions or objects.
287
255
-`defaultChildren`: Optional. Default children to use when a new instance of this component is added to the canvas. For example setting initial text on a span component.
288
-
-`isFromDefaultExport`: Optional. If true, indicates the component should be imported as a default export when generating React code.
289
256
290
257
291
258
### Customizing the Page Config Panel Tabs
292
259
293
-
You can customize the tabs in the left "Page Config" panel (by default, "Layers" and "Appearance") by providing a `pageConfigPanelTabsContent` property inside the `panelConfig` prop. This allows you to change the tab titles or provide custom content for each tab.
260
+
You can customize the tabs in the left "Page Config" panel (by default, "Layers" and "Appearance") by providing a `pageConfigPanelTabsContent` property inside the `panelConfig` prop. This allows you to change the tab titles or provide custom content for each tab. For example, you might want to provide your own appearance tab if you not using tailwind or a custom subset of tailwind like in React-Email .
If you do not provide this, the default tabs ("Layers" and "Appearance") will be used.
281
+
You can also override other panels in the `panelConfig` like `editorPanel`, `propsPanel`, and `navBar`.
314
282
315
283
---
316
-
For more detailed documentation read the [docs](https://uibuilder.app/)
284
+
285
+
## How it Works
286
+
287
+
UI Builder empowers you to visually construct and modify user interfaces by leveraging your own React components. Here's a breakdown of its core principles:
288
+
289
+
***Component-Driven Foundation**: At its heart, UI Builder operates on your existing React components. You provide a `componentRegistry` detailing the components you want to make available in the editor. This registry includes the component itself, its Zod schema for props, its import path for code generation, and optional UI customizations for the editor.
290
+
291
+
***Layer-Based Canvas**: The user interface is constructed as a tree of "layers." Each layer represents an instance of a component from your registry. Users can visually add, remove, reorder, and nest these layers on an interactive canvas, offering a direct manipulation experience. Any component type, like `div`, `main`, or custom containers, can serve as the root page layer.
292
+
293
+
***Dynamic Props Editing**: Each component in the registry is defined with a Zod schema that outlines its props, their types, and default values. UI Builder utilizes this schema to automatically generate a properties panel (using [Auto-Form](https://github.com/vantezzen/autoform/tree/pure-shadcn)). This allows users to configure component instances in real-time, with changes immediately reflected on the canvas.
294
+
295
+
***Flexible State Management**: By default, the editor's state (the arrangement and configuration of layers) is persisted in the browser's local storage for convenience across sessions. For more robust or backend-integrated solutions, you can provide `initialLayers` to seed the editor (e.g., from a database) and use the `onChange` callback to capture state changes and persist them as needed.
296
+
297
+
***React Code Generation**: A key feature is the ability to export the visually designed page structure as clean, readable React code. This process uses the import paths (`from` property) specified in your component registry, ensuring the generated code correctly references your components.
298
+
299
+
***Extensibility and Customization**: The system is designed for deep integration with your project:
300
+
* Customize the properties form for each component using `fieldOverrides` to enhance the editing experience (e.g., custom labels, input types, or conditional visibility).
301
+
* Provide custom React components via the `panelConfig` prop to provide custom components for the editor panels.
302
+
* If you only need to display a UI Builder page without the editor, the `LayerRenderer` component can render it using the same `componentRegistry` and serialized page data.
303
+
317
304
---
318
305
319
306
@@ -358,15 +345,15 @@ npm run test
358
345
359
346
## Roadmap
360
347
361
-
-[ ] Add user friendly styling component instead of directly using tailwind classes
348
+
-[ ] Add user friendly styling component along with of directly using tailwind classes
362
349
-[ ] Add tiptap editor for markdown content
363
350
-[ ] Add global variables for component props
364
351
-[ ] Add Blocks. Reusable component blocks that can be used in multiple pages
365
352
-[ ] Move component schemas to separate shadcn registry to keep main registry light
366
353
-[ ] Move prop form field components (overrides) to separate shadcn registry to keep main registry light
367
354
-[ ] Add data sources to component layers (ex, getUser() binds prop user.name)
0 commit comments