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

@ebitex/forms-sdk

v0.4.92

Published

Fetch and render ebitex Forms in your own application.

Readme

@ebitex/forms-sdk

Fetch and render ebitex Forms in your own application.

Two entry points, split deliberately:

  • @ebitex/forms-sdk — fetches a form definition and validates a submission against it. No React dependency, so a server-only consumer never pulls one in.
  • @ebitex/forms-sdk/react — the rendering components. Imports React as a peerDependency (never bundled), so it never conflicts with your own app's copy.

Your organization's API key is server-side only. Fetch the form definition with createFormsClient on your server or in a build step, then pass the result to <EbitexForm> — which never receives the key itself, only the already-fetched definition.

Install

npm install @ebitex/forms-sdk

Quick start

// Server-side (a route handler, a loader, a build step — never in a browser bundle)
import { createFormsClient } from '@ebitex/forms-sdk'

const client = createFormsClient({ apiKey: process.env.EBITEX_FORMS_API_KEY! })
const form = await client.getForm('contact-us')
// Client-side — `form` is whatever getForm(...) returned above, passed down as a prop
import { EbitexForm } from '@ebitex/forms-sdk/react'
import '@ebitex/forms-sdk/styles.css'

function ContactPage({ form }: { form: SdkForm }) {
  return <EbitexForm form={form} onSubmitted={() => console.log('done')} />
}

<EbitexForm> posts directly to the form's own public submissionUrl — the same anonymous endpoint ebitex's own hosted page and iframe embed use — so it never needs your API key either. Multi-step forms save progress as the respondent advances.

Errors

getForm throws FormsApiError for a non-2xx response, carrying status, the parsed body, and requestId: the request's reference, from the X-Request-Id response header or an unhandled 500's body (null when a proxy answered and the request never reached ebitex). The message ends [request <id>] when there is one. Log it, and quote it to support.

Rendering nodes yourself

If you're not using <EbitexForm> — building a custom renderer, or validating a submission server-side without a browser involved — collectDataFields/resolveVariant/ isFieldComparisonSatisfied/isAllOfSatisfied/isSatisfied are the same evaluators it uses internally, exported so a second, independently-written implementation never has a chance to drift from the real one.

A form's content tree (SdkForm.actions, each FormStep.nodes) is FormNode[]: a Fieldset or Row groups other nodes; a field type (InputField/TextareaField/NumberField/ChoiceField/ ButtonField) is a leaf; a VariantNode shows at most one of its branches (first whose when is satisfied) or its fallback, based on the respondent's own answers so far.

interface VariantNode {
  nodeType: 'Variant'
  branches: VariantBranch[]
  /** Always an array — empty means "nothing" rather than `null`. */
  fallback: FormNode[]
}

interface VariantBranch {
  when: VariantPredicate
  /** May hold more than one node — not capped at one. */
  nodes: FormNode[]
}

type VariantPredicate = FieldComparisonPredicate | AllOfPredicate

interface FieldComparisonPredicate {
  kind: 'FieldComparison'
  field: string // a submissionKey answered *earlier* in the form
  operator: 'Equals' | 'NotEquals' | 'IsEmpty' | 'IsNotEmpty'
  value?: string // present for Equals/NotEquals, absent otherwise
}

/** AND-combination of two or more FieldComparisonPredicates — every one must be satisfied. */
interface AllOfPredicate {
  kind: 'AllOf'
  predicates: FieldComparisonPredicate[]
}
import { resolveVariant, isSatisfied } from '@ebitex/forms-sdk'

// Which of a Variant's branches (or its fallback) the respondent currently sees, given their
// answers so far — returns that branch's/fallback's own node list, possibly empty.
const visibleNodes = resolveVariant(variantNode, currentAnswers)

// Evaluating one branch's own `when` directly, regardless of which predicate kind it is.
const branchApplies = isSatisfied(someBranch.when, currentAnswers)

A field's answer is submitted under its own submissionKey — not necessarily its name: a field placed by reference to one you've reused across forms is keyed by that shared field's own external id instead. Always read/write SubmissionData by submissionKey.

Validating a submission

import { validateSubmission } from '@ebitex/forms-sdk'

const errors = validateSubmission(form, submittedData, { requireAll: true })

<EbitexForm> calls this itself for inline feedback before every request; the server is always the final authority regardless — a client-side pass is for a good respondent experience, not enforcement.

Versioning

This package's public wire shape mirrors ebitex's own Forms API responses directly (see SdkForm/FormNode above) — a breaking shape change on the server ships as a new minor version here (pre-1.0), not a patch. Pin a specific version if that matters to your build.

Full guide: developers.ebitex.io.