Core Packages in Formily's Architecture: A Deep Dive into the Runtime Kernel

Formily's architecture consists of five foundational npm packages—@formily/core, @formily/reactive, @formily/path, @formily/validator, and @formily/shared—that together provide the framework-agnostic runtime kernel powering all UI adapters.

The alibaba/formily repository organizes its codebase into a monorepo structure where the core packages in Formily's architecture operate as loosely-coupled, focused modules. These packages handle everything from reactive state management to deep object path manipulation, providing the essential infrastructure that framework-specific adapters like @formily/react and @formily/vue consume.

The Five Core Packages That Power Formily

@formily/core – The Central Form Model

The @formily/core package serves as the heart of Formily's architecture, implementing the central form model and field graph management. Located in packages/core/src/models/Form.ts, the Form class maintains the complete state tree including values, initial values, errors, and loading states.

This package handles field lifecycle management, form graph operations, and provides the createForm factory function that initializes the entire form instance. All mutable state within the Form model is made observable through integration with @formily/reactive.

@formily/reactive – Observable State Management

Formily implements its reactivity system in packages/reactive, providing observable primitives built on top of Vue's reactivity system with MobX-like utilities. This package exports essential functions including observable, action, batch, and observe.

The reactive layer ensures that any changes to form values, field states, or validation errors trigger precise updates in consuming UI components. By decoupling state management from the view layer, @formily/reactive enables Formily to support multiple frontend frameworks with a single reactive kernel.

@formily/path – Deep Object Navigation

Path-based data manipulation lives in packages/path, providing the FormPath API for deep object operations. This package handles complex path parsing including array indices, wildcard patterns, and nested property access.

When you call form.setValuesIn('user.addresses.0.city', 'Shanghai'), the path resolution and safe mutation logic executes through @formily/path. This abstraction allows Formily to treat flat path strings as pointers into potentially deeply nested object structures.

@formily/validator – Rule Engine

Validation logic resides in packages/validator, implementing a JSON-Schema compatible validation engine with support for custom validators. The SchemaValidator class processes validation rules including required fields, format checking (email, URL), and complex custom logic.

The validator integrates into the core form lifecycle through the form.validate() method and field-level validator configuration. By separating validation concerns into a dedicated package, Formily allows developers to swap or extend validation strategies without modifying the core state management.

@formily/shared – Utility Library

Common utilities and type guards live in packages/shared, providing essential helpers like merge, uid, isPlainObj, and string case conversion utilities. This package serves as the foundational toolkit that other core packages depend upon for internal operations.

The shared package ensures consistent behavior across the monorepo for deep merging, unique identifier generation, and type checking, reducing code duplication between the reactive, core, and validator packages.

How the Core Packages Work Together

The architecture follows a layered dependency model where higher-level packages consume lower-level utilities. When you initialize a form using createForm() from @formily/core, the system orchestrates all five packages:

  1. Form instantiation creates the central model in packages/core/src/models/Form.ts, initializing the field graph and state containers.

  2. State observation wraps all mutable properties (values, errors, loading flags) with @formily/reactive observables, enabling fine-grained reactivity.

  3. Path operations route all nested value access through @formily/path, allowing methods like setValuesIn() and getValuesIn() to safely manipulate deep objects.

  4. Validation execution delegates to @formily/validator when form.validate() triggers, processing JSON-Schema rules or custom validation functions.

  5. Utility consumption relies on @formily/shared for internal helpers like deep merging initial values or generating unique field identifiers.

UI adapters such as @formily/react or @formily/vue sit above this kernel, importing the core packages to bind reactive form state to framework-specific components.

Practical Examples Using Formily's Core Packages

Creating a Form Instance

The entry point for most applications is the createForm factory, which instantiates the Form model with reactive state management:

import { createForm } from '@formily/core'

const form = createForm({
  values: {
    user: { name: 'Alice', age: 30 },
    preferences: { newsletter: true }
  },
  initialValues: {
    user: { name: '', age: 0 }
  }
})

// Access the underlying reactive form state
console.log(form.values)

This code initializes the field graph in packages/core/src/models/Form.ts and wraps all state with @formily/reactive observables.

Reactive State Observation

You can observe specific form values using the reactive primitives exported from @formily/reactive:

import { createForm } from '@formily/core'
import { observable, autorun } from '@formily/reactive'

const form = createForm({
  values: { count: 0 }
})

// Create a reactive observer
autorun(() => {
  console.log('Current count:', form.values.count)
})

// Mutations trigger the observer
form.setValuesIn('count', 1)

The autorun utility from packages/reactive tracks dependencies automatically, executing the callback whenever form.values.count changes.

Validation Integration

Validation rules integrate through @formily/validator, allowing JSON-Schema or custom validation:

import { createForm } from '@formily/core'

const form = createForm({
  values: { email: '' },
  effects: () => {
    form.createField({
      name: 'email',
      validator: {
        required: true,
        format: 'email',
        message: 'Please enter a valid email address'
      }
    })
  }
})

// Trigger validation
await form.validate()
console.log(form.errors)

The validator configuration delegates to packages/validator, which processes the format: 'email' rule using built-in JSON-Schema validators.

Summary

  • @formily/core provides the central Form model and field graph management in packages/core/src/models/Form.ts.
  • @formily/reactive supplies the observable primitives that make form state reactive, built on Vue's reactivity system.
  • @formily/path handles deep object navigation and path-based mutations via the FormPath API.
  • @formily/validator implements the JSON-Schema validation engine consumed by the core form methods.
  • @formily/shared contains utility functions for merging, type checking, and identifier generation used across the monorepo.
  • UI adapters import these core packages to bind reactive form state to React, Vue, or other framework components.

Frequently Asked Questions

What is the relationship between @formily/core and UI libraries?

@formily/core is framework-agnostic and contains no DOM or framework-specific code. UI libraries like @formily/react and @formily/vue import the core packages and provide declarative components that bind the reactive form state to specific framework rendering cycles. The core handles the form logic while the adapter handles the view layer.

Does Formily require a specific framework to work?

No. The core packages in Formily's architecture—including @formily/core, @formily/reactive, and @formily/validator—are pure TypeScript/JavaScript libraries with no framework dependencies. You can use Formily in vanilla JavaScript projects, Node.js backends, or with any UI framework by writing a custom adapter that consumes the core APIs.

How does @formily/reactive differ from MobX?

While @formily/reactive provides MobX-like utilities including observable, action, and autorun, it is built on top of Vue's reactivity system rather than MobX's implementation. This design choice allows Formily to achieve similar reactive semantics with potentially better tree-shaking and alignment with Vue's proxy-based reactivity, while still maintaining framework independence for the core logic.

Where can I find the source code for these core packages?

The source code for Formily's core packages resides in the packages/ directory of the alibaba/formily repository. Key entry points include packages/core/src/models/Form.ts for the form model, packages/reactive/src/index.ts for reactivity primitives, packages/path/src/index.ts for path operations, and packages/validator/src/index.ts for validation logic. Each package maintains its own package.json defining its public API and dependencies.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →