# How to Create a Basic Form Using Formily's Core Package

> Learn to create a basic form with Formily core package. Instantiate Form, use FormProvider, and declare fields with SchemaField for seamless UI integration.

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

---

**To create a basic form using Formily's core package, instantiate a `Form` object by calling `createForm()` from `@formily/core`, then connect it to your UI layer using `FormProvider` and declare fields with `SchemaField` from your framework-specific binding.**

The `@formily/core` package in the alibaba/formily repository provides the foundational state management, validation engine, and lifecycle hooks required to build robust forms programmatically. While the core package operates independently of any rendering layer, it is designed to pair with UI bindings like `@formily/react` or `@formily/vue` to handle the actual DOM representation. This guide walks through the essential steps to create a basic form using Formily's core package, referencing specific implementation details from the source code.

## Instantiating the Form with `createForm`

The entry point for creating any Formily form is the `createForm` factory function exported from the core package. This function initializes a `Form` instance that manages field values, validation state, and submission lifecycle.

According to the source code in [[`packages/core/src/shared/externals.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/shared/externals.ts)](https://github.com/alibaba/formily/blob/formily_next/packages/core/src/shared/externals.ts#L36) (line 36), `createForm` returns a `Form` object configured with your specified options. The resulting instance implements methods such as `setValues`, `validate`, and `submit`, which are defined in the core `Form` class at [[`packages/core/src/models/Form.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/models/Form.ts)](https://github.com/alibaba/formily/blob/formily_next/packages/core/src/models/Form.ts).

```tsx
import { createForm } from '@formily/core';

const form = createForm({
  validateFirst: true,
  initialValues: {
    username: '',
    password: ''
  }
});

```

The `Form` instance created here acts as the single source of truth for all field states, errors, and effects, but it does not render any UI elements on its own.

## Defining Fields with `SchemaField`

To declare form fields declaratively, Formily uses a schema-based approach via the `SchemaField` component provided by UI bindings (e.g., `@formily/react`). The schema itself is a plain JSON object that describes field types, validation rules, and component mappings using `x-component` and `x-decorator` properties.

While the core package in [`packages/core/src/models/Field.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/models/Field.ts) defines the underlying `Field` class that tracks individual field state, the `SchemaField` component translates your declarative schema into these core field instances.

```tsx
import { SchemaField } from '@formily/react';

<SchemaField>
  <SchemaField.String
    name="username"
    title="Username"
    required
    x-decorator="FormItem"
    x-component="Input"
  />
  <SchemaField.String
    name="password"
    title="Password"
    required
    x-decorator="FormItem"
    x-component="Password"
  />
</SchemaField>

```

Each `SchemaField` declaration automatically registers a corresponding field instance with the core `Form` object, linking `form.values.username` and `form.values.password` to the respective components.

## Connecting to the UI Layer with `FormProvider`

To make the core `Form` instance accessible to all descendant components, you must wrap your form layout with `FormProvider` (or the equivalent for your framework). This component creates a context that supplies the `Form` object to `SchemaField` components and action triggers like `Submit`.

As implemented in the React binding documentation, `FormProvider` accepts the `form` instance as a required prop:

```tsx
import { FormProvider, Submit } from '@formily/react';

export default function BasicForm() {
  return (
    <FormProvider form={form}>
      <SchemaField>
        {/* field definitions */}
      </SchemaField>
      
      <Submit onSubmit={values => console.log(values)}>
        Submit
      </Submit>
    </FormProvider>
  );
}

```

The `Submit` component triggers `form.submit()` internally, which validates all fields according to the rules defined in the schema and executes the `onSubmit` callback with the validated values upon success.

## Complete Working Example

Below is a complete, runnable example demonstrating how to create a basic form using Formily's core package with the React UI binding. This setup registers Ant Design components and creates a functional login form.

```tsx
// FormComponent.tsx
import React from 'react';
import { createForm } from '@formily/core';
import { FormProvider, SchemaField, Submit } from '@formily/react';
import { Input, Password, FormItem } from '@formily/antd';

// Register UI components to SchemaField types
SchemaField.define('String', {
  component: Input,
  decorator: FormItem,
});
SchemaField.define('Password', {
  component: Password,
  decorator: FormItem,
});

const form = createForm({
  validateFirst: true,
});

export default function BasicForm() {
  return (
    <FormProvider form={form}>
      <SchemaField>
        <SchemaField.String
          name="username"
          title="Username"
          required
        />
        <SchemaField.Password
          name="password"
          title="Password"
          required
        />
      </SchemaField>

      <Submit onSubmit={values => alert(JSON.stringify(values, null, 2))}>
        Submit
      </Submit>
    </FormProvider>
  );
}

```

This implementation follows the three-step workflow: **(1)** `createForm` instantiates the core state manager, **(2)** `FormProvider` injects it into the component tree, and **(3)** `SchemaField` declarations map UI components to core field instances.

## Core Architecture Concepts

Understanding the underlying classes helps when customizing behavior beyond basic schema definitions.

- **Form Class**: Located at [[`packages/core/src/models/Form.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/models/Form.ts)](https://github.com/alibaba/formily/blob/formily_next/packages/core/src/models/Form.ts), this class manages the global form state, including values, errors, and submission status. It provides methods like `reset`, `validate`, and `setValues`.

- **Field Classes**: Individual fields are represented by the `Field` class and its subclasses (`ObjectField`, `ArrayField`) in [[`packages/core/src/models/Field.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/models/Field.ts)](https://github.com/alibaba/formily/blob/formily_next/packages/core/src/models/Field.ts). These classes track field-specific state such as dirty status, validation errors, and display values.

- **Lifecycle Effects**: Hook into form events (initialization, mounting, submission, validation) using effect creators defined in [[`packages/core/src/effects/onFormEffects.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/effects/onFormEffects.ts)](https://github.com/alibaba/formily/blob/formily_next/packages/core/src/effects/onFormEffects.ts). These allow you to execute side effects when specific form actions occur.

## Summary

- **Initialize** your form by calling `createForm()` from `@formily/core`, which returns a `Form` instance defined in [`packages/core/src/models/Form.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/models/Form.ts).
- **Connect** the form to your components using `FormProvider` from your UI binding (e.g., `@formily/react`).
- **Declare** fields using `SchemaField` components, which map to the core `Field` class in [`packages/core/src/models/Field.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/models/Field.ts).
- **Handle** submission and validation through the `Form` instance methods or the `Submit` component, which orchestrates `form.submit()` and `form.validate()`.

## Frequently Asked Questions

### What is the difference between @formily/core and @formily/react?

`@formily/core` is a framework-agnostic library that manages form state, validation logic, and field relationships through classes like `Form` and `Field`. `@formily/react` is a UI binding that provides React components (`FormProvider`, `SchemaField`, `Submit`) to render the core state. You need both to create a rendered form in a React application, but the core package can operate independently for headless form logic.

### How do I access form values programmatically without using SchemaField?

You can interact directly with the `Form` instance created by `createForm()`. Access `form.values` to read the current state, or call `form.setValuesIn('fieldName', value)` to update specific fields. These methods are implemented in [`packages/core/src/models/Form.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/models/Form.ts) and allow imperative control when declarative schema definitions are insufficient.

### Can I use @formily/core without a UI framework binding?

Yes, `@formily/core` is designed to be headless and can manage form state in non-UI environments such as Node.js servers or testing frameworks. You would manually instantiate fields using the `Field` class constructors and manage their lifecycle through the `Form` instance methods without ever mounting a `FormProvider` or `SchemaField`.

### Where are validation rules processed in the Formily core?

Validation logic is orchestrated by the `Form` class methods and executed at the field level through the `Field` class in [`packages/core/src/models/Field.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/models/Field.ts). When `form.validate()` is called, it triggers validation across all registered field instances, aggregating results into the form's error state before completing the submission lifecycle.