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

@formdata/parser

v1.141.0

Published

Form-Data text form definition parser

Readme

@formdata/parser

A specialized parser for Form-Data text-based form definitions. This package converts the .fd format into structured JSON that can be used to render forms.

Installation

npm install @formdata/parser

Features

  • 📋 Simple Syntax: Parse the human-readable .fd format
  • 🧩 Form Structure: Convert form definitions into structured objects
  • ⚠️ Error Handling: Detailed error reporting for validation
  • 🔍 Diagnostics: Editor-compatible diagnostics for IDEs
  • 📐 Extensible: Supports numerous input types and validations

Usage

import { parseFormDefinition } from '@formdata/parser';

// Form definition in .fd format
const formContent = `
type form
name Contact form
action https://example.com/submit
message Thank you for your message!
design
    theme light
    background #f5f5f5

type h1
text Contact Us

type text
name full_name
label Full Name
placeholder Enter your name
validations required|length:3,50

type email
name email_address
label Email Address
placeholder [email protected]
validations required|email

type submit
label Send Message
`;

// Parse the definition
const result = parseFormDefinition(formContent);

console.log(result.name); // "Contact form"
console.log(result.endpoint); // "https://example.com/submit"
console.log(result.blocks); // Array of form elements
console.log(result.errors); // Array of any parsing errors

Form Definition Format

The .fd format uses a simple syntax with indentation for nesting:

Basic Structure

type <block_type>
property1 value1
property2 value2
nested_property
    key1 value1
    key2 value2

Example Form

type form
name my_contact_form
action https://example.com/submit
message Thank you for contacting us!
design
    theme light
    background #f5f5f5

type h1
text Contact Us

type text
name full_name
label Full Name
placeholder Enter your full name
validations required|length:3,50

type email
name email
label Email Address
placeholder [email protected]
validations required|email

type submit
label Send Message

Supported Block Types

| Block Type | Description | |-----------------|-----------------------| | form | The root form element | | step | Multi-step form step | | h1 to h6 | Heading elements | | text | Text input field | | email | Email input field | | tel | Telephone input field | | date | Date input field | | textarea | Multiline text area | | select | Dropdown select field | | cards | pick a card | | radio | Radio button group | | checkbox | Single checkbox | | checkboxGroup | Group of checkboxes | | file | File upload field | | slider | Range slider input | | rating | Star rating input | | signature | Signature pad input | | button | Generic button | | submit | Submit button | | variable | Computed variable | | hidden | Hidden form field | | tag | Third-party tags (GTM, Facebook Pixel, etc.) |

Common Properties

Most form elements support these properties:

| Property | Description | |----------|-------------| | name | Field name (used in form submission) | | label | Display label for the field | | placeholder | Placeholder text | | validations | Validation rules separated by pipe (\|) | | default | Default value | | help | Help text displayed below the field | | classes | Custom CSS classes for styling | | show | Conditional visibility (boolean or expression) | | hide | Conditional hiding (boolean or expression) | | disabled | Disable the field | | readonly | Make the field read-only | | attributes | Custom HTML attributes |

Signature Field

The signature field allows users to draw their signature:

type signature
name user_signature
label Please sign here
pen-color #0000ff
validations required
help Draw your signature in the box above

Signature-specific properties:

  • pen-color: Color of the signature stroke (e.g., #0000ff, rgb(0,0,255))

Standard properties:

  • All common properties listed above (name, label, validations, help, classes, show, hide, disabled, readonly)

Special Field Types

Variable Fields

Variable fields are used to define computed values that can be referenced by other fields. They support templating expressions and are useful for calculations, scoring, or dynamic value generation.

type variable
name qualification_score
value {{ (10 if (budget | int) > 1000 else 0) + (10 if (timeline | int) < 30 else 0) }}

Properties:

  • name (required): Variable name for referencing
  • value (required): Computed value expression

Hidden Fields

Hidden fields store values that are not visible to users but are included in form submissions. They can reference variables or contain static values.

type hidden
name score
value {{ qualification_score }}

Properties:

  • name (required): Field name for form submission
  • value (required): Field value (can be templated)

Tag Blocks

Tag blocks allow you to embed third-party scripts and tracking codes like Google Tag Manager, Facebook Pixel, or other analytics tools. Unlike HTML blocks, tag content is not sanitized by the renderer.

type tag
placement head
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXX');</script>
<!-- End Google Tag Manager -->

Properties:

  • placement (optional): Where to place the tag - head or body (defaults to head)

Usage:

  • Content is specified line-by-line after the properties
  • Blank lines within content are skipped (not included)
  • Content collection stops when a new block starts (same as HTML/CSS blocks)
  • Content is not sanitized or escaped by the renderer
  • Useful for tracking pixels, analytics, and third-party integrations

Multi-Step Forms

Create multi-step forms by adding the multi-step property to the form block and defining step blocks to organize your form fields.

Basic Multi-Step Syntax

type form
name my-survey
action https://example.com/submit
multi-step

type step
name personal-info
label Personal Information
next-label Continue

type text
name full_name
label Full Name
validations required

type email
name email
label Email
validations required

type step
name preferences
label Your Preferences
previous-label Back

type select
name category
label Category
options
    Option A
    Option B

type submit
label Submit

Multi-Step Properties

Form Block multi-step Property:

  • multi-step: (boolean) Enables multi-step form mode. Use multi-step or multi-step true to enable.

Step Block Properties:

  • name: (required) Unique identifier for the step
  • label: (optional) Display label shown to users
  • next-label: (optional) Custom text for the "Next" button
  • previous-label: (optional) Custom text for the "Previous" button
  • show: (optional) Conditional visibility (supports templating, e.g., show {{ field_name }})

Key Features

  • Form fields belong to the most recent step defined (no indentation required)
  • Steps are sequential - define them in the order you want users to see them
  • The submit button is automatically placed in the last step if not explicitly added
  • Single-step forms work exactly as before (backward compatible)
  • css and tag blocks can appear before steps (they're not part of the form flow)

Output Format

Multi-step forms produce a different output structure:

{
  "name": "my-survey",
  "multiStep": {},
  "steps": [
    {
      "name": "personal-info",
      "label": "Personal Information",
      "nextLabel": "Continue",
      "blocks": [
        { "$el": "form.text", "name": "full_name", "label": "Full Name" },
        { "$el": "form.email", "name": "email", "label": "Email" }
      ]
    },
    {
      "name": "preferences",
      "label": "Your Preferences",
      "previousLabel": "Back",
      "blocks": [
        { "$el": "form.select", "name": "category", "label": "Category" }
      ]
    }
  ]
}

Indented Properties

Some properties use indentation for nested values:

Design Settings

type form
name my_form
design
    theme dark
    background #333333

Options for select, radio, cards and checkbox

type select
name fruit
label Choose a fruit
options
    Apple
        value apple
    Banana
        value banana
    Orange
        value orange

Validation Rules

Validation rules are specified using a pipe-separated format:

validations required|length:3,50|email

Common validation rules:

  • required: Field must not be empty
  • email: Must be a valid email
  • length:min,max: Text length constraints
  • min:value: Minimum value (for numeric inputs)
  • max:value: Maximum value (for numeric inputs)
  • matches:/regex/: Custom regex pattern

Error Handling

The parser returns detailed error information:

const result = parseFormDefinition(formContent);

if (result.errors.length > 0) {
  result.errors.forEach(error => {
    console.log(`Line ${error.line}: ${error.message} (${error.code})`);
  });
}

Error codes:

  • PROPERTY_NOT_SUPPORTED: Property not supported for the block type
  • MISSING_REQUIRED_PROPERTY: Missing a required property
  • INVALID_INDENTATION: Incorrect indentation structure
  • INVALID_BLOCK_TYPE: Unknown block type
  • INVALID_PROPERTY_VALUE: Invalid property value
  • DUPLICATE_PROPERTY: Property defined multiple times

Editor Integration

The parser includes utilities for IDE/editor integration:

import { createDiagnostics } from '@formdata/parser';

// Create CodeMirror-compatible diagnostics
const diagnostics = createDiagnostics(formContent, result.errors);

API Reference

Main Functions

  • parseFormDefinition(text): Parse a form definition into a structured object
  • createDiagnostics(text, errors): Create editor-compatible diagnostics

Constants

  • ERROR_CODES: Enumeration of error code constants
  • PROPERTY_TYPES: Property type classifications
  • BLOCK_TYPES: Supported form block types
  • PROPERTIES: Property configurations for each block type
  • ALL_PROPERTY_NAMES: List of all valid property names

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT