Skip to main content

Migrating v2 to v3

This guide is designed to help you through the migration. If you went through it and encountered any problems - do let us know. For more information on why certain changes were made, see the When migrating to v3, use the newest version. Gradual updates will take more time and won't ease this process.

Breaking API changes

  • Context data shape has changed: changed, changedMap, submitting, and validating were lifted from the state property to the root.
  • Removed AutoForm.state.modelSync. Use AutoForm.state.model instead.
  • Removed BaseField. Use connectField or useField instead.
  • Removed BaseForm.getChangedKeys. Use changedKeys directly.
  • Removed BaseForm.state.bridge. Use BaseForm.props.schema instead.
  • Removed Bridge.check. Without createSchemaBridge it's no longer needed.
  • Removed baseField from connectField options. There's no one solution here and it may require additional changes, depending on the usage.
  • Removed createSchemaBridge. Now all *Bridge instances have to be created manually.
      import { SimpleSchema } from 'simpl-schema';
    + import { SimpleSchema2Bridge } from 'uniforms-bridge-simple-schema-2';
    const schema = new SimpleSchema({ /* ... */ });
    - <AutoForm schema={schema} />
    + const bridge = new SimpleSchema2Bridge(schema);
    + <AutoForm schema={bridge} />
  • Removed ensureValue from connectField options. That means undefined will no longer be automatically passed to the field as ''. Use value ?? '' instead. This option was enabled by default, therefore it will impact all your custom fields.
  • Removed includeParent from connectField options. Use useField as many times as needed instead.
    const parentName = joinName(joinName(null,, -1));
    const parentField = useField(parentName, {}, { absoluteName: true })[0];
  • Removed injectName. In most cases, it can be safely omitted.
  • Removed includeInChain parameter from connectField options. It was used only in the NestField and ListField family, and mostly because of the way how the old context API worked. In most cases, if you've used includeInChain: false, the migration is to use name="" for the nested fields. See #738, #720, #721 for more information.
  • Removed mapProps from connectField options. Map props directly in the component.
  • Removed nothing. Use null instead.
  • Removed all propTypes in favor of TypeScript types.
  • Renamed or removed deprecated lifecycle methods. If you were using them, e.g. super.componentWillReceiveProps, check whether it's still there and use the correct name if needed.
  • Renamed getChildContext* methods to getContext*, e.g. getChildContextName -> getContextName.
  • Synchronous return and throw in onSubmit are no longer allowed. To return an error or some result, return a Promise instead.
  • filterDOMProps.registered is now read-only.

Validation flow changes

  • Bridge validators have to return errors instead of throwing them.
      // GraphQL Schema
    function validator(model) {
    if (errors.length) {
    - throw { details: validator.errors };
    + return { details: validator.errors };
      // JSON Schema
    function createValidator(schema) {
    const validator = ajv.compile(schema);
    return (model) => {
    if (validator.errors && validator.errors.length) {
    - throw { details: validator.errors };
    + return { details: validator.errors };
  • Removed onSubmitSuccess and onSubmitFailure. Perform all needed operations directly in the onSubmit:
    - onSubmit={onSubmit}
    - onSubmitSuccess={onSubmitSuccess}
    - onSubmitFailure={onSubmitFailure}
    + onSubmit={model => {
    + const result = onSubmit(model);
    + result.then(onSubmitSuccess, onSubmitFailure);
    + return result;
    + }}`
  • onValidate is no longer using callbacks. The error (or the lack of it) has to be returned either synchronously or asynchronously (i.e. wrapped in a promise).
    - onValidate={(model, error, done) => done(error)}
    + onValidate={async (model, error) => error}

React Context API

  • If you were not using context, contextTypes, childContextTypes, or getChildContext* methods directly, there's nothing to do.
  • For direct context access, use useForm hook (functional components), contextType static property (class components), or <context.Consumer /> (both).
    • The React context object, context, is exported from the uniforms package.


  • A lot of types were added or changed. If you are using TypeScript, you may expect some type errors, as all components are no longer full of any.
  • filterDOMProps.register is now type safe and requires FilterDOMProps interface extension.


  • For performance reasons getField, getSubfields, and getType of all bridges are now memoized. If possible, do the same for custom bridges for a potential performance gain.
  • Simplified NumField in most themes as it works as expected in React 16 and later. If you have a custom NumField in your project, do revise its implementation for a potential performance gain.
  • Stop using direct imports and use named ones instead. It'll let your bundler decide, which version it'll need.
    -import BaseForm from 'uniforms/BaseForm';
    +import { BaseForm } from 'uniforms';