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

wikify.md

v1.0.1

Published

Runtime markdown docs viewer with Mermaid support for Fastify and framework-agnostic runtimes

Readme

wikify.md

wikify.md turns a folder of Markdown docs into a polished docs site with:

  • automatic sidebar from your file tree
  • full-text search
  • syntax highlighting
  • Mermaid diagram rendering (including .mmd files)
  • light/dark mode and simple theme customization

It ships with:

  • a framework-agnostic fetch handler (wikify.md)
  • a Fastify plugin (wikify.md/fastify)

Features

  • Serves a docs SPA under a configurable route prefix (default: /wiki)
  • Builds a nested sidebar from folders and .md / .mmd files
  • Prioritizes README.md in each folder for better landing pages
  • Supports in-app search (Cmd/Ctrl + K) across Markdown content
  • Renders Mermaid diagrams inline with an expandable pan/zoom viewer
  • Theme controls: default dark mode, accent color, and code highlight theme

Install

npm install wikify.md

Or with Bun:

bun add wikify.md

Quick Start

Framework-Agnostic (Default)

import { createServer } from "node:http"
import wikify from "wikify.md"

const wiki = wikify({
  docsDir: "./docs",
  prefix: "/wiki",
  title: "Project Docs",
})

createServer(async (req, res) => {
  const origin = `http://${req.headers.host ?? "localhost"}`
  const request = new Request(new URL(req.url ?? "/", origin), {
    method: req.method,
    headers: req.headers as HeadersInit,
  })

  const response = await wiki(request)
  if (!response) {
    res.statusCode = 404
    res.end("Not found")
    return
  }

  res.statusCode = response.status
  response.headers.forEach((value, key) => res.setHeader(key, value))
  res.end(Buffer.from(await response.arrayBuffer()))
}).listen(3000)

Open http://localhost:3000/wiki.

Express.js

import express from "express"
import wikify from "wikify.md"

const app = express()

const wiki = wikify({
  docsDir: "./docs",
  prefix: "/wiki",
  title: "Project Docs",
})

app.use(async (req, res, next) => {
  const request = new Request(`${req.protocol}://${req.get("host")}${req.originalUrl}`, {
    method: req.method,
    headers: req.headers as HeadersInit,
  })

  const response = await wiki(request)
  if (!response) return next()

  res.status(response.status)
  response.headers.forEach((value, key) => res.setHeader(key, value))
  res.send(Buffer.from(await response.arrayBuffer()))
})

app.listen(3000)

Open http://localhost:3000/wiki.

Fastify

import Fastify from "fastify"
import path from "node:path"
import wikify from "wikify.md/fastify"

const app = Fastify()

await app.register(wikify, {
  docsDir: path.resolve("./docs"),
  prefix: "/wiki",
  title: "Project Docs",
})

await app.listen({ port: 3000 })

Open http://localhost:3000/wiki.

Expected Docs Folder

docs/
  README.md
  getting-started.md
  architecture/
    README.md
    request-flow.mmd

Notes:

  • Hidden files/folders (starting with .) are ignored.
  • Only .md and .mmd files are listed in the sidebar.
  • .mmd files are rendered as Mermaid diagrams automatically.

Configuration

The same config shape is used by both wikify(config) and app.register(wikify, config):

| Option | Type | Default | Description | | --- | --- | --- | --- | | docsDir | string | required | Absolute or relative path to your docs directory | | prefix | string | /wiki | Route prefix where docs UI and APIs are mounted | | exclude | string[] | [] | Folder names to hide from tree/search | | title | string | Docs | Navbar title | | theme | WikifyTheme | { darkMode: true } | Theme options |

theme options

| Option | Type | Default | Description | | --- | --- | --- | --- | | darkMode | boolean | true | Initial color mode | | primaryColor | string | - | Accent color in hex (#rrggbb) | | codeTheme | HljsTheme | github-dark | Syntax highlight theme |

Supported codeTheme values:

  • github-dark
  • github
  • atom-one-dark
  • atom-one-light
  • nord
  • night-owl
  • tokyo-night-dark
  • monokai

Example With Theming

import path from "node:path"
import Fastify from "fastify"
import wikify from "wikify.md/fastify"

const app = Fastify()

await app.register(wikify, {
  docsDir: path.resolve("./docs"),
  prefix: "/docs",
  title: "Acme Docs",
  exclude: ["drafts", "private"],
  theme: {
    darkMode: true,
    primaryColor: "#7c3aed",
    codeTheme: "night-owl",
  },
})

Type-Safe Config Helper

If you keep config in a separate file, you can use defineConfig:

import { defineConfig } from "wikify.md"

export default defineConfig({
  docsDir: "./docs",
  prefix: "/wiki",
  title: "My Docs",
})

Routes Exposed

For a given prefix (for example /wiki), both variants expose:

  • GET /wiki and GET /wiki/* - docs UI shell
  • GET /wiki/assets/* - static built UI assets
  • GET /wiki/_api/tree - sidebar file tree data
  • GET /wiki/_api/file?path=... - raw file content
  • GET /wiki/_api/search?q=... - search results (up to 20)

Mermaid Support

You can use Mermaid either inside Markdown fences:

```mermaid
flowchart LR
  A[Client] --> B[Fastify]
  B --> C[Docs]
```

Or as standalone .mmd files in your docs folder.

Development

bun install
bun run dev
bun run build

Build outputs:

  • UI bundle: dist/ui
  • Framework-agnostic bundle + types: dist/plugin/index.*
  • Fastify plugin bundle + types: dist/plugin/fastify.*

Compatibility

  • Fastify: >=4
  • Framework-agnostic runtime: standard Web Request / Response
  • Package runtime is ESM-first with CJS export support

If your docs include Mermaid content from untrusted sources, review your content pipeline carefully before serving it.