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

html-to-pdf-crab-js

v0.2.0

Published

Chromium-free HTML-to-PDF rendering for Node.js and WebAssembly, built with Rust and NAPI-RS.

Readme

html-to-pdf-crab-js

Chromium-free HTML-to-PDF rendering for Node.js and WebAssembly, built with Rust and NAPI-RS.

Use this package when the source document is already HTML and CSS: invoices, reports, printable screens, exports, letters, and documents that benefit from normal web layout. If you need low-level, coordinate-based PDF generation, use pdf-crab-js.

html-to-pdf-crab-js is the easy HTML path in the Crab JS PDF stack. It converts HTML/CSS to PDF without running Chromium, Puppeteer, Playwright, or a Gotenberg service. The rendering pipeline is native Rust exposed through NAPI-RS, with a WASM build for browser and portable runtimes.

Why html-to-pdf-crab-js

  • Keep authoring documents in HTML and CSS instead of translating layouts into PDF coordinates.
  • Avoid a heavyweight browser process or external conversion service for common document exports.
  • Pass explicit CSS, fonts, images, page size, margins, and orientation through one small API.
  • Use the same package family as pdf-crab-js: HTML/CSS for convenience, structured PDF for maximum speed.

Benchmark Snapshot

Local 10-page benchmark, fastest to slowest by execution time:

| Order | Language | Mode | Execution time | Throughput | | ----- | ----------------------- | ---------- | -------------: | ---------------: | | 1 | Node + pdf-crab | local | 4.116 ms | 2429.253 pages/s | | 2 | Node + pdf-crab | builder | 4.232 ms | 2362.863 pages/s | | 3 | Node + html-to-pdf-crab | local-html | 62.327 ms | 160.443 pages/s | | 4 | Node + Gotenberg | gotenberg | 128.304 ms | 77.940 pages/s |

Benchmark results are workload and machine dependent. The important comparison is practical: html-to-pdf-crab-js keeps the HTML/CSS workflow while avoiding Chromium service overhead. It is not as fast as pdf-crab-js because it still performs HTML/CSS layout, but it is the simpler path when HTML is already the document source.

PDF Results

These previews are generated from examples/html-to-pdf-crab-js/report.ts and examples/html-to-pdf-crab-js/invoice.ts.

html-to-pdf-crab-js report PDF result

html-to-pdf-crab-js invoice PDF result

Install

npm install html-to-pdf-crab-js

Requirements:

  • Node.js >=22 for the native package.
  • A browser or static host with SharedArrayBuffer enabled for the WASM package.

Quick Start

import { readFileSync, writeFileSync } from 'node:fs'
import { createPdfFromHtml } from 'html-to-pdf-crab-js'

const html = readFileSync('invoice.html', 'utf8')
const css = readFileSync('invoice.css', 'utf8')
const font = readFileSync('assets/Tuffy.ttf')

const pdf = await createPdfFromHtml({
  html,
  css,
  fonts: [font],
  basePath: process.cwd(),
  page: {
    size: 'A4',
    margin: { top: 14, right: 14, bottom: 16, left: 14, unit: 'mm' },
  },
  systemFonts: false,
  title: 'Invoice INV-2026-042',
})

writeFileSync('invoice.pdf', pdf)

CommonJS is also supported:

const { createPdfFromHtml } = require('html-to-pdf-crab-js')

API

| Export | Description | | -------------------------- | ------------------------------------- | | createPdfFromHtml(input) | Renders HTML/CSS into a PDF Buffer. |

CreatePdfFromHtmlInput

| Field | Description | | ------------- | ------------------------------------------------------------------------------------------------------------- | | html | Required HTML document string. Must not be empty. | | title | Optional PDF title. | | css | Optional CSS string or array of CSS strings. | | basePath | Optional base path for resolving relative assets. Must not be empty when provided. | | systemFonts | Enables host system fonts when true; defaults to true. Use false for deterministic bundled-font output. | | fonts | Optional array of font buffers in Node. Browser WASM examples normalize binary font assets to base64. | | images | Optional named image assets. Names are referenced from HTML/CSS asset paths. | | page | Optional page size, margins, and orientation. | | bookmarks | Enables or disables generated bookmarks when supported by the renderer. | | tagged | Enables or disables tagged PDF output when supported by the renderer. | | pdfUa | Enables or disables PDF/UA mode when supported by the renderer. |

Page Options

type HtmlPdfPageInput = {
  size?: 'A4' | 'LETTER' | 'A3' | { width: number; height: number; unit?: 'mm' | 'pt' }
  margin?: number | { top: number; right: number; bottom: number; left: number; unit?: 'mm' | 'pt' }
  landscape?: boolean
}

A numeric margin is interpreted as millimeters. Custom page sizes and margin objects support mm and pt.

Fonts and Assets

For reliable rendering, pass explicit fonts and set systemFonts: false:

const font = readFileSync('assets/Tuffy.ttf')

await createPdfFromHtml({
  html,
  css,
  fonts: [font],
  systemFonts: false,
})

basePath is useful when the HTML references local assets with relative paths. For browser WASM, see examples/html-to-pdf-crab-js/wasm/browser.ts; it fetches font bytes and converts them before calling the WASI binding.

Browser and WASM

Browser, Deno, Bun, and portable runtimes can use the NAPI-RS WebAssembly build:

import { createPdfFromHtml } from 'html-to-pdf-crab-js/wasm'

Browser deployments must enable SharedArrayBuffer, which requires cross-origin isolation:

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

The combined Netlify browser sample lives in examples/netlify-pdf-samples/ and demonstrates html-to-pdf-crab-js with pdf-crab-js using the required WASM headers.

Published sample: https://pdf-crab-js.netlify.app/#html-to-pdf-crab-js

Examples

Run the Node examples from the workspace root:

pnpm --filter html-to-pdf-crab-js-examples invoice
pnpm --filter html-to-pdf-crab-js-examples report

Generated files are written to examples/html-to-pdf-crab-js/output/.

Run the browser WASM example:

pnpm --filter html-to-pdf-crab-js-examples browser

Open /wasm/ on the local Vite server. The page previews report.html and renders that same HTML/CSS into a PDF iframe.

Browser builds use the generated *.wasi-browser.js loader. The package build rewrites that loader to use async WASM instantiation because browser engines reject synchronous compilation for the current WASM artifact size. Restart the Vite dev server after rebuilding the package so the page loads the regenerated loader cleanly.

Preview the source HTML in a browser:

open examples/html-to-pdf-crab-js/invoice.html
open examples/html-to-pdf-crab-js/report.html

Development

Install dependencies from the workspace root:

pnpm install --filter html-to-pdf-crab-js

Build and test:

pnpm --filter html-to-pdf-crab-js build
pnpm --filter html-to-pdf-crab-js test
pnpm --filter html-to-pdf-crab-js check
pnpm --filter html-to-pdf-crab-js lint
pnpm --filter html-to-pdf-crab-js fmt:check

Build and smoke-test the WebAssembly binding:

rustup target add wasm32-wasip1-threads
pnpm --filter html-to-pdf-crab-js build:wasm
pnpm --filter html-to-pdf-crab-js test:wasm

Release

Native and WebAssembly package publishing is handled by napi prepublish -t npm.