# How to Build Forms Visually with Formily's Form Builder: A Complete Guide

> Learn to build forms visually with Formily's Form Builder using drag-and-drop. This guide shows you how to leverage the Designable framework for complex form creation.

- Repository: [Alibaba/formily](https://github.com/alibaba/formily)
- Tags: how-to-guide
- Published: 2026-02-24

---

**Formily's Form Builder, built on the Designable visual editor framework, lets you create complex forms through drag-and-drop by initializing a Designable engine and registering Formily components as draggable resources.**

The alibaba/formily repository provides a powerful **Form Builder** that eliminates manual JSON schema writing. Built atop the open-source Designable framework, this visual editor integrates deeply with Formily's core to offer a canvas-based form design experience. This guide explains how to assemble the builder using the actual source implementation and official documentation.

## Architecture of the Visual Form Builder

The Form Builder consists of four integrated layers. According to the source code in [`packages/core/src/types.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/types.ts), Formily exposes a `designable?: boolean` property in `IFormProps` that enables Designable hooks when set to true. The architecture flows through Designable's core engine, Formily-specific component bridges, a React-based UI kit, and the actual Formily field components used as drag targets.

The typical workflow involves:

- **Designable Core** – Provides the engine (`createDesigner`), workspace management, undo/redo history, and plugin system.
- **Formily Integration** – Bridges Designable primitives with Formily's `Form`, `Field`, and UI components while maintaining the `designable` metadata flag.
- **UI Kit** – Offers React widgets like `Designer`, `Workspace`, `ResourceWidget`, and `SettingsPanel` to compose the interface.
- **Form Components** – Exposes draggable entities including `Input`, `Select`, `ArrayCards`, and `FormLayout` from packages like `@designable/formily-antd`.

## Installation Prerequisites

Before implementing the builder, install the Designable Formily adapter for your UI library. The official documentation in [`docs/guide/form-builder.md`](https://github.com/alibaba/formily/blob/main/docs/guide/form-builder.md) describes two primary distribution packages.

```bash

# For Ant Design users

npm install --save @designable/formily-antd

# For Alibaba Fusion Design users  

npm install --save @designable/formily-next

```

Import the required Ant Design CSS if using the AntD package:

```tsx
import 'antd/dist/antd.less'

```

## Constructing the Visual Editor

Building the interface requires assembling Designable widgets into a standard layout: a left resource panel, central canvas, and right property panel.

### Initializing the Designable Engine

Create the designer engine with `rootComponentName: 'Form'` to establish Form as the root node. This configuration, referenced in [`packages/core/src/types.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/types.ts), ensures the engine recognizes Formily-specific metadata structures.

```tsx
import { createDesigner, GlobalRegistry, Shortcut, KeyCode } from '@designable/core'

const engine = createDesigner({
  rootComponentName: 'Form',
  shortcuts: [
    new Shortcut({
      codes: [
        [KeyCode.Meta, KeyCode.S],
        [KeyCode.Control, KeyCode.S],
      ],
      handler: (ctx) => {
        const schema = ctx.engine.getCurrentSchema()
        console.log(JSON.stringify(schema, null, 2))
      },
    }),
  ],
})

```

### Registering Draggable Resources

Use `ResourceWidget` components to expose Formily fields as draggable items. Register internationalization labels via `GlobalRegistry.registerDesignerLocales()` to provide human-readable category titles.

```tsx
import { ResourceWidget } from '@designable/react'
import { Input, Select, Card, ArrayCards, FormGrid } from '@designable/formily-antd'

GlobalRegistry.registerDesignerLocales({
  'en-US': {
    sources: {
      Inputs: 'Inputs',
      Layouts: 'Layouts',
      Arrays: 'Arrays',
    },
  },
})

// Inside your component:
<ResourceWidget title="sources.Inputs" sources={[Input, Select]} />
<ResourceWidget title="sources.Layouts" sources={[Card, FormGrid]} />
<ResourceWidget title="sources.Arrays" sources={[ArrayCards]} />

```

### Assembling the Workspace Layout

Wrap your application with the `Designer` provider and compose the layout using `StudioPanel`, `CompositePanel` (left sidebar), `Workspace` (center canvas), and `SettingsPanel` (right sidebar).

The canvas requires `ComponentTreeWidget` to render the live component tree, while `ViewPanel` containers support multiple view modes (Designable, JSON Tree, Markup, Preview).

```tsx
import {
  Designer,
  StudioPanel,
  CompositePanel,
  Workspace,
  WorkspacePanel,
  ToolbarPanel,
  ViewportPanel,
  ViewPanel,
  SettingsPanel,
  ComponentTreeWidget,
  OutlineTreeWidget,
  HistoryWidget,
  DesignerToolsWidget,
  ViewToolsWidget,
} from '@designable/react'
import { SettingsForm } from '@designable/react-settings-form'

return (
  <Designer engine={engine}>
    <StudioPanel logo={<div>Form Builder</div>} actions={<div />}>
      <CompositePanel>
        <CompositePanel.Item title="panels.Component" icon="Component">
          <ResourceWidget title="sources.Inputs" sources={[Input, Password, Select]} />
        </CompositePanel.Item>
        <CompositePanel.Item title="panels.OutlinedTree" icon="Outline">
          <OutlineTreeWidget />
        </CompositePanel.Item>
      </CompositePanel>

      <Workspace id="form">
        <WorkspacePanel>
          <ToolbarPanel>
            <DesignerToolsWidget />
            <ViewToolsWidget use={['DESIGNABLE', 'JSONTREE', 'MARKUP', 'PREVIEW']} />
          </ToolbarPanel>
          <ViewportPanel>
            <ViewPanel type="DESIGNABLE">
              {() => (
                <ComponentTreeWidget
                  components={{
                    Form,
                    Field,
                    Input,
                    Select,
                    Card,
                    ArrayCards,
                    FormGrid,
                  }}
                />
              )}
            </ViewPanel>
            <ViewPanel type="JSONTREE">
              {(tree, onChange) => <SchemaEditorWidget tree={tree} onChange={onChange} />}
            </ViewPanel>
            <ViewPanel type="PREVIEW">
              {(tree) => <PreviewWidget tree={tree} />}
            </ViewPanel>
          </ViewportPanel>
        </WorkspacePanel>
      </Workspace>

      <SettingsPanel title="panels.PropertySettings">
        <SettingsForm uploadAction="https://example.com/upload" />
      </SettingsPanel>
    </StudioPanel>
  </Designer>
)

```

## Exporting the Generated Schema

The schema lives in Designable's internal graph. Retrieve the current JSON schema by calling `engine.getCurrentSchema()` on the engine instance, typically inside a shortcut handler or custom save button.

```tsx
const schema = engine.getCurrentSchema()
// Returns the complete Formily JSON schema representing the visual form

```

## Key Implementation Files

| File | Significance |
|------|------------|
| [`packages/core/src/types.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/types.ts) | Defines the `designable?: boolean` interface that enables Designable integration. |
| [`docs/guide/form-builder.md`](https://github.com/alibaba/formily/blob/main/docs/guide/form-builder.md) | Official guide documenting the builder workflow and component imports. |
| `@designable/react` | Provides the UI widget library (external dependency). |
| `@designable/formily-antd` | Supplies the Formily component set for Ant Design. |

## Summary

- **Install** the `@designable/formily-antd` (or `formily-next`) package to access the visual builder components.
- **Initialize** a Designable engine with `rootComponentName: 'Form'` to establish the proper metadata structure as defined in [`packages/core/src/types.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/types.ts).
- **Register** Formily components (`Input`, `Select`, `ArrayCards`, etc.) via `ResourceWidget` to populate the draggable palette.
- **Compose** the interface using `Designer`, `StudioPanel`, `Workspace`, and `SettingsPanel` widgets to create the canonical three-panel layout.
- **Export** the final form schema using `engine.getCurrentSchema()` for persistence or runtime rendering.

## Frequently Asked Questions

### What is the relationship between Formily and Designable?

Designable is the underlying open-source visual editor framework that powers Formily's Form Builder. Formily provides the specific form component library (`@designable/formily-antd`) and the `designable` metadata flag in [`packages/core/src/types.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/types.ts) that bridges Designable's engine with Formily's schema system.

### Can I use the Form Builder with UI libraries other than Ant Design?

Yes. Alibaba maintains `@designable/formily-next` for Alibaba Fusion Design users. The architecture remains identical; you simply import components from the alternative package and adjust the CSS imports accordingly.

### How do I save the form schema created in the visual builder?

Call `engine.getCurrentSchema()` on your Designable engine instance to retrieve the current JSON representation. You can trigger this inside a `Shortcut` handler (as shown in the `createDesigner` configuration) or bind it to a custom save button in the `ToolbarPanel`.

### Where is the `designable` configuration defined in the Formily source?

The `designable?: boolean` property is defined in [`packages/core/src/types.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/types.ts) within the `IFormProps` interface. This flag tells Formily to expose Designable-specific hooks and metadata when operating inside the visual builder context.