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

selfdocumenting

v0.8.1

Published

Code-aware static site generator with directive-based content extraction

Readme

selfdocumenting

Code-aware documentation site generator. Builds full static sites from Markdown templates and source code, with directive-based content extraction, auto-generated API/CLI reference pages, theming, search, SEO, and deploy to Cloudflare Pages or GitHub Pages.

Supports Python, Go, and TypeScript/JavaScript. One runtime dependency (strictcli). Pure Python.

Install

pip install selfdocumenting

or via npm (delegates to Python under the hood):

npm install -g selfdocumenting

Requires Python 3.11+.

The npm package is named selfdocumenting (npm blocks selfdoc due to name similarity). The CLI command remains selfdoc.

Quick start

# Initialize in an existing project (auto-detects language)
selfdoc init

# Auto-generate API and CLI reference pages
selfdoc gen

# Edit docs/ pages -- add directives referencing your code

# Build HTML output
selfdoc build

# Validate directives, coverage, and SEO lint
selfdoc check

# Serve locally with live reload
selfdoc serve

Features

  • Attribute-based directive syntax (:-:, :<:, :>:) for embedding code-extracted content
  • Auto-generated API reference and CLI docs from source code structure (selfdoc gen)
  • Sandboxed data generation scripts (selfdoc gen-data)
  • Theming with dark mode, accent colors, and custom CSS overrides
  • Pluggable search (builtin, Fuse.js, or MiniSearch)
  • 15+ SEO lint rules, WCAG contrast validation, JSON-LD structured data
  • Per-symbol documentation coverage tracking with configurable thresholds
  • Build-time Pygments syntax highlighting, code tabs, sortable tables
  • CSS/JS/HTML minification, critical CSS inlining, gzip and Brotli pre-compression
  • Atom feed, robots.txt with AI crawler controls, llms.txt / llms-full.txt
  • Landing page with hero section, tagline, and feature cards
  • SSE-based live reload dev server
  • Auto-commit of generated files (prefers safegit)

Directive syntax

Directives are inline blocks in your Markdown templates. They get replaced with content extracted from your source code at build time.

:-: directive-name path="arg"

Self-closing directives use :-:. Block directives that wrap a body use :<: to open, :>: to close, with :=: and ::: to delimit sections inside. Directives inside fenced code blocks are ignored.

Built-in directives

| Directive | Description | | --- | --- | | callout-danger | Styled danger callout block | | callout-important | Styled important callout block | | callout-note | Styled note callout block | | callout-tip | Styled tip callout block | | callout-warning | Styled warning callout block | | code-help | Extract CLI help/usage text and flag definitions | | code-test | Embed test source code (whole file or specific function) | | list-features | Module summaries from docstring first lines | | list-glossary | Definition list from Term: Definition lines | | list-modules | List source modules with file paths and docstring summaries | | list-tree | File/directory tree listing | | prose-desc | Extract module/package docstring as prose text | | ref | Extract module docstring, exported functions, and classes | | table-commands | CLI command summary table from strictcli structure | | table-config | Render a config file (JSON/TOML) as a key-value table | | table-config-schema | Configuration field reference table from schema | | table-dep | Dependencies table from pyproject.toml | | table-directives | Table of all core built-in directives | | table-schema | Extract dataclass/struct fields as a markdown table | | var | Interpolate project metadata value |

Example -- embed the API docs for a Python module:

## API Reference

:-: ref path="selfdoc.config"

Example -- show a JSON schema as a table:

:-: table-schema path="selfdoc.json"

Custom directives

Register custom directives in selfdoc.json under the directives key. Each entry maps a directive name to a Python script (relative to project root) that exports a resolve(attrs, config, body) function returning a Markdown string.

{
  "directives": {
    "changelog": "scripts/changelog_directive.py"
  }
}

Script interface:

def resolve(attrs: dict, config: dict, body: list) -> str:
    """Return Markdown string to replace the directive block.

    attrs  -- directive attributes as str->str dict (e.g. {"path": "v1.0.0"})
    config -- the full selfdoc.json config dict
    body   -- body lines from the directive block (empty list for one-liners)
    """
    version = attrs.get("path")
    ...

Use in templates:

:-: changelog path="v1.0.0"

Custom directives take priority over built-in names.

Configuration

selfdoc.json at the project root:

{
  "language": "python",
  "source": ["selfdoc/"],
  "docs": "docs/",
  "output": "docs/_build/",
  "deploy": {
    "provider": "cloudflare-pages",
    "project": "my-docs"
  },
  "directives": {}
}

| Field | Required | Description | | --- | --- | --- | | language | yes | Programming language of the documented project. | | source | yes | List of source directories or files to extract documentation from. | | base_url | yes | Base URL of the generated site, used for canonical links and SEO. | | docs | no | Directory containing Markdown documentation templates. | | output | no | Output directory for generated HTML files. | | theme | no | Visual theme for the generated site. | | repo | no | GitHub repository URL shown in the site header. | | lang | no | BCP 47 language tag for the site content (e.g. 'en', 'pt-BR'). | | description | no | Short description of the project, used in meta tags and SEO. | | branch | no | Git branch used for source links in the generated site. | | search | no | Search UI mode: icon button, full bar, or hidden. | | search_engine | no | Client-side search engine implementation to use. | | code_icons | no | Style of language icons shown on code blocks. | | line_numbers | no | Show line numbers in code blocks. | | run_button | no | Show a run button on code blocks for supported languages. | | page_nav | no | Show previous/next navigation links between pages. | | page_progress | no | Show a reading progress bar at the top of each page. | | glossary | no | Auto-generate a glossary page from dfn terms. | | min_coverage | no | Minimum documentation coverage percentage required by the check command. | | feed_max_entries | no | Maximum number of entries in the Atom feed, sorted by most recent. | | lint_ignore | no | List of lint rule IDs to suppress (e.g. 'SEO007'). | | root_files | no | List of underscore-prefixed template paths in docs/ for root file generation. | | deploy | no | Deployment configuration for publishing the generated site. | | directives | no | Custom directive mappings from directive name to source file path. | | author | no | Author information for meta tags and structured data. | | feedback | no | Feedback collection configuration (at least one of webhook or ga required). | | branding | no | Landing page branding and call-to-action configuration. | | auto_detect | no | Automatic content detection settings for step guides and API entries. | | gen | no | Configuration for the gen command. | | gen_data | no | Configuration for the gen-data command. |

selfdoc init auto-detects language and source paths from project files (pyproject.toml, go.mod, tsconfig.json, package.json).

Commands

| Command | Description | | --- | --- | | init | Initialize selfdoc in the current project | | build | Build the documentation site | | serve | Serve the documentation site locally | | deploy | Deploy the documentation site | | check | Check documentation coverage and consistency | | gen | Auto-generate documentation pages from project structure | | gen-data | Generate data files by running sandboxed scripts |

Deploy

Cloudflare Pages

Requires the Wrangler CLI installed and authenticated.

{
  "deploy": {
    "provider": "cloudflare-pages",
    "project": "my-docs-project"
  }
}
selfdoc build && selfdoc deploy

GitHub Pages

Pushes the output directory to the gh-pages branch via force-push.

{
  "deploy": {
    "provider": "github-pages"
  }
}

Enable GitHub Pages in your repo settings (source: gh-pages branch).

Integration with rlsbl

When rlsbl detects a selfdoc.json in the project, it can trigger selfdoc build and selfdoc deploy as part of the release lifecycle via the .rlsbl/hooks/post-release.sh hook.

License

MIT