npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

red-form

v1.0.28

Published

A powerful, type-safe React form library that lets you create dynamic dialog-based forms using schema definitions — inspired by Formik but designed for real-time UI rendering and reusability.

Readme

red form code snippet

🟥 Red Form

Schema-driven React form system that builds entire UI — no HTML, no CSS. Define once. Render anywhere. Fully typed, flexible, and lightning-fast.



red form code snippet

🚀 Why RED FORM?

Building forms in React often means juggling inputs, styles, and validation logic for every single field. Red Form solves that by letting you define the schema only once — it automatically generates the UI, handles validation, manages state, and aligns everything perfectly.

You get developer clarity, instant layout, and zero boilerplate.


✨ Features

  • 🧱 Schema-driven – define once, render everywhere
  • 🎨 No HTML/CSS needed – automatic layout, focus, hover, spacing, and shadows
  • ⚙️ Type-safe – fully typed schema and form instance
  • 🧩 Extensible – inject custom components and validation logic
  • 🚀 Optimized – minimal re-renders, built for scalability
  • 💡 Declarative logic – dynamic visibility and branching made easy
  • 🪶 Extreamly Light Weight – 56kb package can save your multiple hours
  • 🪲Low Code - Low or Less code means less chance of BUG.

📦 Installation

npm install red-form
# or
yarn add red-form

🧩 Example 1 — Create Product Form

A simple and elegant example showing Red Form’s minimal setup.

import Form, { create } from "red-form";
import "red-form/dist/index.css";

const productForm = create({
  name: {
    label: "Product Name",
    component: "text",
    value: "",
    required: true
  },
  category: {
    label: "Category",
    component: "select",
    options: ["Electronics", "Clothing", "Books", "Other"],
    value: "",
    required: true
  },
  price: {
    label: "Price ($)",
    component: "number",
    value: 0,
    min: 0,
    required: true
  },
  available: {
    label: "In Stock",
    component: "switch",
    value: true
  },
  description: {
    label: "Description",
    component: "textarea",
    value: "",
    span: 12
  }
});

export default function CreateProduct() {
  return (
    <Form title="Add New Product" description="Fill in the details below to list your product." schema={productForm} onSubmit={values => alert(JSON.stringify(values, null, 2))} />
  );
}

⚙️ Example 2 — Dynamic Form + Custom Component

Dynamic field rendering and asynchronous file uploads — all declaratively.

import Form, { create } from "red-form";

const schema = create({
  title: {
    label: "Project Title",
    component: "text",
    value: "",
    required: true
  },
  category: {
    label: "Category",
    component: "select",
    options: ["Web", "Mobile", "AI", "IoT"],
    value: "",
    required: true
  },
  image: {
    label: "Cover Image",
    component: "image",
    value: "",
    onSelect: async file => {
      const reader = new FileReader();
      return new Promise(resolve => {
        reader.onloadend = () => resolve(reader.result as string);
        reader.readAsDataURL(file);
      });
    }
  },
  isPrivate: {
    label: "Private Project",
    component: "switch",
    value: false
  },
  password: {
    label: "Access Password",
    component: "password",
    value: "",
    hidden: form => !form.values.isPrivate
  },
  customFooter: {
    label: "Custom Note",
    component: "custom",
    inputBase: false,
    render: () => (
      <div style={{ padding: 12, background: "#f5f5f5", borderRadius: 6 }}>
        <small>All fields are auto-validated before submit ✅</small>
      </div>
    ),
    span: 12
  }
});

export default function ProjectForm() {
  return <Form title="New Project" description="Quickly configure and submit your project details." schema={schema} onSubmit={values => console.log("Submitted:", values)} />;
}

👩‍💼 Example 3 — Job Application Form (Real-world)

A large, production-grade form built entirely through schema configuration.

import Form, { create } from "red-form";

export default function JobApplication() {
  const schema = create({
    name: {
      label: "Name",
      component: "text",
      value: "",
      autoFill: "name",
      required: true,
      max: 20
    },
    email: {
      label: "Email",
      component: "text",
      value: "",
      autoFill: "email",
      required: true,
      max: 30
    },
    phone: {
      label: "Phone",
      component: "text",
      value: "",
      autoFill: "home tel",
      required: true,
      max: 10
    },
    address: {
      label: "Address",
      component: "text",
      value: "",
      autoFill: "address-line1",
      required: true,
      max: 20
    },
    city: {
      label: "City",
      component: "text",
      value: "",
      autoFill: "address-level3",
      required: true,
      max: 20
    },
    district: {
      label: "District",
      component: "text",
      value: "",
      autoFill: "address-level2",
      required: true,
      max: 20
    },
    state: {
      label: "State",
      component: "text",
      value: "",
      autoFill: "address-level3",
      required: true,
      max: 20
    },
    zipcode: {
      label: "Pincode",
      component: "text",
      value: "",
      autoFill: "postal-code",
      required: true,
      max: 6
    },
    role: {
      label: "Role",
      component: "search",
      value: "",
      options: ["frontend", "backend", "sales", "bidder", "analyst", "architect", "DBA"],
      required: true
    },
    gender: {
      label: "Gender",
      component: "radio",
      value: "",
      options: ["Male", "Female", "Other"]
    },
    qualification: {
      label: "Highest Qualification",
      component: "checkbox",
      value: "", // INITIAL VALUE BLANK QUOTE ON CHECKBOX COMPONENT WILL ALLOW SINGLE CHECK AT A TIME.
      options: ["Diploma", "B.Tech", "M.Tech"],
      required: true
    },
    site: {
      label: "Preferred Site (multi select)",
      component: "checkbox",
      value: [], // INITIAL VALUE BLANK ARRAY ON CHECKBOX COMPONENT WILL ALLOW MULTI SELECT.
      options: ["on-site", "remote"],
      required: true
    },
    skills: {
      label: "Skills",
      component: "multi-select",
      value: [],
      span: 12,
      options: ["react", "angular", "node.js", "php"],
      required: true
    },
    comment: {
      label: "Comment",
      component: "textarea",
      value: "",
      span: 12
    }
  });

  return (
    <div className="border-3 border-border-strong border-solid px-6 py-8 rounded-lg">
      <Form title="Job Application" description="Please fill all the details carefully." schema={schema} onSubmit={values => console.log(values)} />
    </div>
  );
}

👩‍💼 Example 4 — LogIn Form Schema (Real-world)

const schema = create({
  username: {
    label: "username",
    component: "text",
    value: "",
    autoFill: "email",
    required: true
  },
  password: {
    label: "password",
    component: "password",
    value: "",
    required: true
  }
});

👩‍💼 Example 5 — SignUp Form Schema (Real-world)

const schema = create({
  name: {
    label: "Name",
    component: "text",
    value: "",
    autoFill: "name",
    required: true
  },
  email: {
    label: "email",
    component: "text",
    value: "",
    autoFill: "email",
    required: true
  },
  password: {
    label: "password",
    component: "password",
    value: "",
    required: true
  }
});

🧩 This example demonstrates:

  • 10+ field types (text, select, radio, checkbox, switch, textarea, search, etc.)
  • Built-in autoFill support
  • Multi-column layout via span
  • Zero external UI dependency — all styling and alignment handled by Red Form

red form code snippet


🧩 Components


💎 Common Props available in all components


{
 label: string;
  required?: boolean;
  placeholder?: string;
  helperText?: ReactNode;
  information?: string;
  disabled?: boolean;
  span?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
  validate?: ({ field, props, form }) => string[];
  hidden?: boolean;
  adorment?: Adorment;
}

Label is always mandatory.

🛡️ Validate Function

The validate function expects from you to return string of array.


const schema = create({
	field: {
		component: "text";
		value: "",
		validate: ({field, props, form})=>{
			const errors:string[] = [];
			const value = form.values[field];
			if(!value.startsWith('http')) errors.push(`${props.label} must start with "http".`)
			return errors;
		}
	}
})

ⓘ Information

The content of information will be shown as tooltip at the side of label.

🤝 Helper Text

The content of helperText will be shown as below the input field.

🚫 Disabled

if disabled is true then field will become readOnly can't edit that field.

👻 Hidden

if hidden is true then field will not shown in the form can be used in spacial cases.

🤔 Placeholder

The content of placeholder will be shown... Ok just guese it, I am not telling this.

📿Adorment

Through Adorment You can add some element like button, icons, div at the start or end of the INPUT field.

{
  start?: ReactNode ;
  end?: ReactNode ;
}

🗒️Text

Text field is most commonly used to handel single line string value input.

{
   component: "text";
  value: string; // Initial Value
  autoFill?: AutoFillField; // Browser supported AutoFill
  min?: number;  // minimum length
  max?: number; // maximum length
}

🖹 TextArea

Text Area is just a multiline text field.

{
   component: "textarea";
  value: string; // Initial Value
  min?: number;  // minimum length
  max?: number; // maximum length
  span: 12;
}

🖹 Number

In Number Field you can only enter number.

{
   component: "number";
  value: number; // Initial Value
  min?: number;  // minimum value
  max?: number; // maximum value
  step?: number; // per step value
}

🔑 Password

It rendered as password field, you can't see entered value.

{
   component: "password";
  value: string; // Initial Value
  min?: number;  // minimum value
  max?: number; // maximum value
}

🔽 Select

Select prop will be renderd as dropdown field.

{
  component: "select";
  value: string | number; // Initial Value
  options: Option[]; // string[] or {label: string; value: string | number}[]
  reloadOptions?: boolean;
}

🔍 Search

Search Field is a dropdown which is searchable.

{
  component: "search";
  value: string | number; // Initial Value
  autoFill?: AutoFillField; // Same Browser AutoFIlls
  options: Option[]; // string[] or {label: string; value: string | number}[]
  reloadOptions?: boolean;
}

🏷️ Tags

Tags can hold multiple user entered string values.

{
  component: "tags";
  value: string[]; // Initial Value
  min?: number;  // minimum value
  max?: number; // maximum value
}

🔽🔍 Multi Select

Multi-Select is mixture of tags and search field, can pick searchable multiple values.

{
  component: "multi-select";
  value: string[]; // Initial Value
  options: Option[]; // string[] or {label: string; value: string | number}[]
  min?: number;  // minimum number of selected values
  max?: number; // maximum number of selected values
}

⇆ Switch

Switch are toogle button commonly used to pick boolean values.

{
  component: "switch";
  value: boolean; // Initial Value
}

🔴 Radio

Radio Group is used pick single value from option. good for 2 or 3 values.

{
  component: "radio";
  value: string;
  direction?: "row" | "column";
  options: Option[]; // string[] or {label: string; value: string | number}[]
}

─•──── Range

Range component will be rendered as a slider.

{
   component: "range";
  value: number; // Initial Value
  min?: number;  // minimum value
  max?: number; // maximum value
  step?: number; // per step value
}

🌈 Color

{
   component: "color";
  value: string[]; // Initial Value (#ffffff, #ff0000)
}

🌄 Image

In image component you have to add onSelect prop to handel picked file and convert it into url.

{
   component: "image";
  value: string; // Initial Value ( link or dataurl)
  onSelect: (file: File) => Promise<string>; The uploader function
}

✅ Checkbox Single Value

{
  component: "checkbox";
  value: string | undefined;
  direction?: "row" | "column"; // default "row"
  options:  Option[]; // string[] or { label: string; value: string | number }[]
}

✅✅ Checkbox Multi Value

{
  component: "checkbox";
  value: string[]; // initial value must be string of array.
  direction?: "row" | "column"; // default "row"
  options:  Option[]; // string[] or { label: string; value: string | number }[]
}

📅 Date

The value pattern of Date is 2025-11-02 (YYYY-MM-DD).

{
  component: "date";
  value: "";
  min?: string;
  max?: string;
}

📅🕘 Date Time

The value pattern of Date Time is 2025-11-02T14:20 (YYYY-MM-DDTHH:mm).

{
  component: "datetime";
  value: "";
  min?: string;
  max?: string;
}

🕘 Time

The value pattern of time is 13:26 (HH:mm)

{
  component: "time";
  value: "";
  min?: string;
  max?: string;
}

📅 Week

The value pattern of week is 2025-32 (YYYY-WW) for 32th week of 2025.

{
  component: "week";
  value: "";
  min?: string;
  max?: string;
}

🗓 Month

The value pattern of Month is 2025-04 (YYYY-MM) for April.

{
  component: "month";
  value: "";
  min?: string;
  max?: string;
}

✨ Custom

Custom component will allow you to render anything in place of the form field.

{
  component: "custom";
  value?: any;
  inputBase?: boolean;
  render: ({ field, props, form }) => ReactNode;
}

🎨 Styling with sx

<Form
  schema={schema}
  sx={{
    title: { color: "#e11d48", fontWeight: 700 },
    submitButton: { background: "#e11d48", color: "#fff" },
    inputBase: { borderRadius: 8, borderColor: "#ddd" }
  }}
/>

🧑‍💻 Author

Manish Gun 💻 GitHub • 🌐 Website • ✉️ [email protected]


🪪 License

MIT © Manish Gun