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

fragmentainers

v0.0.7

Published

Javascript fragmentation engine

Readme

Fragmentainers

Javascript fragmentation engine to split content across bounded containers (fragmentainers). It implements the CSS Fragmentation model and CSS Paged Media breaks, inspired by browser layout engines internal block fragmentation architecture.

A part of Pagedjs, but this library can be used independently to fragment content across columns, regions, pages, or any bounded container.

NPM Module

npm install fragmentainers

Usage

Fragmenter

import { Fragmenter } from "fragmentainers";

const flow = new Fragmenter(content, options);
for (const el of flow) {
	/* ... */
}

Content

  • DocumentFragment — from template.content or document.createDocumentFragment()

  • Element — cloned into a new DocumentFragment

Options

  • styles — CSSStyleSheet[] applied via adoptedStyleSheets
  • constraintSpace — ConstraintSpace for sizing
  • resolver — A PageResolver or RegionResolver instance
  • width / height — Resolves to a constraint space for fixed size fragmentation
  • type — Fragmentation type used with width / height (defaults to "column")
  • devicePixelRatio — Target DPR for line-height rounding
  • emulatePrintPixelRatio — Screen-only matching of print line-height
  • styleSheet — Caller-owned sheet that receives the composite scoped rules
  • continuation — { fragmentainerIndex, blockOffset } resume point from another flow

Pagination with @page styles

import { Fragmenter } from "fragmentainers";

const sheet = new CSSStyleSheet();
sheet.replaceSync(`
  @page { size: A4; margin: 2cm; }
`);

const template = document.createElement("template");
template.innerHTML = "<h1>Hello</h1><p>Content to paginate...</p>";

const flow = new Fragmenter(template.content, { styles: [sheet] });

for (const fragmentainer of flow) {
	// Each element is a <fragment-container>
	document.body.appendChild(fragmentainer);
}

Preloading

Layout is synchronous. If fonts or images haven't loaded yet, measurements may be inaccurate. Use preload() to ensure resources are ready before iterating:

const flow = new Fragmenter(template.content, { styles: [sheet] });
await flow.preload();
for (const el of flow) {
	document.body.appendChild(el);
}
  • Images — set width and height attributes on <img> elements when possible. Images with explicit dimensions are automatically set to loading="lazy" and don't need preloading. Images that are unable to be loaded will be removed from the flow as their size can not be calculated.
  • Fonts — Ensure web fonts are loaded before layout. preloadFonts() registers @font-face rules from the supplied content styles and waits for unloaded faces used by those styles. For best performance, use <link rel="preload" as="font"> in your HTML.
  • Measurement — Top-level forced breaks and named-page changes divide long content into segments. One measurement element is rearranged as the break token advances, keeping only the active segment, persistent elements, and unfinished parallel-flow boxes live. Content without segment boundaries is measured as one segment.

The measurement element is released automatically when iteration or flow() completes, and when a for...of loop exits early. Call destroy() when the flow is no longer needed to release handlers, generated styles, preloaded fonts, and retained layout state.

Layout Handlers

Like pagedjs the engine supports handlers - self-contained extensions that hook into the layout and rendering pipeline. Much of the functionality outside of the core layout is implemented using these handlers.

.float-top {
	--float-reference: page;
	--float: top;
}
import { LayoutHandler, Fragmenter } from "fragmentainers";

// Custom handlers extend the LayoutHandler base class
class MyHandler extends LayoutHandler {
	claim(node) {
		/* ... */
	}
	layout(rootNode, constraintSpace, breakToken, layoutChild) {
		/* ... */
	}
}

// Add it to the catalog once, at package load. Every flow constructed
// afterwards instantiates it.
Fragmenter.handlers.push(MyHandler);

See Layout Handlers for the full handler interface and how handlers are added or overridden.

Emulate Print Pixel Ratio

Blink-based browsers round line-height: normal to the device pixel ratio — integer CSS pixels at DPR 1, half-pixels at DPR 2. This means the same content renders at different line heights screen vs print, causing fragmentation mismatches between layout and rendering.

The emulatePrintPixelRatio option attempts to normalize the two ratios to provide a more accurate preview of the print output. DPR 1 line-height values are emulated with a screen only the adopted stylesheet and will not be used in printing.

Documentation

Testing

npm test                # unit/integration tests
npm run lint            # eslint (separate from tests)

Set FRAG_TEST_PORT to override the Playwright server port when running multiple checkouts concurrently.

Tests use Playwright running in a browser. Each test imports a shared browser fixture and evaluates code inside the browser via page.evaluate().

Specs (visual comparison tests)

npm run specs

Spec tests are reftests based on the Web Platform Tests approach. Each test has a test HTML file and a reference HTML file — the runner screenshots both and compares them pixel-by-pixel.

Viewer

The fragment bin opens a spec in a headed browser with the engine live-injected, so you can refresh to re-run after edits:

fragment specs/at-page/awesome.html                  # interactive (Chromium)
fragment specs/at-page/awesome.html --inspect        # per-page report to stdout
fragment specs/at-page/awesome.html --html out.html  # dump fragmented HTML
fragment specs/at-page/awesome.html --pdf book.pdf   # render to PDF
fragment --help                                      # full flag list

--inspect is the fastest way to see which page a break token landed on, which elements got split, and any zero-progress warnings — no screenshotting needed.

License

MIT