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

@technomoron/unyuck

v1.0.6

Published

**Unyuck** is a drop-in preprocessor for Nunjucks templates. It resolves `extends`, `include`, and `block` directives at build time, producing a single flattened template plus an optional asset manifest. Instead of shipping a full template tree and a runt

Readme

Unyuck

Unyuck is a drop-in preprocessor for Nunjucks templates. It resolves extends, include, and block directives at build time, producing a single flattened template plus an optional asset manifest. Instead of shipping a full template tree and a runtime loader, you can deploy just one resolved file — as plain text or stored directly in a database.

Nunjucks is arguably one of the best template engines for text processing, flow control, variable expansion, and extensibility. But its loader model can be restrictive: it has no option to resolve and flatten templates into a single merged text representation, only to compile them into an AST. This is often impractical — or even impossible — when transferring or storing complex templates in databases or across networks. By flattening ahead of time, Unyuck removes the complexity of loading a full, chunked template when plain text output is the most practical option.

Unyuck is not a runtime replacement for Nunjucks. It is a build-time companion that preprocesses templates into deployable artifacts, leaving rendering, variable substitution, and logic evaluation to the standard Nunjucks runtime.

Why this matters:

  • Synchronous and portable – Works without async I/O or filesystem access, so it’s safe for serverless functions, databases, or edge runtimes.
  • Single-file deployment – Simplifies packaging and transfer; no need to bundle the entire directory tree.
  • Performance – Eliminates runtime lookups for includes/extends; the result is pre-resolved.
  • Security – Guards against directory traversal outside your template root if path access is a concern.
  • Asset handling – Collects asset("...") references into a manifest for inlining, CID attachments, or CDN URLs, with hooks for custom URL formatting.
  • Easy preprocess - Make text-based preprocessing possible on the entire merged template. No need to traverse the Nunjucks AST.

Unyuck preserves Nunjucks-compatible whitespace trimming ({% %} vs {%- -%}), strips out template comments, and ensures the compiled result matches what Nunjucks would render — just lighter, safer, and easier to deploy.


Repository


Installation

npm install unyuck

Unyuck ships with both ES modules and CommonJS builds plus TypeScript declarations. Node.js 18+ is recommended.


Quick Start

ES modules

import { flatten, flattenWithAssets, Unyuck } from "unyuck";

const basePath = new URL("./templates", import.meta.url).pathname;
const baseUrl = "https://cdn.example.com/email";

// Flatten to a single HTML string
const html = flatten({ basePath, baseUrl, template: "welcome.njk" });

// Flatten and collect assets
const { html: merged, assets } = flattenWithAssets({
  basePath,
  baseUrl,
  template: "parts/newsletter.njk",
});

// Inspect the AST
const processor = new Unyuck({ basePath, baseUrl });
const ast = processor.toAst("layout.njk");
const astWithAssets = processor.toAst("layout.njk", { withAssets: true });

CommonJS

const { flattenWithAssets, Unyuck } = require("unyuck");
const path = require("path");

const basePath = path.join(__dirname, "templates");
const baseUrl = "https://cdn.example.com/email";

const { html, assets } = flattenWithAssets({
  basePath,
  baseUrl,
  template: "email.njk",
});

const processor = new Unyuck(basePath, baseUrl);
const ast = processor.toAst("email.njk");

Template Rules

  • Template names are resolved relative to basePath.
  • Relative jumps (../partials/header.njk) are allowed but cannot escape the base directory.
  • {%- -%} trimming follows Nunjucks semantics for includes, extends, and blocks.
  • Template comments ({# … #}) are stripped before processing.
  • Asset references rely on asset("relative.png", inline?):
    • Paths are resolved by walking up from the template directory looking for the nearest assets/ folder.
    • Without inline, the path expands to baseUrl + urlPath, where urlPath defaults to the filename without the assets/ prefix (noAssetUrl: true). Set noAssetUrl: false to keep the full relative path.
    • Provide an assetFormatter to override the final string; its context includes { baseUrl, filename, path, urlPath }.
    • With inline (truthy second arg) the tag rewrites to cid:<filename> and the asset is still tracked.
    • Absolute remote URLs (http://, https://) are left unchanged and skipped in the manifest.

API Reference (cheat sheet)

import {
  Unyuck,
  flatten,
  flattenNoAssets,
  flattenWithAssets,
  parseTemplate,
} from "unyuck";

Class: Unyuck

new Unyuck(basePath: string, baseUrl?: string, collectAssets?: boolean);
new Unyuck({
  basePath,
  baseUrl?,
  collectAssets?,
  assetFormatter?,
  noAssetUrl?,
});
  • basePath: template root.
  • baseUrl (optional): required when assets are being collected unless an assetFormatter is supplied.
  • collectAssets: default asset manifest collection behaviour.
  • assetFormatter: callback receiving { baseUrl, filename, path, urlPath } for custom URLs.
  • noAssetUrl: drop the leading assets/ segment from generated URLs (defaults to true).

Methods

  • flatten(template, { withAssets? })string | { html, assets } (primary entry point)
  • flattenWithAssets(template){ html, assets } Flatten and process assets, simple mode
  • flattenNoAssets(template)string Flatten, don't process assets, simple mode

Helpers

  • toAst(template, { withAssets? })BlockNode | { ast, assets }
  • parse(template)BlockNode (AST only, no assets)

Types: AssetFile, BlockNode, TemplateRequest.


License

MIT - Copyright (c) 2025 Bjørn Erik Jacobsen / Technomoron

MIT