FormKrafter
MIT · Web Components · React · Vue · React Native

Build forms once,
run them everywhere

A drag & drop form builder and renderer that works in plain HTML, React, Vue or React Native — with validation, dynamic rules, nested forms and i18n built in.

$ bun add @streamline-pulse/formkrafter-react

How it works

One JSON spec. Three steps. Zero drift.

  1. 01

    Describe

    Every form is a JSON tree of bricks — fields, panels, validations, rules. Exportable, diffable, storable anywhere.

    { id: 'email', validations: [required] }
  2. 02

    Validate

    The same spec compiles to an Ajv schema — client-side in real time, server-side with the exact same verdict.

    validateFormData(spec, data, 'fr')
  3. 03

    Render

    One spec, four renderers: plain Web Components, React, Vue or React Native — pick per app, keep one source of truth.

    <FkFormRender spec={spec} />
Integrations

One behavior, four ways to wire it in.

Web Components

Pure custom elements (Stencil). No framework dependency.

bun add @streamline-pulse/formkrafter-wc

React

Thin wrappers generated from the web components — typed props and events.

bun add @streamline-pulse/formkrafter-react

Vue 3

Same surface, native Vue components.

bun add @streamline-pulse/formkrafter-vue

React Native

A native-primitive renderer for React Native and Expo. Same specs, same rules, same validation.

bun add @streamline-pulse/formkrafter-react-native
Why

Why FormKrafter.

🧩

Framework-agnostic

Web Components at the core; React and Vue wrappers generated from the same source.

Actually lightweight

~130 KB gzipped for a page running the full builder. Lazy-loaded code editor, zero CSS framework.

🛡️

Rules without eval

JSON Logic or JS sandboxed by an AST interpreter: CSP-safe, execution budget.

📄

Specs, not components

Forms as portable JSON. RFC 6902 patches both ways, built-in undo/redo.

🔁

Form.io converter

convertFormioForm migrates fields, wizards, validations and uploads — reports the rest.

🌍

i18n end to end

Content and builder chrome localized; English and French shipped, extendable.

In practice

One builder, one renderer, one event.

App.tsx
import { useState } from 'react'
import { FkFormBuilder, FkFormRender } from '@streamline-pulse/formkrafter-react'
import '@streamline-pulse/formkrafter-wc/styles.css'

export function FormStudio() {
  const [spec, setSpec] = useState()

  return (
    <>
      <FkFormBuilder onSpecChange={(e) => setSpec(e.detail.spec)} />
      {spec && (
        <FkFormRender
          spec={spec}
          onFormSubmit={(e) => console.log(e.detail.data)}
        />
      )}
    </>
  )
}
Migration

Coming from Form.io?

Cut your gzipped form-stack weight by ~3.5×, drop Bootstrap, and watch stored definitions shrink 3–5.5× on real production exports.

470 KB → 130 KBspecs ÷ 3–5,5
Migration guide →
Use cases

Where it actually earns its keep.

Internal tools & back office

Case management, approvals, admin consoles — the forms your ops team touches every day.

Citizen services

Multi-language public forms, official documents, conditional eligibility rules.

Onboarding & surveys

KYC flows, product onboarding, feedback — wizards with per-step validation.

Embeddable builder

Give your own customers a form builder — white-label the palette, keep your data model.

Ready to build?

Add FormKrafter to the app you already have.

$ bun add @streamline-pulse/formkrafter-react