kadirulislam/ki-forms

KiForms - Build dynamic React forms from JSON — with zero setup.

TypeScript

0

21 commits

updated Sep 21, 2026

See the code

See what people are saying (1)

SourceMessageScoreDate

I built a visual form builder for React — Ki-forms Studio (r/reactjs)

I’ve been working on **Ki-forms**, a JSON-driven React form library, and today I built the first version of **Ki-forms Studio**. You can visually build a form, configure fields, preview it, and export the schema/code. The idea is to make dynamic React forms faster to build without taking control…

0

Sep 21, 2026

README

ki-forms

Build dynamic React forms from JSON — with zero setup.

Stop wiring forms manually. Define them as data.

Live Demo Schema Studio

Interactive playground — every feature (conditionals, themes, conversational mode, the live schema editor) running the real library. No install needed.

Schema Studio — design forms visually: drag-and-drop fields, edit properties with live preview, then copy the schema JSON or a ready-to-paste React component.


⚡ Quick Example

import { KiForm } from "ki-forms"
import "ki-forms/styles.css"

export default function App() {
  return (
    <KiForm
      fields={[
        "email",
        "password",
        {
          name: "role",
          options: ["User", "Admin"]
        },
        {
          name: "company",
          showIf: { field: "role", equals: "Admin" }
        }
      ]}
      onSubmit={(data) => console.log(data)}
    />
  )
}

🤯 The Problem

Building forms in React is repetitive and inefficient:

  • Managing state for every input
  • Handling validation manually
  • Writing conditional logic
  • Repeating boilerplate code

Even popular libraries like React Hook Form require setup and mental overhead.


✅ The Solution

ki-forms lets you build forms using simple JSON.

  • No manual state handling
  • No boilerplate
  • No complex configuration

Just describe your form → it renders automatically.


📦 Installation

npm install ki-forms

🚀 Basic Usage

import { KiForm } from "ki-forms"
import "ki-forms/styles.css"

<KiForm
  fields={["email", "password"]}
  onSubmit={(data) => console.log(data)}
/>

🧩 Field Configuration

{
  name: "email",
  type: "email", // "text" | "textarea" | "email" | "password" | "number" | "select" | "checkbox" | "tel" | "url" | "date"
  required: true,
  label: "Email",
  placeholder: "Enter your email",
  helperText: "We never share your email"
}

🔄 Conditional Fields

Show fields dynamically based on other values:

{
  name: "company",
  showIf: {
    field: "role",
    equals: "Admin"
  }
}

AND / OR groups (new in 2.1)

{
  name: "taxId",
  required: true,
  showIf: {
    all: [
      { field: "country", equals: "US" },
      { field: "plan", equals: "Pro" }
    ]
  }
}

Use all (every condition must match) or any (at least one). They combine with a top-level field condition via AND. Hidden fields skip validation.


🎯 Smart Defaults

ki-forms automatically:

  • Infers input types (email, password)
  • Generates labels (firstName → First Name)
  • Adds placeholders (Enter your email)
  • Converts simple strings into fields
fields={["email", "password"]}

🧠 Field Events

Run logic when field value changes:

{
  name: "role",
  options: ["User", "Admin"],
  onChange: (value, values) => {
    console.log("Selected:", value)
    console.log("All values:", values)
  }
}

🎨 Styling

Default styles included:

import "ki-forms/styles.css"

Override using className:

{
  name: "email",
  className: "my-custom-input"
}

⚙️ Advanced Usage

Use the form hook directly:

import { useKiForm, KiForm } from "ki-forms"

const form = useKiForm({
  fields: ["email", "password"]
})

<KiForm form={form} />

📋 Supported Features

  • JSON-based form builder
  • Conditional fields + AND/OR groups
  • Smart defaults
  • Theme tokens (CSS variables)
  • Zod schema generation
  • Minimal API
  • React + Next.js support
  • Extendable component system
  • Built-in UI

Supported field types

text, email, password, number, tel, url, date, textarea, select, and checkbox.

Custom field components

Replace or extend built-in renderers with the components prop. A custom component receives the field definition, current value, validation error, and an onChange callback:

function RatingField({ field, value, onChange, error }) {
  return (
    <div>
      <input
        type="range"
        min="1"
        max="5"
        value={value ?? 1}
        onChange={(event) => onChange(Number(event.target.value))}
      />
      {error && <p>{error}</p>}
    </div>
  )
}

<KiForm
  fields={[{ name: "rating", type: "text" }]}
  components={{ text: RatingField }}
/>

For the complete public API, see the exported TypeScript types: Field, KiFormProps, FormApi, KiTheme, and SubmitEndpointResult.


🎨 Theming (new in 2.1)

Pass visual tokens — they become --ki-* CSS variables on the form element:

<KiForm
  fields={["email", "password"]}
  theme={{
    accentColor: "#8b5cf6",
    radius: "12px",
    borderColor: "#334155"
  }}
/>

Available tokens: accentColor, borderColor, errorColor, helperColor, radius, surfaceColor, textColor, fontFamily. Defaults match the built-in styles, so no theme = zero visual change.


🧩 Zod Schema Generation (new in 2.1)

Generate a validation schema from the same field config — using your own zod:

import { KiForm } from "ki-forms"
import { buildZodSchema } from "ki-forms/zod"
import { z } from "zod"

const fields = [
  { name: "email", type: "email", required: true },
  { name: "company", showIf: { field: "role", equals: "Admin" } }
]

<KiForm
  fields={fields}
  schema={buildZodSchema(fields, {
    zod: z,
    requiredWhen: { company: { field: "role", equals: "Admin" } }
  })}
  onSubmit={save}
/>

requiredWhen reuses showIf semantics: the field becomes required exactly when it would be shown. Works with zod v3 and v4.


💬 Conversational Mode (new in 2.1)

One question at a time, Typeform-style — with a progress bar, Back/Next, Enter-to-advance, and automatic jump-back to a failing step:

<KiForm
  fields={fields}
  variant="conversational"
  stepLabels={{ next: "Continue", submit: "Send it" }}
  onSubmit={save}
/>

Hidden conditional fields are skipped automatically. Enter inside a textarea inserts a newline instead of advancing.


📥 Collect Responses (new in 2.2)

No backend? Add endpoint and every valid submit is POSTed as JSON — no server actions, no wiring:

<KiForm
  fields={fields}
  endpoint="https://script.google.com/macros/s/…/exec"
  submitLabel="Sign up"
/>
  • Payload: { values, meta }meta carries submittedAt, pageUrl, referrer, userAgent.
  • Built-in pending/success/error status line (fully re-labelable, or hide it with hideSubmitStatus).
  • Works with Formspree, Web3Forms, Basin, Discord/automation webhooks — anything that accepts a JSON POST.
  • Google Sheets with zero code: the Schema Studio generates a ~50-line Apps Script — paste it into your Sheet once, connect the /exec URL, and every submission lands as a row. (Apps Script can't answer CORS preflights, so ki-forms automatically sends those endpoints as text/plain — no config needed.)
  • onSubmit still fires as before; onSubmitted(result) reports the request outcome.

New props: endpoint, method (default POST), headers, submitLabel, submittingLabel, successLabel, errorLabel, hideSubmitStatus, onSubmitted.


⚖️ Comparison

Featureki-formsReact Hook Form
SetupZeroMedium
BoilerplateLowMedium
Dynamic formsBuilt-inManual
Learning curveVery LowMedium

Contributors

kadirulislam

21 commits

kadirulislam/ki-forms

KiForms - Build dynamic React forms from JSON — with zero setup.

TypeScript

0

21 commits

updated Sep 21, 2026

See the code

See what people are saying (1)

SourceMessageScoreDate

I built a visual form builder for React — Ki-forms Studio (r/reactjs)

I’ve been working on **Ki-forms**, a JSON-driven React form library, and today I built the first version of **Ki-forms Studio**. You can visually build a form, configure fields, preview it, and export the schema/code. The idea is to make dynamic React forms faster to build without taking control…

0

Sep 21, 2026

README

ki-forms

Build dynamic React forms from JSON — with zero setup.

Stop wiring forms manually. Define them as data.

Live Demo Schema Studio

Interactive playground — every feature (conditionals, themes, conversational mode, the live schema editor) running the real library. No install needed.

Schema Studio — design forms visually: drag-and-drop fields, edit properties with live preview, then copy the schema JSON or a ready-to-paste React component.


⚡ Quick Example

import { KiForm } from "ki-forms"
import "ki-forms/styles.css"

export default function App() {
  return (
    <KiForm
      fields={[
        "email",
        "password",
        {
          name: "role",
          options: ["User", "Admin"]
        },
        {
          name: "company",
          showIf: { field: "role", equals: "Admin" }
        }
      ]}
      onSubmit={(data) => console.log(data)}
    />
  )
}

🤯 The Problem

Building forms in React is repetitive and inefficient:

  • Managing state for every input
  • Handling validation manually
  • Writing conditional logic
  • Repeating boilerplate code

Even popular libraries like React Hook Form require setup and mental overhead.


✅ The Solution

ki-forms lets you build forms using simple JSON.

  • No manual state handling
  • No boilerplate
  • No complex configuration

Just describe your form → it renders automatically.


📦 Installation

npm install ki-forms

🚀 Basic Usage

import { KiForm } from "ki-forms"
import "ki-forms/styles.css"

<KiForm
  fields={["email", "password"]}
  onSubmit={(data) => console.log(data)}
/>

🧩 Field Configuration

{
  name: "email",
  type: "email", // "text" | "textarea" | "email" | "password" | "number" | "select" | "checkbox" | "tel" | "url" | "date"
  required: true,
  label: "Email",
  placeholder: "Enter your email",
  helperText: "We never share your email"
}

🔄 Conditional Fields

Show fields dynamically based on other values:

{
  name: "company",
  showIf: {
    field: "role",
    equals: "Admin"
  }
}

AND / OR groups (new in 2.1)

{
  name: "taxId",
  required: true,
  showIf: {
    all: [
      { field: "country", equals: "US" },
      { field: "plan", equals: "Pro" }
    ]
  }
}

Use all (every condition must match) or any (at least one). They combine with a top-level field condition via AND. Hidden fields skip validation.


🎯 Smart Defaults

ki-forms automatically:

  • Infers input types (email, password)
  • Generates labels (firstName → First Name)
  • Adds placeholders (Enter your email)
  • Converts simple strings into fields
fields={["email", "password"]}

🧠 Field Events

Run logic when field value changes:

{
  name: "role",
  options: ["User", "Admin"],
  onChange: (value, values) => {
    console.log("Selected:", value)
    console.log("All values:", values)
  }
}

🎨 Styling

Default styles included:

import "ki-forms/styles.css"

Override using className:

{
  name: "email",
  className: "my-custom-input"
}

⚙️ Advanced Usage

Use the form hook directly:

import { useKiForm, KiForm } from "ki-forms"

const form = useKiForm({
  fields: ["email", "password"]
})

<KiForm form={form} />

📋 Supported Features

  • JSON-based form builder
  • Conditional fields + AND/OR groups
  • Smart defaults
  • Theme tokens (CSS variables)
  • Zod schema generation
  • Minimal API
  • React + Next.js support
  • Extendable component system
  • Built-in UI

Supported field types

text, email, password, number, tel, url, date, textarea, select, and checkbox.

Custom field components

Replace or extend built-in renderers with the components prop. A custom component receives the field definition, current value, validation error, and an onChange callback:

function RatingField({ field, value, onChange, error }) {
  return (
    <div>
      <input
        type="range"
        min="1"
        max="5"
        value={value ?? 1}
        onChange={(event) => onChange(Number(event.target.value))}
      />
      {error && <p>{error}</p>}
    </div>
  )
}

<KiForm
  fields={[{ name: "rating", type: "text" }]}
  components={{ text: RatingField }}
/>

For the complete public API, see the exported TypeScript types: Field, KiFormProps, FormApi, KiTheme, and SubmitEndpointResult.


🎨 Theming (new in 2.1)

Pass visual tokens — they become --ki-* CSS variables on the form element:

<KiForm
  fields={["email", "password"]}
  theme={{
    accentColor: "#8b5cf6",
    radius: "12px",
    borderColor: "#334155"
  }}
/>

Available tokens: accentColor, borderColor, errorColor, helperColor, radius, surfaceColor, textColor, fontFamily. Defaults match the built-in styles, so no theme = zero visual change.


🧩 Zod Schema Generation (new in 2.1)

Generate a validation schema from the same field config — using your own zod:

import { KiForm } from "ki-forms"
import { buildZodSchema } from "ki-forms/zod"
import { z } from "zod"

const fields = [
  { name: "email", type: "email", required: true },
  { name: "company", showIf: { field: "role", equals: "Admin" } }
]

<KiForm
  fields={fields}
  schema={buildZodSchema(fields, {
    zod: z,
    requiredWhen: { company: { field: "role", equals: "Admin" } }
  })}
  onSubmit={save}
/>

requiredWhen reuses showIf semantics: the field becomes required exactly when it would be shown. Works with zod v3 and v4.


💬 Conversational Mode (new in 2.1)

One question at a time, Typeform-style — with a progress bar, Back/Next, Enter-to-advance, and automatic jump-back to a failing step:

<KiForm
  fields={fields}
  variant="conversational"
  stepLabels={{ next: "Continue", submit: "Send it" }}
  onSubmit={save}
/>

Hidden conditional fields are skipped automatically. Enter inside a textarea inserts a newline instead of advancing.


📥 Collect Responses (new in 2.2)

No backend? Add endpoint and every valid submit is POSTed as JSON — no server actions, no wiring:

<KiForm
  fields={fields}
  endpoint="https://script.google.com/macros/s/…/exec"
  submitLabel="Sign up"
/>
  • Payload: { values, meta }meta carries submittedAt, pageUrl, referrer, userAgent.
  • Built-in pending/success/error status line (fully re-labelable, or hide it with hideSubmitStatus).
  • Works with Formspree, Web3Forms, Basin, Discord/automation webhooks — anything that accepts a JSON POST.
  • Google Sheets with zero code: the Schema Studio generates a ~50-line Apps Script — paste it into your Sheet once, connect the /exec URL, and every submission lands as a row. (Apps Script can't answer CORS preflights, so ki-forms automatically sends those endpoints as text/plain — no config needed.)
  • onSubmit still fires as before; onSubmitted(result) reports the request outcome.

New props: endpoint, method (default POST), headers, submitLabel, submittingLabel, successLabel, errorLabel, hideSubmitStatus, onSubmitted.


⚖️ Comparison

Featureki-formsReact Hook Form
SetupZeroMedium
BoilerplateLowMedium
Dynamic formsBuilt-inManual
Learning curveVery LowMedium

Contributors

kadirulislam

21 commits

Languages

TypeScript

96.6%

CSS

3.2%