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

merchi_sdk_product_form

v1.0.7

Published

Contract SDK for AI-built Merchi custom product forms.

Downloads

511

Readme

Merchi Product Form SDK

Contract SDK for AI-built and hand-written custom Merchi product order forms.

License: GPL-3.0

Custom forms are React components that run inside the Merchi dashboard preview and the product embed. This package defines the only imports, components, and helpers those forms may use. Source is validated by a static gate and compiled to a browser bundle that externalises react and this SDK to window globals.

Table of Contents

Installation

npm install merchi_sdk_product_form

Peer dependency: react ^18 or ^19.

In the Merchi monorepo, the dashboard installs a packed tarball:

cd merchi_sdk_product_form
npm run build && npm pack
cd ../merchi_dashboard && npm install

Quick start

A minimal form renders independent variation fields and relies on the host shell for quantity, live pricing, and submit actions:

import React from 'react';
import {
  Section,
  Stack,
  Heading,
  Text,
  Field,
} from 'merchi_sdk_product_form';

export default function Form({ product }) {
  const fields = product?.independentVariationFields ?? [];

  return (
    <Stack gap={24}>
      <Section>
        <Heading>{product?.name || 'Order form'}</Heading>
        {product?.description ? <Text muted>{product.description}</Text> : null}
      </Section>
      <Section title="Options">
        <Stack gap={16}>
          {fields.map((field) => (
            <Field key={field.id} field={field} />
          ))}
        </Stack>
      </Section>
    </Stack>
  );
}

See examples/colour-grid-form.tsx for a per-colour quantity grid (wristbands, multi-SKU products).

How forms run

  1. Authoring — Form source is stored as TSX on a ProductForm in Merchi.
  2. Gate — Only imports from react and merchi_sdk_product_form are allowed (legacy @merchi/product-form-sdk is still accepted for older drafts).
  3. Compile — esbuild bundles the form to an IIFE; reactwindow.React, merchi_sdk_product_formwindow.MerchiProductFormSdk.
  4. Host — The dashboard or embed loads the bundle, provides createProductFormRuntime, and wraps the form in ProductFormShell (quantity control, live quote footer, add-to-cart / buy-now).

Form authors should not reimplement quantity controls, pricing footers, or checkout buttons — the shell provides those.

Form component contract

Default-export a React component matching ProductFormComponent:

export default function Form({ product, pricing, actions, helpers }) {
  // product  — ProductJson for the item being ordered
  // pricing  — request quotes as the user edits (createPricing wrapper)
  // actions  — submit handlers (addToCart, buyNow, …); may be undefined
  // helpers  — serializeJob, nonEmptyGroups, formatCurrency, urlFor
}

Inside composed UI, prefer useProductForm() from a ProductFormProvider / ProductFormShell subtree for quote state and submit wiring.

Layout and fields

| Export | Purpose | |--------|---------| | Section, Stack, Card | Page structure | | Heading, Text, Divider | Typography | | Field | Render a product variation field (options, text, files, etc.) | | theme | Shared spacing/colour tokens |

Loop product.independentVariationFields for options that apply to the whole order (job.variations).

There is no TextInput, Select, Button, or ColorSwatches — use Field and layout components only.

Group variations

Some products need per-batch choices (e.g. colour × quantity grids):

| Helper / component | When to use | |--------------------|-------------| | productHasGroups(product) | Product has groupVariationFields | | isOptionQuantityGridProduct(product) | Single option-based group field → use grid | | OptionQuantityGrid | Table: swatch, quantity, row cost, inventory | | GroupRows | Multiple group fields or free-text group fields | | Field with groupIndex | Field inside a specific batch row |

When groups exist, each batch has its own quantity in job.variationsGroups. Do not use top-level job.quantityProductFormShell hides the global quantity control for group products.

Pricing and job building

| Export | Purpose | |--------|---------| | createPricing / createProductFormRuntime | Host/runtime wiring (embed & dashboard) | | buildProductFormJob | Build a JobJson from form state | | selectionsToVariations | Map field selections to variation payloads | | serializeJob | Strip empty groups before submit | | nonEmptyGroups | Filter groups with quantity > 0 | | formatCurrency, urlFor | Display helpers |

Allowed exports

The compile gate allowlists these runtime named imports (type-only imports are erased and not checked):

SDK_VERSION, serializeJob, nonEmptyGroups, formatCurrency, urlFor, createPricing, createProductFormRuntime, productHasGroups, groupFieldsOf, independentFieldsOf, isOptionQuantityGridProduct, buildProductFormJob, selectionsToVariations, Section, Stack, Card, Heading, Text, Divider, Field, GroupRows, OptionQuantityGrid, ProductFormProvider, ProductFormShell, useProductForm, OPTION_FIELD_TYPES, theme

Keep this list in sync with src/index.ts and merchi_api/common/js/product_form_gate.cjs.

Development

npm install
npm run build    # tsc → dist/
npm test         # jest
npm run lint     # eslint src
npm pack         # merchi_sdk_product_form-<version>.tgz

Repository: github.com/merchisdk/merchi_sdk_product_form

License

GPL-3.0 — see LICENSE (same as merchi_sdk_ts).