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 🙏

© 2025 – Pkg Stats / Ryan Hefner

usite

v3.0.0

Published

Tiny static site generator

Readme

uSite

Tests passing License: MIT

uSite is a tiny, flexible static website generator designed for programmers.

It consists of a powerful content transformation API and a minimal footprint—less than 90 lines of code can build a fully functional blog. With uSite, you are in full control of your build pipeline, conventions, and site structure.

🚀 Features

  • Minimalist: Core logic is lightweight and unopinionated.
  • Flexible: Define your own conventions and build steps.
  • Programmatic: Use standard JavaScript/TypeScript to generate your site.
  • Fast: Built on modern Node.js.

📦 Installation

Install uSite globally via npm:

npm install -g usite

🏁 Quick Start

  1. Create a project folder:

    mkdir my-website
    cd my-website
  2. Initialize a barebones site:

    usite init
  3. Install dependencies:

    npm install
  4. Generate your site:

    usite generate blog

    This runs the blog task defined in your configuration.

📝 Example: Custom Blog Build

Here is a complete example of how to build a blog using uSite. This script loads settings, processes markdown files, and renders them using Nunjucks templates.

const blog = new uSite();

// 1. Load website settings into the global context
blog.context.global = blog.loadOptions('website.json');

// 2. Load and process post files
const posts = blog.loadContent('content/post/*')
    .map((item) => {
        const file = item.rawContent;
        const [frontMatter, ...rest] = file.split('+++');
        const content = rest.join('+++').trim();
        const [excerpt] = content.split('<!-- excerpt -->');

        const meta = blog.utils.parseOptions(frontMatter);
        const slug = meta.slug || blog.utils.generateSlug(meta.title);

        return {
            meta,
            slug,
            content: blog.utils.parseMarkdown(content),
            excerpt: blog.utils.parseMarkdown(excerpt),
            relativeUrl: `post/${slug}`
        };
    })
    .sort((a, b) => b.meta.date.getTime() - a.meta.date.getTime());

// 3. Render individual post pages
posts.emit('template/single.njk', 'www/post/{slug}');

// 4. Group posts for pagination (e.g., 10 posts per page)
const postsPerPage = blog.context.global.postsPerPage || 10;
const postGroups = posts.group((post, index) => {
    return Math.floor(index / postsPerPage).toString();
});

// 5. Render pagination pages
postGroups.emit('template/list.njk', 'www/posts/{groupKey}');

// 6. Copy static assets
blog.copy('content/images', 'www/images');

// 7. Create the index page (alias for the first page of posts)
blog.copy('www/posts/0/index.html', 'www/index.html');

📚 API Reference

uSite

The main class for the static site generator.

  • loadOptions(path: string): Object Reads a file (JSON/YAML), detects the content type, and parses it into a JavaScript object.

  • loadContent<T>(path: string): ContentList<T> Loads files matching the glob pattern and returns a ContentList of ContentItems.

  • copy(sourcePath: string, destinationPath: string): void Copies files or directories from source to destination.

ContentItem

Represents a single file loaded by loadContent.

  • context: Object: Holds internal context and helper functions.
  • filePath: string: The absolute path to the source file.
  • rawContent: string: The raw string content of the file.

ContentList<T>

A collection of content items with transformation methods.

  • map<U>(fn: (item: T) => U): ContentList<U> Transforms each item in the list. Properties from the original item are copied to the new item, overriding duplicates.

  • emit(templateFn: string, destination: string): void Renders items using a Nunjucks template and writes them to the destination pattern (e.g., www/post/{slug}).

  • group(keyFn: (item: T, index: number) => string): ContentMap<T> Groups items by a key returned by the function. Useful for pagination or categories.

  • sort(sortFn: (a: T, b: T) => number): ContentList<T> Sorts the items in the list.

  • count(): number Returns the number of items.

  • get(i: number): T Returns the item at the specified index.

ContentMap<T>

A collection of grouped ContentLists.

  • emit(templateFn: string, destination: string): void Renders each group using a template.

  • filter(predicate: (group: ContentList<T>) => boolean): ContentMap<T> Filters groups based on the predicate.

📄 License

MIT