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

@unlev/exeq

v0.1.12

Published

Embeddable PDF form builder and document signing — client-side, no backend required

Downloads

1,352

Readme

Exeq

Embeddable PDF form builder and document signing for the browser. Design form templates on any PDF, then let users fill and sign them — all client-side, no backend required. Your documents never leave the device.

Install

npm install @unlev/exeq
# or
yarn add @unlev/exeq

Quick Start

import { DesignerView, SignerView } from '@unlev/exeq';
import '@unlev/exeq/styles';

// Template editor — open a PDF, place fields, export template
function Editor() {
  return (
    <DesignerView
      apiKey="your-api-key"
      initialPdfUrl="/contracts/blank.pdf"
      onSave={(template) => {
        // store the template JSON on your server
      }}
    />
  );
}

// Signing UI — load a template, pre-fill values, collect signed PDF
function Signer() {
  return (
    <SignerView
      apiKey="your-api-key"
      initialPdfUrl="/contracts/template.pdf"
      initialTemplate={template}
      initialSigner="Signer 1"
      initialValues={{
        "Full Name": "Jane Smith",
        "Email": "[email protected]",
      }}
      onComplete={(blob) => {
        // upload the signed PDF
      }}
    />
  );
}

// Multi-party signing — signers complete sequentially
function MultiPartySigner() {
  return (
    <SignerView
      apiKey="your-api-key"
      initialPdfUrl="/contracts/template.pdf"
      initialTemplate={template}
      signerOrder={['Signer 1', 'Sender']}  // recipient signs first, then sender
      onComplete={(blob) => {
        // final PDF with all signatures
      }}
    />
  );
}

API

DesignerView Props

| Prop | Type | Required | Description | |------|------|----------|-------------| | apiKey | string | Yes | Your Exeq API key | | initialPdfUrl | string | No | URL to a PDF to pre-load | | initialTemplate | Template | No | Existing template to resume editing | | onSave | (template: Template) => void | No | Called on "Export Template". If omitted, downloads JSON. |

SignerView Props

| Prop | Type | Required | Description | |------|------|----------|-------------| | apiKey | string | Yes | Your Exeq API key | | initialPdfUrl | string | No | URL to the PDF | | initialTemplate | Template | No | Template with fields and signer roles | | initialSigner | string | No | Signer role name (default: "Signer 1") | | initialValues | Record<string, string> | No | Pre-fill fields by label (case-insensitive) or ID | | callbackUrl | string | No | URL to POST the signed PDF to | | onComplete | (blob: Blob) => void | No | Callback with the signed PDF Blob | | submitLabel | string | No | Label for the final submit button (default: "Complete") | | signerOrder | string[] | No | Signing order for multi-party docs. Signers complete sequentially. Defaults to non-Sender roles first, then Sender. |

Utilities

import { renderPdfPages, generateFilledPdf, downloadPdf } from '@unlev/exeq';

// Render PDF pages to images
const pages = await renderPdfPages(pdfUrlOrBytes);

// Generate a filled PDF with form values overlaid
const bytes = await generateFilledPdf(pdfSource, fields);

// Trigger browser download
downloadPdf(bytes, 'signed-document.pdf');

Types

import type { FormField, Template, FieldType, RenderedPage } from '@unlev/exeq';

Field Types

| Type | Description | |------|-------------| | text | Text input (subtypes: freeform, number, date, email, phone) | | signature | Freehand signature drawing (supports ink color) | | initials | Smaller freehand drawing for initials | | signed-date | Auto-filled date when signer signs | | checkbox | Toggle checkbox | | blackout | Black redaction rectangle (designer only) | | whiteout | White redaction rectangle (designer only) |

Additional Components

| Component | Description | |-----------|-------------| | PdfViewer | Low-level PDF page renderer with draggable field overlays | | SignatureCanvas | Freehand signature/initials drawing canvas | | FieldPropertyPanel | Field property editor (type, label, assignee) | | FieldNavigator | Prev/Next navigation through signer fields | | SignerRoleSelector | Manage signer roles |

Privacy

All PDF processing happens client-side in the browser. Documents are never uploaded to any server. The npm package is self-hosted — it bundles into your app and serves from your infrastructure.

Workflow

  1. Design — Use <DesignerView /> to open a PDF and place form fields
  2. Pre-fill — Fill Sender fields (company name, your signature, etc.)
  3. Export — Capture the template JSON via onSave
  4. Sign — Render <SignerView /> with the template. Use initialValues for mail-merge.
  5. Collect — Receive the signed PDF via onComplete

CDN Usage

For non-React apps, use the embed script:

<script src="https://unpkg.com/@unlev/exeq/dist/embed.global.js"></script>

<div id="signer" style="width:100%;height:800px"></div>
<script>
  Exeq.sign({
    target: '#signer',
    apiKey: 'your-api-key',
    pdf: '/contract.pdf',
    fields: '/template.json',
    onComplete: (blob) => { /* signed PDF */ }
  });
</script>

Documentation

Full docs at exeq.org/docs

License

MIT — Unleavened LLC