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

@discontent/cms

v1.1.0

Published

The core CMS engine providing generic, reusable primitives for managing file-backed content. All functionality is driven by a `ContentTypeConfig` that consumers define to describe their specific content type.

Readme

@discontent/cms

The core CMS engine providing generic, reusable primitives for managing file-backed content. All functionality is driven by a ContentTypeConfig that consumers define to describe their specific content type.

ContentTypeConfig

ContentTypeConfig<TData, TIndexValue, TKey> is the central abstraction. It describes how a content type is stored, indexed, and referenced:

interface ContentTypeConfig<TData, TIndexValue, TKey extends Key> {
  contentType: string; // identifier, e.g. "recipes"
  dataDirectory: string; // subdirectory for data files
  indexDirectory: string; // subdirectory for the LMDB index
  dataFilename: string; // filename for each content item, e.g. "recipe.json"
  buildIndexValue(data: TData): TIndexValue;
  buildIndexKey(slug: string, data: TData): TKey;
  createDefaultSlug?(data: TData): string;
  uploadsDirectory?: string;
  referencedBy?: ReferenceSpec[]; // other types that reference this one by slug
}

Sub-modules

content/

Core CRUD operations and indexing.

| Export | Description | | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | createContent(options) | Creates a new content item on the filesystem and writes its index entry. Throws SlugConflictError if the slug is already taken. | | updateContent(options) | Updates an existing content item. Handles slug renames, index key changes, and optional upload processing. | | deleteContent(options) | Deletes a content item from the filesystem and removes its index entry. | | readContentFile(options) | Reads and returns the data file for a single content item by slug. | | readContentIndex(options) | Reads paginated entries from the LMDB index. Returns { entries, total, more }. Supports limit, offset, and reverse. | | rebuildIndex(options) | Scans all data files and rebuilds the LMDB index from scratch. |

All mutation functions accept an optional author and commitMessage to record a git commit after the change.

fs/

Filesystem helpers.

| Export | Description | | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | getContentDirectory() | Returns the content directory path. Respects CONTENT_DIRECTORY env var; falls back to test-content in TEST_MODE, then content. | | contentDirectory | Pre-resolved content directory path (evaluated at import time). | | collectFiles(dir, filename) | Recursively collects all files with a given name under a directory. |

git/

Git integration.

| Export | Description | | ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | | commitChanges(contentDirectory, message, author?, paths?) | Stages the given paths and creates a git commit. No-ops if the content directory is not a git repo. | | directoryIsGitRepo(dir) | Returns true if the directory contains a .git folder. |

forms/

Form data parsing.

| Export | Description | | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | parseFormData(schema, formData) | Validates a FormData object against a Zod schema, using lodash set for nested field assignment. Returns the parsed data or throws on validation failure. |

hooks/

React hooks.

| Export | Description | | ---------------------- | ------------------------------------------------------------------------------- | | useCurrentTimezone() | Returns the browser's current IANA timezone string using Intl.DateTimeFormat. |

Key Types

  • ReferenceSpec — Describes a content type that references another by slug. Used by updateContent to automatically update references when a slug changes.
  • UploadSpec — Per-field upload specification: a File, a fileImportUrl, a clearFile flag, or an existing filename.
  • FileUploadData — Resolved upload data passed to custom processUploads callbacks.

Part of Discontent