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

@printedjs/browser

v0.2.3

Published

Browser-native rendering engine and DOM layout adapter for Printedjs.

Downloads

510

Readme

@printedjs/browser

Browser-native rendering engine and DOM layout adapter for Printedjs.

@printedjs/browser coordinates DOM measurement, page box structure generation, stylesheet loading, isolated sandbox rendering (root or iframe), and page virtualization for paginated documents.


Features

  • Surface Isolation (RootSurface / IframeSurface) — Render directly into an existing DOM container (root) or into a clean, sandboxed iframe to isolate external styles and scripts.
  • W3C Paged Media Shell (createPageShell) — Generates complete page box hierarchy with bleed areas, crop marks, and 16 standard margin boxes (@top-left, @top-center, @bottom-right, etc.).
  • Scoped DOM Layout Adapter (DomLayoutAdapter) — Content slicing and chunking engine with strict table header/footer isolation and nested table boundary protection.
  • Dynamic Stylesheet Registry (StyleRegistry, loadStylesheets) — Concurrent fetching, @import resolution, and scoping of inline and remote CSS stylesheets.
  • Page Virtualization (virtualizePages) — Intersection-observer-backed DOM virtualizer for smooth scrolling and minimal memory consumption when previewing 100+ page documents.
  • Non-Destructive Teardown (renderer.destroy()) — Complete restoration of original target DOM elements with zero leak of injected styles.

Installation

pnpm add @printedjs/browser @printedjs/core

Usage

Basic Rendering

import { createRenderer } from "@printedjs/browser";

const target = document.querySelector("#preview-container")!;

const renderer = createRenderer({
	target,
	isolation: "root", // or "iframe"
	pagedjsCompatible: false, // Set to true to include legacy .pagedjs_* class aliases
});

const result = await renderer.render({
	content: {
		html: `
      <style>
        @page {
          size: A4;
          margin: 25mm 20mm;
          @bottom-center {
            content: "Page " counter(page) " of " counter(pages);
          }
        }
      </style>
      <h1>Annual Financial Report</h1>
      <p>Continuous flow content spanning multiple printed pages.</p>
    `,
	},
});

console.log(
	`Rendered ${result.pages.length} pages in ${result.metrics.totalDurationMs}ms.`,
);

// When finished, clean up DOM:
renderer.destroy();

Isolated Iframe Surface

When rendering untrusted HTML or documents with conflicting global CSS, use isolation: "iframe":

const renderer = createRenderer({
	target: document.body,
	isolation: "iframe",
});

await renderer.render({
	content: {
		html: untrustedHtmlString,
	},
});

Page Virtualization for Large Documents

import { virtualizePages } from "@printedjs/browser";

const container = document.querySelector(".printedjs_pages") as HTMLElement;

// Virtualize rendered pages so only visible pages consume layout resources
const virtualizer = virtualizePages(container, {
	bufferPages: 2,
	rootMargin: "200px 0px",
});

// To disconnect virtualizer observers:
virtualizer.disconnect();

API Reference

createRenderer(options: CreateRendererOptions): BrowserRenderer

Creates a new BrowserRenderer instance with the specified options:

  • target: SurfaceTarget — The container element or selector where pages will be rendered.
  • isolation?: "root" | "iframe" — Isolation strategy (default: "root").
  • plugins?: readonly PrintedjsPlugin[] — Plugins to attach to the layout pipeline.
  • pagedjsCompatible?: boolean — Whether to emit dual Printedjs and legacy Paged.js CSS classes and custom properties.

BrowserRenderer Methods

  • render(request: RenderRequest): Promise<RenderResult> — Parses stylesheets, prepares the surface, and renders the document.
  • renderIncremental(request: IncrementalRenderRequest): Promise<RenderResult> — Re-renders from a specific page onwards without rebuilding preceding pages.
  • destroy(): void — Destroys active sessions, disconnects observers, and clears rendered nodes from the target.

License

MIT