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

bloom-form-engine

v0.2.6

Published

A themeable, config-driven multi-step form engine for Bloom.io

Downloads

1,102

Readme

BloomForm Engine

A themeable, config-driven multi-step form engine for Bloom.io.

Give the CLI a Bloom form URL and it can generate a custom React form that is already mapped back to Bloom. The generated form includes the Bloom account ID, form ID, question IDs, step types, options, required flags, and success message. The package provides a clean base theme, and you can redesign the form with CSS variables or your own wrapper UI.

Quick Start

New project: one-command setup

If you are inside an empty folder and want BloomForm Engine to create the app shell for you, run:

npx bloom-form-engine@latest setup

The setup command detects whether a supported framework already exists. If no framework is found, it asks whether to create a Next.js App Router app or a Vite React app, installs the required packages, creates bloom-form.config.ts, creates bloom-form-theme.css, and wires theme/global CSS where the framework supports it.

To use the recommended Next.js setup without prompts:

npx bloom-form-engine@latest setup --yes

Existing project: install

npm install bloom-form-engine

This installs BloomForm Engine inside the current project folder, not globally. During local installs, the postinstall helper skips framework checks for global installs and otherwise detects your project framework. If a framework is missing or theme/CSS wiring is incomplete, it points you to the interactive setup flow:

npx bloom-form-engine setup

During installation, BloomForm Engine checks for the required peer dependencies. When your package manager allows interactive lifecycle prompts, the installer lets you choose react, react-dom, framer-motion, or all required dependencies and installs the selected packages for you.

If the install runs in a non-interactive environment, install them manually:

npm install react react-dom framer-motion

You can also run the peer dependency helper any time:

npx bloom-form-engine peers

Initialize

npx bloom-form-engine init

This creates a bloom-form.config.ts and a theme CSS file in your project.

Connect your Bloom account

npx bloom-form-engine connect

Add a form

npx bloom-form-engine add

This walks you through creating a form step-by-step and generates a ready-to-use React component.

Or import from a Bloom form URL

npx bloom-form-engine import "https://your-account.bloom.io/your-form"

The importer fetches Bloom's public form configuration, detects the account ID, form ID, question IDs, step types, multiple-choice options, personal-info fields, required flags, and success message, then generates a ready-to-use React component. The generated component submits to Bloom automatically through the same answer-group, answer, availability, timezone, and final-submit endpoints used by Bloom forms.

The CLI creates two starter files:

  • A themed form component that imports BloomForm Engine's Perfect Booth-style starter theme.
  • A Next.js app route page that centers the form vertically and horizontally, loads Google Inter, and stays mobile-friendly by default.

Bloom may reject browser submissions from localhost, so the CLI also asks for an optional proxy/API base URL. Leave it blank to set the proxy up later.

If you pass a local Next.js proxy path, the CLI creates the route for you:

npx bloom-form-engine import "<bloom-url>" --proxy "/api/bloom"

That writes app/api/bloom/[...path]/route.ts. Browser requests go to your app first, and the route forwards only the Bloom headers that are needed, so localhost Origin and Referer headers are not sent upstream to Bloom.

You can also enter the domain you plan to deploy to:

npx bloom-form-engine import "<bloom-url>" --proxy "rosecitybooth.com"

The generated form still uses same-origin proxyBaseUrl: "/api/bloom" and writes app/api/bloom/[...path]/route.ts. That means localhost testing goes to http://localhost:3000/api/bloom/..., and production goes to https://rosecitybooth.com/api/bloom/... after you deploy the same app. This avoids browser CORS errors from sending x-account to an external domain during local development.

You can also pass Bloom's public API URL directly:

npx bloom-form-engine import "https://api.bloom.io/api/public-forms/{accountId}/forms/{formId}"

If the URL does not expose both IDs, the CLI asks for the missing value.

Useful options:

npx bloom-form-engine import "<bloom-url>" --name RentalQuote --output ./components/forms --summary

To set the submission proxy immediately with a deployed app domain:

npx bloom-form-engine import "<bloom-url>" --proxy "https://your-domain.com/api/bloom"

This also generates same-origin proxyBaseUrl: "/api/bloom" for the app. Use the full domain as a deployment hint, not as a browser-side cross-origin API base.

Address autocomplete uses Bloom's public places endpoint by default, so generated address steps work from localhost without a Google Maps key. You can still override placesEndpoint in your BloomFormConfig if you want to use your own Google Places route.

Generated forms use the package's standard theme by default. Import the base stylesheet, then override CSS variables to match your brand.

What You Get

When you import a Bloom URL, the starter is intentionally ready-made:

  • A mapped React form component with Bloom accountId, formId, question IDs, field types, options, required flags, and success copy.
  • A centered Next.js page route such as app/get-quote/page.tsx.
  • The Perfect Booth-style base theme using Inter by default, with question titles shown in normal case rather than forced all-caps.
  • Address autocomplete through Bloom's places endpoint.
  • Optional local proxy generation at app/api/bloom/[...path]/route.ts when you pass --proxy "/api/bloom", --proxy "example.com", or --proxy "https://example.com/api/bloom".

For most Next.js + Tailwind projects, the generated files are enough. Make sure your global CSS includes Tailwind and your Tailwind content config scans the package output:

// tailwind.config.js
export default {
  content: [
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
    "./components/**/*.{js,ts,jsx,tsx,mdx}",
    "./node_modules/bloom-form-engine/dist/**/*.{js,jsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
};

For Tailwind v4 projects created by create-next-app, the CLI automatically adds this source directive to app/globals.css when it sees @import "tailwindcss":

@source "../node_modules/bloom-form-engine/dist/**/*.js";

The setup command also looks for common global CSS locations such as app/globals.css, src/app/globals.css, src/index.css, and src/App.css. When it finds a CSS file, it imports bloom-form-theme.css; when it finds Tailwind v4, it also adds the @source directive so package classes are available immediately.

If your app does not use Tailwind, keep the generated component and page as the wiring layer, then replace the class names with your own styles while keeping the generated BloomFormConfig.

Manual Usage

import { BloomForm } from 'bloom-form-engine';
import type { BloomFormConfig } from 'bloom-form-engine';
import 'bloom-form-engine/src/theme.css';

const config: BloomFormConfig = {
  accountId: 'your-account-id',
  formId: 'your-form-id',
  proxyBaseUrl: '/api/bloom',
  steps: [
    {
      id: 'name',
      questionId: 'q1',
      title: 'Your Name',
      description: 'Please enter your name',
      type: 'personal_info',
      fields: [
        { name: 'firstName', label: 'First Name', type: 'text', required: true },
        { name: 'lastName', label: 'Last Name', type: 'text', required: true },
      ],
      required: true,
    },
    // ... more steps
  ],
  successMessage: {
    title: 'Thank You!',
    description: 'We will be in touch soon.',
  },
};

export default function MyForm() {
  return <BloomForm config={config} />;
}

Theming

Override CSS variables to match your brand:

:root {
  --bf-font-heading: 'Your Heading Font', sans-serif;
  --bf-font-body: 'Your Body Font', sans-serif;
  --bf-color-accent: #your-accent-color;
  --bf-color-error: #your-error-color;
  --bf-color-border: #your-border-color;
  --bf-color-bg: #ffffff;
  --bf-color-bg-header: #f1f1f1;
  --bf-color-text: #1c1c1c;
  --bf-radius: 10px;
  --bf-radius-card: 12px;
}

The default starter theme mirrors the Perfect Booth form treatment while using Inter instead of Perfect Booth's custom brand fonts. It also includes these layout helpers for generated pages:

.bf-starter-page
.bf-starter-form-shell

Step Types

| Type | Description | |------|-------------| | multiple_choice | Radio buttons (single) or checkboxes (multi) | | date | Calendar picker with time slots and timezone | | address | Address autocomplete using Bloom's public places endpoint by default | | personal_info | Grouped input fields (name, email, phone) | | text | Single-line text input | | textarea | Multi-line text input | | summary | Review step before submission |

Props

<BloomForm />

| Prop | Type | Default | Description | |------|------|---------|-------------| | config | BloomFormConfig | required | Form configuration | | stickyFooter | boolean | false | Pin footer buttons to bottom of viewport | | onSuccess | () => void | - | Callback when form submits successfully |

Local Proxy Route

Use a proxy when your form runs on localhost or on a domain Bloom does not accept directly:

npx bloom-form-engine import "https://your-account.bloom.io/your-form" --proxy "/api/bloom"

The generated route forwards requests to https://api.bloom.io/api, preserves only the headers Bloom needs, strips localhost Origin and Referer, supports GET, POST, and OPTIONS, and adds browser-friendly CORS headers.

For production, deploy the same route with your app and keep proxyBaseUrl: "/api/bloom" in the generated config. If you pass a domain to the CLI, the CLI treats that as your deploy target and still generates same-origin /api/bloom so local development does not make cross-origin requests.

proxyBaseUrl: '/api/bloom'

The generated proxy route allows x-account in Access-Control-Allow-Headers, so browser preflight requests can succeed when the request goes through your same-origin Next.js route.

New Next.js Apps

If you are starting from scratch inside an empty folder, the shortest path is:

npx bloom-form-engine@latest setup --yes

That creates a Next.js App Router app, installs BloomForm Engine's dependencies, creates bloom-form.config.ts, creates bloom-form-theme.css, and wires the global CSS. Then run the import command inside that app. You should not need to manually change "type" in package.json or rename config files. Those fixes are only needed if you hand-roll a Next app with plain npm init, because recent npm versions can create "type": "commonjs" while Next.js app files use ES modules.

In Tailwind v4 apps, the CLI updates app/globals.css so Tailwind scans BloomForm Engine's compiled component classes. In Tailwind v3 apps, use the content setting shown above if your project does not already scan package code.

Peer Dependencies

  • React >= 18
  • React DOM >= 18
  • Framer Motion >= 10

The components use Tailwind-style utility class names alongside BloomForm Engine's CSS variables. If your app does not compile utility classes, keep the generated form as a starting point and restyle it with your own classes or wrapper UI.

License

MIT