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

@tforster/gilbert-monorepo

v1.0.0-rc.1

Published

Workspace container for the Gilbert and GilbertFile modules.

Downloads

11

Readme

Gilbert

Gilbert is a data-driven static site generator built on Web API streams. It generates content by merging structured data with Handlebars templates, processing scripts and stylesheets through esbuild, and passing static assets through unchanged — all via a single concurrent pipeline that completes a complex 200+ page site in well under a second.

[!IMPORTANT] Full documentation is in docs/. Tutorials, how-to guides, API reference, and architectural explanations are all there, organised by the Diátaxis framework.

Table of Contents

About

Gilbert is a streams-based, data-driven static site generator designed for modern deployment environments. Rather than walking a tree of markdown files, Gilbert accepts a stream of JSON data and merges it with in-memory Handlebars templates, generating each page on the fly.

  • Data-driven: Content is structured data — a JSON stream where each record maps a URI to a template key and its data properties. This approach supports arbitrarily complex information architectures without a rigid filesystem convention.

  • Web API streams: All I/O flows through the WHATWG Streams API (ReadableStream, TransformStream, WritableStream). There are no Node.js stream dependencies in the core engine, making Gilbert portable across Node.js ≥20, Deno, Bun, and Cloudflare Workers.

  • Concurrent pipelines: Templates, Scripts, Stylesheets, and Static Files run as four concurrent pipelines. A validated 200+ page build with all four pipelines completes in ~200ms on a modest workstation.

  • Decoupled adapters: Gilbert core accepts and returns streams. Filesystem I/O, GitHub API access, and Cloudflare R2 uploads are all separate adapter packages. Any ReadableStream<GilbertFile> is a valid source; any WritableStream<GilbertFile> is a valid destination.

Features

  • Template pipeline — Handlebars templates; includes/partials via {{> component}}; built-in HTML minification via a zero-dependency custom minifier that outperforms html-minifier-terser
  • Scripts pipeline — esbuild bundling, tree-shaking, and minification; source maps; configurable target (default esnext); full esbuild options passthrough
  • Stylesheets pipeline — esbuild CSS bundling; PostCSS Autoprefixer support; font/asset loaders; source maps
  • Static files pipeline — pass-through with folder structure preservation; no filesystem coupling in the core engine
  • Data middleware — array-based transformation pipeline applied to all data before rendering begins; enables markdown-to-HTML conversion, content enrichment, pagination, and global navigation across the full dataset
  • Custom MIME module — zero audit vulnerabilities; correct content-type derivation from file extension on every path rename
  • GilbertFile object modelpath, base, relative, contents (Uint8Array or ReadableStream), contentType, clone(), async toString(), toBuffer(); ReadableStream.tee() ensures stream independence on clone
  • webProducerKey — data convention that maps a URI record to its Handlebars template; supports path separators for component-based architectures (e.g. "webProducerKey": "/admin/report/report")
  • Programmatic APIgilbert.compile() returns a ReadableStream directly; pipe it anywhere
  • Zero audit vulnerabilities — all third-party dependencies audited; custom replacements used where vulnerabilities existed

Packages

| Package | Description | | -------------------------------------------------------- | ------------------------------------------------- | | @tforster/gilbert | Core engine — orchestrates all four pipelines | | @tforster/gilbert-file | GilbertFile virtual file object | | @tforster/gilbert-fs | Filesystem adapter (read/write via glob patterns) | | @tforster/gilbert-github | GitHub repository source adapter | | @tforster/gilbert-glob | Shared glob pattern matching utilities | | @tforster/gilbert-logger | Lightweight async logger; zero dependencies | | @tforster/gilbert-r2 | Cloudflare R2 destination adapter |

See the packages reference for full API details.

Quick Start

npm install @tforster/gilbert @tforster/gilbert-file @tforster/gilbert-fs
import Gilbert from "@tforster/gilbert";
import GilbertFS from "@tforster/gilbert-fs";

const dataAdapter = new GilbertFS({ base: "./src/data" });
const templatesAdapter = new GilbertFS({ base: "./src/templates" });
const componentsAdapter = new GilbertFS({ base: "./src/components" });

const gilbert = new Gilbert({
  data: { source: dataAdapter.read("**/*.json") },
  // Accept an array of streams to load templates from multiple sources.
  // All sources are merged into a single in-memory template map before rendering begins.
  templates: [templatesAdapter.read("**/*.hbs"), componentsAdapter.read("**/*.hbs")],
  scripts: ["./src/scripts/main.js"],
  stylesheets: ["./src/stylesheets/main.css"],
  // staticFiles also accepts an array — each stream is processed independently.
  staticFiles: [new GilbertFS({ base: "./src/files" }).read("**/*"), new GilbertFS({ base: "./src/assets" }).read("**/*")],
});

await gilbert.compile();
await gilbert.stream.pipeTo(new GilbertFS({ base: "./dist" }).write("./dist"));

For a full walkthrough, see the Getting Started tutorial.

API

Full API documentation is in docs/reference/api.md.

The core entry point is gilbert.compile(), which returns a ReadableStream<GilbertFile> directly. Content sources are not limited to the filesystem — any ReadableStream<GilbertFile> is a valid input, including gilbert-github (GitHub API) and custom adapters (REST APIs, databases, headless CMS systems).

Change Log

See CHANGELOG.md for more information.

Code of Conduct

See CODE_OF_CONDUCT.md for more information.

Contributing

See CONTRIBUTING.md for more information.

Meta

Troy Forster — @tforster[email protected]

See LICENSE for more information.

https://github.com/tforster/gilbert