easy-forms
Pro

Licensing

Setting your key, checking status, and how the unlicensed watermark works.

Pro is honour-based: the license gate is not DRM. An unlicensed build works fully — it just shows a watermark.

Setting the key

Call once at startup, before any Pro feature mounts:

import { setEasyFormsProLicense } from '@easy-forms/pro';

setEasyFormsProLicense('<your license key>');

Checking status

import { getLicenseStatus } from '@easy-forms/pro';

const status = getLicenseStatus();
if (status.valid) {
	console.log(status.claims.customer, status.claims.seats);
} else {
	console.warn(status.reason);
}

LicenseStatus is a discriminated union:

type LicenseStatus =
	| { valid: true; claims: LicenseClaims }
	| { valid: false; reason: LicenseInvalidReason };

reason is one of 'missing', 'malformed', 'bad-signature', 'expired', or 'wrong-audience'.

What the token contains

interface LicenseClaims {
	customer: string;   // licensee name / organization
	edition: 'pro';
	seats: number;      // contracted seats (honour-based, not enforced)
	iat: number;        // issued-at, Unix seconds
	exp: number;        // expiry, Unix seconds
	aud?: 'license' | 'registry';
}

The token is signed, not encrypted. You can read your own claims; they are tamper-evident, not secret. The public verification key ships inside the package.

Two tokens, two jobs

TokenUsed byWhere it goes
License keysetEasyFormsProLicense at runtimeYour app's startup code
Registry tokenshadcn add @ef-pro/* at install timecomponents.json / EASY_FORMS_PRO_TOKEN

Passing one where the other is expected fails with reason: 'wrong-audience'.

The unlicensed watermark

Changed in 1.0

<ProWatermark> was removed. There is no component to render or place.

The badge is a singleton injected into document.body. A mount counter tracks how many Pro features are active; the badge appears while activeCount > 0 and no valid license is set, and disappears when the last Pro feature unmounts. Calling setEasyFormsProLicense re-syncs it immediately.

Consequences worth knowing:

  • Two repeating groups and an advanced wizard on one page produce one badge, not three.
  • A page using only free features never shows it, even in an app that also uses Pro.
  • It is outside your React tree, so it cannot be styled or positioned by your components.

Other exports

  • assertLicensed(feature) — returns a boolean and warns once per feature, in every environment (not just development). It never blocks — the feature still renders when unlicensed.
  • verifyLicense(key) — verify a key without installing it as the active license.
  • verifyRegistryToken(token) — used by the registry worker; rarely needed in app code.