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

@xemahq/document-templates

v0.1.0

Published

Layer 1 SDK: a pure, deterministic, domain-agnostic document assembler. Takes agent-authored structured content blocks + a theme and produces a paginated document — section numbering, table of contents, running headers/footers, page-break control — emitti

Readme

@xemahq/document-templates

This package belongs to Layer 1 — a pure SDK with zero runtime dependencies (only npm dev tooling). It is owned by the xema-kernel-sdk carved repo, so any Layer 2 service (e.g. document-render-api, which owns the puppeteer PDF / pandoc DOCX engines) and any Layer 3 biome may depend on it without crossing the release DAG.

What it is

The deterministic block → document assembly layer. Xema already renders raw HTML → PDF/DOCX; what was missing is the step that turns agent-authored structured content blocks + a theme into a complete, paginated document: section numbering, a generated table of contents, running headers/footers, page numbers, and block composition.

assembleDocument({ title, blocks, theme, metadata }) produces:

  • a self-contained, print-ready HTML string (@page size/margins, margin-box running headers/footers via CSS counters + a running string, page-break control) that the existing puppeteer PDF path can consume directly; and
  • a normalized DocumentModel (heading-derived section tree + resolved TOC) so a DOCX path can assemble from the same tree without being locked to HTML.

It is pure: no LLM, no network, no clock, no randomness — the same input always yields byte-identical output.

Block model (BlockKind)

A closed discriminated union of generic document primitives — no domain concepts:

heading · paragraph · list · table · image · callout · page_break · toc · key_value

Usage

import { assembleDocument, BlockKind } from '@xemahq/document-templates';

const { html, model, pdfHeaderTemplate, pdfFooterTemplate } = assembleDocument({
  title: 'Quarterly Report',
  blocks: [
    { kind: BlockKind.Toc },
    { kind: BlockKind.Heading, level: 1, text: 'Overview' },
    { kind: BlockKind.Paragraph, runs: [{ text: 'Hello ' }, { text: 'world', bold: true }] },
    { kind: BlockKind.Heading, level: 2, text: 'Details' },
    { kind: BlockKind.PageBreak },
    { kind: BlockKind.Heading, level: 1, text: 'Appendix' },
  ],
  // theme defaults to DEFAULT_THEME (A4, decimal numbering)
});

// html → puppeteer page.setContent(html); page.pdf({ preferCSSPageSize: true })
// model → a DOCX renderer walks model.sections / model.toc

Malformed block trees fail fast with a typed DocumentTemplateError citing the offending path (e.g. Invalid block at blocks[2].runs[0].text: expected string).

Markdown authoring

LLM producers can author content as Markdown instead of hand-writing block JSON. parseMarkdownToBlocks(markdown, opts?) losslessly expands a documented CommonMark(+GFM) subset into the same canonical Block[] — it is input-only sugar (the assembler/renderer are unchanged) that cuts tokens and the invalid-JSON surface. It is pure and deterministic: identical Markdown always yields an identical Block[].

import { parseMarkdownToBlocks, assembleDocument } from '@xemahq/document-templates';

const blocks = parseMarkdownToBlocks(`
# Overview

A paragraph with **bold**, _italic_, \`code\` and a [link](https://xema.dev).

- one
  - nested
- two

> [!WARNING]
> Handle with care.
`);

const { html } = assembleDocument({ title: 'Report', blocks });

Supported subset (each maps onto an existing block/mark — nothing new is invented):

| Markdown | Block | | --- | --- | | ATX headings #..###### | HeadingBlock (plain text — inline marks inside a heading are flattened to their text, as HeadingBlock has no runs) | | paragraphs with **strong**, _em_, `code`, ~~strike~~, [label](href) | ParagraphBlock rich-text runs | | ordered / unordered lists, nested by indentation | ListBlock | | GFM pipe tables | TableBlock (first row = header) | | standalone ![alt](src) on its own line | ImageBlock (alt → caption + alt) | | blockquotes, incl. a leading GFM alert [!NOTE]/[!TIP]/[!IMPORTANT]/[!WARNING]/[!CAUTION] | CalloutBlock (variant from the marker; default note) | | fenced code ```/~~~ | ParagraphBlock with one monospace (code) run preserving the text (BlockKind is closed — there is deliberately no CodeBlock) | | thematic break ---/***/___ | PageBreakBlock (the closest structural divider the canonical model offers) |

Deliberately not interpreted (documented, fail-fast — never silently dropped): raw HTML blocks/autolinks, setext headings, reference-style links, footnotes, definition lists, YAML frontmatter, and inline images embedded in rich text. By default (onUnsupported: 'error') these throw a typed DocumentTemplateError naming the construct and 1-based line. Pass { onUnsupported: MarkdownUnsupportedMode.Paragraph } to instead emit a block-level unsupported construct as a raw literal ParagraphBlock (an inline image inside a list/table/callout has no clean block fallback and always fails fast). A GFM table row whose column count differs from the header is malformed input and always fails fast.

Theme

DocumentTheme describes page size/orientation/margins, typography, per-level heading styles, header/footer templates (tokens {pageNumber}, {totalPages}, {title}, {sectionTitle}), TOC style, and the numbering scheme. One built-in theme, DEFAULT_THEME, is provided.