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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@diludilshad/form-builder-library

v1.0.9

Published

A powerful React library for building dynamic, drag-and-drop forms with a rich set of field types and customization options. Uses Tailwind CSS classes - requires Tailwind CSS as a peer dependency in your project.

Readme

Form Builder Library

A powerful React library for building dynamic, drag-and-drop forms with a rich set of field types and customization options. Uses Tailwind CSS classes - requires Tailwind CSS as a peer dependency in your project.

Features

  • 🎨 Visual Form Builder - Drag and drop interface for creating forms
  • 📝 Rich Field Types - 25+ field types including text, numbers, choices, dates, uploads, and more
  • 🔧 Field Customization - Extensive settings for each field type
  • 👀 Real-time Preview - See your form as users will see it
  • 📱 Responsive Design - Works perfectly on desktop and mobile
  • 💾 Local Storage - Automatic form persistence
  • 🎯 Form Validation - Built-in validation rules and custom logic
  • 🎨 Icon Support - Choose from 30+ icons for each field
  • 🎨 Tailwind CSS - Uses Tailwind utility classes for styling
  • 📦 Minimal Dependencies - Only React, React DOM, and Tailwind CSS required

Installation

npm install @diludilshad/form-builder-library

Prerequisites

This library requires Tailwind CSS to be installed and configured in your project. If you haven't already set up Tailwind CSS, follow these steps:

  1. Install Tailwind CSS:
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
  1. Configure your tailwind.config.js:
/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
    // Add this line to scan the form builder library
    "./node_modules/@diludilshad/form-builder-library/**/*.{js,jsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
};
  1. Add Tailwind directives to your CSS:
@tailwind base;
@tailwind components;
@tailwind utilities;

Why Peer Dependency?

The Form Builder Library uses Tailwind CSS classes for styling. By using Tailwind as a peer dependency instead of bundling it:

  • No Style Conflicts - Avoids duplicate Tailwind base styles
  • Consistent Theming - Components use your project's Tailwind configuration
  • Smaller Bundle Size - No duplicate CSS utilities
  • Customization - Easy to customize colors, spacing, and other design tokens

Using in Your Project

Step 1: Create a New React Project

# Create a new React project
npx create-react-app my-form-app
cd my-form-app

# Or with Vite (recommended)
npm create vite@latest my-form-app -- --template react
cd my-form-app
npm install

Step 2: Install Dependencies

# Install the form builder library
npm install @diludilshad/form-builder-library

# Install required peer dependencies
npm install tailwindcss postcss autoprefixer

Step 3: Setup Tailwind CSS

# Initialize Tailwind
npx tailwindcss init -p

Update your tailwind.config.js:

/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
    // IMPORTANT: Include the form builder library
    "./node_modules/@diludilshad/form-builder-library/**/*.{js,jsx}",
  ],
  theme: {
    extend: {
      // You can extend the theme to customize form builder appearance
      colors: {
        primary: {
          50: "#eff6ff",
          500: "#3b82f6",
          600: "#2563eb",
          700: "#1d4ed8",
        },
      },
    },
  },
  plugins: [],
};

Add to your src/index.css:

@tailwind base;
@tailwind components;
@tailwind utilities;

Step 4: Basic Implementation

Create src/App.jsx:

import React, { useState } from "react";
import { BuilderForm, FormReader } from "@diludilshad/form-builder-library";

function App() {
  const [currentView, setCurrentView] = useState("builder");
  const [form, setForm] = useState({
    name: "",
    type: "",
    description: "",
    structure: [],
    formsRules: [],
  });

  const handleSave = (formData) => {
    console.log("Form saved:", formData);
    setForm(formData);
    // Here you would typically save to your backend
  };

  const handleFormSubmit = (values) => {
    console.log("Form submitted:", values);
    // Handle form submission
  };

  return (
    <div className="min-h-screen bg-gray-100">
      {/* Navigation */}
      <nav className="bg-white shadow-sm border-b px-6 py-4">
        <div className="flex space-x-4">
          <button
            onClick={() => setCurrentView("builder")}
            className={`px-4 py-2 rounded-md ${
              currentView === "builder"
                ? "bg-blue-500 text-white"
                : "bg-gray-200 text-gray-700"
            }`}
          >
            Form Builder
          </button>
          <button
            onClick={() => setCurrentView("reader")}
            className={`px-4 py-2 rounded-md ${
              currentView === "reader"
                ? "bg-blue-500 text-white"
                : "bg-gray-200 text-gray-700"
            }`}
            disabled={!form.structure?.length}
          >
            Form Preview
          </button>
        </div>
      </nav>

      {/* Content */}
      {currentView === "builder" ? (
        <BuilderForm
          editFormId="demo-form"
          form={form}
          setForm={setForm}
          onSave={handleSave}
        />
      ) : (
        <div className="p-6">
          <div className="max-w-2xl mx-auto bg-white rounded-lg shadow-sm p-6">
            <FormReader
              formData={form}
              onSubmit={handleFormSubmit}
              onFieldChange={(fieldId, value) => {
                console.log(`Field ${fieldId} changed:`, value);
              }}
            />
          </div>
        </div>
      )}
    </div>
  );
}

export default App;

Quick Start

Basic Form Builder

import React, { useState } from "react";
import { BuilderForm } from "@diludilshad/form-builder-library";

function App() {
  const [form, setForm] = useState({
    name: "",
    type: "",
    description: "",
    structure: [],
    formsRules: [],
  });

  const handleSave = (formData) => {
    console.log("Form saved:", formData);
    setForm(formData);
  };

  return (
    <BuilderForm
      editFormId="my-form-1"
      form={form}
      setForm={setForm}
      onSave={handleSave}
    />
  );
}

Form Reader (Display Forms)

import React from "react";
import { FormReader } from "@diludilshad/form-builder-library";

function FormDisplay() {
  const formData = {
    name: "Contact Form",
    description: "Please fill out this contact form",
    structure: [
      {
        id: "name",
        type: "single-line",
        label: "Full Name",
        placeholder: "Enter your full name",
        required: true,
        selectedIcon: "person",
      },
      {
        id: "email",
        type: "email",
        label: "Email Address",
        placeholder: "Enter your email",
        required: true,
        selectedIcon: "mail",
      },
    ],
  };

  const handleSubmit = (values) => {
    console.log("Form submitted:", values);
  };

  return (
    <FormReader
      formData={formData}
      onSubmit={handleSubmit}
      onFieldChange={(fieldId, value) => console.log(fieldId, value)}
    />
  );
}

Components

BuilderForm

The main form builder component with drag-and-drop functionality.

Props

| Prop | Type | Required | Default | Description | | ------------ | -------- | -------- | ------- | ---------------------------------------------------------- | | editFormId | string | Yes | - | Unique identifier for the form (used for localStorage key) | | form | object | Yes | - | Current form state object | | setForm | function | Yes | - | Function to update form state | | onSave | function | No | - | Callback function called when form is saved |

Form Object Structure

{
  name: string,           // Form name
  type: string,           // Form type
  description: string,    // Form description
  structure: array,       // Array of form fields
  formsRules: array       // Array of validation rules
}

FormReader

Component for displaying and collecting data from forms.

Props

| Prop | Type | Required | Default | Description | | ------------------ | -------- | -------- | -------- | ------------------------------------ | | formData | object | Yes | - | Form data object with structure | | onSubmit | function | Yes | - | Called when form is submitted | | onFieldChange | function | No | - | Called when any field value changes | | initialValues | object | No | {} | Initial values for form fields | | customSubmitText | string | No | "Submit" | Custom submit button text | | customCancelText | string | No | "Cancel" | Custom cancel button text | | onCancel | function | No | - | Called when cancel button is clicked | | className | string | No | "" | Additional CSS classes | | formRules | array | No | [] | Form validation rules |

FormPreview

Component for previewing forms in builder mode.

Props

| Prop | Type | Required | Default | Description | | --------------- | -------- | -------- | ------- | ------------------------------- | | formFields | array | Yes | - | Array of form fields | | previewData | object | No | {} | Preview data | | isTestMode | boolean | No | false | Whether in test mode | | formRules | array | No | [] | Form validation rules | | onExit | function | Yes | - | Called when exiting preview | | onSubmit | function | Yes | - | Called when form is submitted | | onFieldUpdate | function | No | - | Called when field values change |

Field Types

Basic Information Fields

  • Name (name) - Person icon, blue color
  • Address (address) - Location icon, green color
  • Phone (phone) - Call icon, purple color
  • Email (email) - Mail icon, red color
  • Website (website) - Globe icon, indigo color

Text Fields

  • Single Line (single-line) - Document icon, orange color
  • Dynamic Single Line (dynamic-single-line) - Document icon, orange color
  • Multi Line (multi-line) - Reader icon, teal color
  • Rich Text (rich-text) - Options icon, indigo color

Number Fields

  • Number (number) - 123 icon, purple color
  • Decimal (decimal) - .00 icon, emerald color
  • Formula (formula) - fx icon, pink color
  • Currency (currency) - Wallet icon, yellow color

Choice Fields

  • Dropdown (dropdown) - Chevron down icon, blue color
  • Radio (radio) - Radio button icon, green color
  • Checkbox (checkbox) - Checkbox icon, purple color
  • Multiple Choice (multiple-choice) - List icon, teal color
  • Image Choices (image-choices) - Images icon, pink color
  • Matrix Choice (matrix-choice) - Grid icon, indigo color
  • Table (table) - Grid icon, orange color

Date & Time Fields

  • Date (date) - Calendar icon, orange color
  • Time (time) - Time icon, blue color
  • Date-Time (date-time) - Calendar clear icon, green color
  • Month-Year (month-year) - MY icon, amber color

Upload Fields

  • File Upload (file-upload) - Document attach icon, green color
  • Image Upload (image-upload) - Cloud upload icon, teal color
  • Audio/Video Upload (audio-video-upload) - Musical notes icon, purple color

Rating & Scale Fields

  • Rating (rating) - Star icon, yellow color
  • Slider (slider) - Options icon, pink color

Layout Fields

  • Section (section-header) - Remove icon, gray color

Field Structure

Each field in the form structure has the following properties:

{
  id: string,                    // Unique field identifier
  type: string,                  // Field type (see above)
  label: string,                 // Field label
  placeholder: string,           // Field placeholder text
  required: boolean,             // Whether field is required
  selectedIcon: string,          // Icon identifier
  iconColor: string,             // Icon color class
  options: array,                // Options for choice fields
  validation: object,            // Field-specific validation rules
  settings: object,              // Field-specific settings
  // ... other field-specific properties
}

Form Rules

Form rules allow you to create conditional logic and validation:

{
  id: string,                    // Unique rule identifier
  name: string,                  // Rule name
  conditions: array,             // Array of conditions
  actions: array,                // Array of actions
  enabled: boolean               // Whether rule is active
}

LocalStorage Persistence

The BuilderForm component automatically saves form data to localStorage using the editFormId as the key:

localStorage.setItem(`form_${editFormId}`, JSON.stringify(formData));

Available Icons

The library includes 30+ icons from react-icons/io5:

  • person, location, call, mail, globe
  • document, reader, wallet, calendar, time
  • business, briefcase, home, car, airplane
  • train, bus, restaurant, shirt, ticket
  • id-card, checkmark, heart, music, camera
  • game, book, school, medical, fitness
  • palette

Examples

Complete Example with Both Builder and Reader

import React, { useState } from "react";
import { BuilderForm, FormReader } from "@diludilshad/form-builder-library";

function FormBuilderApp() {
  const [formData, setFormData] = useState(null);
  const [isBuilderMode, setIsBuilderMode] = useState(true);
  const [formValues, setFormValues] = useState({});

  const handleSaveForm = (formData) => {
    console.log("Form saved:", formData);
    setFormData(formData);
  };

  const handleFormSubmit = (values) => {
    console.log("Form submitted:", values);
    setFormValues(values);
    alert("Form submitted successfully!");
  };

  return (
    <div className="min-h-screen bg-gray-50">
      <div className="max-w-7xl mx-auto py-8 px-4">
        <div className="text-center mb-8">
          <h1 className="text-3xl font-bold text-gray-900 mb-4">
            Form Builder Library
          </h1>

          <div className="flex justify-center space-x-4 mb-8">
            <button
              onClick={() => setIsBuilderMode(true)}
              className={`px-4 py-2 rounded-md font-medium ${
                isBuilderMode
                  ? "bg-blue-600 text-white"
                  : "bg-white text-gray-700 border border-gray-300 hover:bg-gray-50"
              }`}
            >
              Builder Mode
            </button>
            <button
              onClick={() => setIsBuilderMode(false)}
              className={`px-4 py-2 rounded-md font-medium ${
                !isBuilderMode
                  ? "bg-blue-600 text-white"
                  : "bg-white text-gray-700 border border-gray-300 hover:bg-gray-50"
              }`}
            >
              Reader Mode
            </button>
          </div>
        </div>

        {isBuilderMode ? (
          <BuilderForm
            editFormId="example-form"
            form={
              formData || {
                name: "",
                type: "",
                description: "",
                structure: [],
                formsRules: [],
              }
            }
            setForm={setFormData}
            onSave={handleSaveForm}
          />
        ) : (
          formData && (
            <div className="max-w-2xl mx-auto">
              <FormReader
                formData={formData}
                onSubmit={handleFormSubmit}
                onFieldChange={(fieldId, value) =>
                  console.log("Field changed:", fieldId, value)
                }
              />
            </div>
          )
        )}
      </div>
    </div>
  );
}

export default FormBuilderApp;

Custom Form with Validation

import React from "react";
import { FormReader } from "@diludilshad/form-builder-library";

function CustomForm() {
  const formData = {
    name: "Registration Form",
    description: "Please complete your registration",
    structure: [
      {
        id: "fullName",
        type: "single-line",
        label: "Full Name",
        placeholder: "Enter your full name",
        required: true,
        selectedIcon: "person",
        validation: {
          minLength: 2,
          maxLength: 50,
          pattern: "^[a-zA-Z\\s]+$",
        },
      },
      {
        id: "email",
        type: "email",
        label: "Email Address",
        placeholder: "Enter your email",
        required: true,
        selectedIcon: "mail",
        validation: {
          pattern: "^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$",
        },
      },
      {
        id: "country",
        type: "dropdown",
        label: "Country",
        placeholder: "Select your country",
        required: true,
        selectedIcon: "location",
        options: [
          { value: "us", label: "United States" },
          { value: "uk", label: "United Kingdom" },
          { value: "ca", label: "Canada" },
          { value: "au", label: "Australia" },
        ],
      },
    ],
  };

  const formRules = [
    {
      id: "email-validation",
      name: "Email Validation",
      conditions: [
        {
          fieldId: "email",
          operator: "contains",
          value: "@",
        },
      ],
      actions: [
        {
          type: "show_field",
          fieldId: "fullName",
        },
      ],
      enabled: true,
    },
  ];

  return (
    <FormReader
      formData={formData}
      formRules={formRules}
      onSubmit={(values) => {
        console.log("Registration submitted:", values);
        // Handle form submission
      }}
      onFieldChange={(fieldId, value) => {
        console.log(`${fieldId} changed to:`, value);
      }}
      customSubmitText="Register"
      customCancelText="Back"
    />
  );
}

Development

Prerequisites

  • Node.js >= 16.0.0
  • React >= 18.0.0
  • React DOM >= 18.0.0

Installation

git clone https://github.com/diludilshad/form-builder-library.git
cd form-builder-library
npm install

Development Server

npm run dev

Building

npm run build

Type Checking

npm run type-check

Linting

npm run lint

Advanced Usage & Integration

Backend Integration

Saving Forms to Database

import React, { useState, useEffect } from "react";
import { BuilderForm } from "@diludilshad/form-builder-library";

function FormBuilderPage() {
  const [form, setForm] = useState(null);
  const [loading, setLoading] = useState(true);

  // Load existing form
  useEffect(() => {
    const loadForm = async () => {
      try {
        const response = await fetch("/api/forms/123");
        const formData = await response.json();
        setForm(formData);
      } catch (error) {
        console.error("Failed to load form:", error);
        setForm({
          name: "",
          type: "",
          description: "",
          structure: [],
          formsRules: [],
        });
      } finally {
        setLoading(false);
      }
    };

    loadForm();
  }, []);

  const handleSave = async (formData) => {
    try {
      const response = await fetch("/api/forms/123", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(formData),
      });

      if (response.ok) {
        console.log("Form saved successfully!");
        setForm(formData);
      }
    } catch (error) {
      console.error("Failed to save form:", error);
    }
  };

  if (loading) return <div className="p-6">Loading...</div>;

  return (
    <BuilderForm
      editFormId="form-123"
      form={form}
      setForm={setForm}
      onSave={handleSave}
    />
  );
}

Processing Form Submissions

import React from "react";
import { FormReader } from "@diludilshad/form-builder-library";

function PublicForm({ formId }) {
  const [formData, setFormData] = useState(null);

  useEffect(() => {
    fetch(`/api/forms/${formId}/public`)
      .then((res) => res.json())
      .then(setFormData);
  }, [formId]);

  const handleSubmit = async (values) => {
    try {
      const response = await fetch(`/api/forms/${formId}/submissions`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          formId,
          submittedAt: new Date().toISOString(),
          values,
        }),
      });

      if (response.ok) {
        alert("Form submitted successfully!");
      }
    } catch (error) {
      console.error("Submission failed:", error);
      alert("Failed to submit form. Please try again.");
    }
  };

  if (!formData) return <div>Loading form...</div>;

  return (
    <div className="max-w-2xl mx-auto p-6">
      <FormReader
        formData={formData}
        onSubmit={handleSubmit}
        onFieldChange={(fieldId, value) => {
          // Optional: Auto-save draft
          localStorage.setItem(
            `draft_${formId}`,
            JSON.stringify({
              ...JSON.parse(localStorage.getItem(`draft_${formId}`) || "{}"),
              [fieldId]: value,
            })
          );
        }}
      />
    </div>
  );
}

Framework Integration

Next.js Setup

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  transpilePackages: ["@diludilshad/form-builder-library"],
};

module.exports = nextConfig;
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./components/**/*.{js,ts,jsx,tsx,mdx}",
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
    // Include form builder library
    "./node_modules/@diludilshad/form-builder-library/**/*.{js,jsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
};

Vite Setup

// vite.config.js
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react()],
  optimizeDeps: {
    include: ["@diludilshad/form-builder-library"],
  },
});

Custom Styling & Theming

Override Default Colors

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        // Override primary colors used by form builder
        primary: {
          50: "#fdf2f8",
          500: "#ec4899", // Pink instead of blue
          600: "#db2777",
          700: "#be185d",
        },
      },
    },
  },
};

Custom CSS Classes

/* src/index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
  /* Customize form builder styles */
  .form-builder-container {
    @apply bg-gradient-to-br from-purple-50 to-pink-50;
  }

  .form-field-item {
    @apply border-purple-200 hover:border-purple-400;
  }

  .form-builder-button {
    @apply bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-700 hover:to-pink-700;
  }
}

State Management Integration

Redux Integration

import { useSelector, useDispatch } from "react-redux";
import { BuilderForm } from "@diludilshad/form-builder-library";
import { updateForm, saveForm } from "./store/formSlice";

function ReduxFormBuilder() {
  const dispatch = useDispatch();
  const form = useSelector((state) => state.forms.currentForm);

  return (
    <BuilderForm
      editFormId="redux-form"
      form={form}
      setForm={(formData) => dispatch(updateForm(formData))}
      onSave={(formData) => dispatch(saveForm(formData))}
    />
  );
}

Performance Optimization

Lazy Loading

import React, { lazy, Suspense } from "react";

// Lazy load the form builder
const BuilderForm = lazy(() =>
  import("@diludilshad/form-builder-library").then((module) => ({
    default: module.BuilderForm,
  }))
);

function App() {
  return (
    <Suspense fallback={<div className="p-6">Loading Form Builder...</div>}>
      <BuilderForm {...props} />
    </Suspense>
  );
}

Troubleshooting

Common Issues

1. Styles not applying:

# Make sure Tailwind is scanning the library
# Check your tailwind.config.js includes:
"./node_modules/@diludilshad/form-builder-library/**/*.{js,jsx}"

2. TypeScript errors:

// Add to your tsconfig.json
{
  "compilerOptions": {
    "moduleResolution": "node",
    "skipLibCheck": true
  }
}

3. Build errors in production:

// For Webpack-based builds, add to webpack.config.js
module.exports = {
  resolve: {
    alias: {
      "@diludilshad/form-builder-library": require.resolve(
        "@diludilshad/form-builder-library"
      ),
    },
  },
};

Browser Support

  • Chrome >= 88
  • Firefox >= 85
  • Safari >= 14
  • Edge >= 88

License

MIT License - see LICENSE file for details.

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Support

Changelog

v1.0.5

  • Added 30+ field types
  • Improved drag and drop functionality
  • Enhanced form validation
  • Added icon support
  • Bundled Tailwind CSS
  • Zero additional dependencies

Made with ❤️ by Dilshad