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

@hardikg/mdview

v0.8.1

Published

Local CLI markdown viewer with live reload, outline navigation, and folder browsing

Downloads

33

Readme

mdview

Version License: MIT Node

A local markdown viewer for reading long, hierarchical docs without losing focus. Run a command, browser opens with a beautifully rendered, navigable view of your file or folder. Edits in your editor show up live. Close terminal to stop.

mdview ./docs              # browse a folder
mdview README.md           # view a single file
mdview                     # current directory

Why

Reading long markdown docs is hard:

  • You scroll, get distracted, come back, can't find your spot.
  • Deep inside a subsection, you forget how it relates to the parent topic.
  • AI-generated brainstorming docs grow as you iterate — paste-and-render tools can't keep up.
  • Raw markdown without color or rhythm is monotonous over hundreds of lines.

mdview is built for that. It's a single-machine, single-user, read-only viewer with editorial typography, persistent navigation, and live reload.

Install

npm install -g @hardikg/mdview

Requires Node >= 20. The mdview binary lands on your PATH.

Install from source

git clone https://github.com/hardikg2907/mdview.git
cd mdview
npm install
npm run build
npm install -g .          # puts `mdview` on your PATH

Or run from source without global install:

npm install && npm run build
node bin/mdview.mjs ./docs

Share with friends without publishing

npm run build && npm pack    # produces hardikg-mdview-<version>.tgz

Send them the .tgz (Slack/Drive/AirDrop). They install with:

npm install -g ./hardikg-mdview-<version>.tgz

Usage

mdview <path>              # open a file or folder; the shell comes straight back
mdview                     # current directory
mdview ls                  # what's open, and where the server is
mdview rm <name>           # stop serving a folder
mdview stop                # stop the background server
mdview --foreground        # run in this terminal instead (Ctrl-C to stop)
mdview --no-open           # don't auto-launch the browser
mdview --port 9000         # one-off server on a specific port (implies --foreground)
mdview --palette nord      # palette for this run (implies --foreground)
mdview --help              # show usage

One server, many folders

mdview does not hold your terminal. It starts a single background server the first time you need one, and every later mdview <path> — in any repo — adds that folder to the same server and opens it. So you can read ~/work/api/docs and ~/notes side by side in one window, with one stable URL, whether or not the folders are anywhere near each other.

$ mdview ~/work/api
mdview → http://mdview.localhost:7331/?root=api
added: /Users/you/work/api (api)
$ cd ~/notes && mdview .
mdview → http://mdview.localhost:7331/?root=notes
added: /Users/you/notes (notes)
$ mdview ls
● api    ~/work/api    (primary)
● notes  ~/notes

server:  http://mdview.localhost:7331/  (pid 40113)
logs:    ~/.config/mdview/daemon.log

Folders stay open until you remove them with mdview rm <name>, across restarts and reboots. Up to 8 at a time — each one holds a live file watcher, so the limit is there to keep mdview from quietly watching your whole disk. Opening a file or subfolder inside a folder that's already open reuses it rather than adding a duplicate.

The server keeps running until you mdview stop it, or you reboot. If you'd rather it stood down on its own, set MDVIEW_IDLE_TIMEOUT to a number of minutes and it will exit that long after the last browser tab disconnects; the next mdview starts it again.

Its state lives in ~/.config/mdview/ (daemon.json, workspace.json, daemon.log) and nowhere else. workspace.json is also how the CLI talks to the server: mdview <path> writes the file and the server picks the change up, which is why there is no HTTP endpoint that can change what's being served.

The URL is http://mdview.localhost:7331/*.localhost always resolves to loopback (RFC 6761) with no setup, and the server still listens on 127.0.0.1 only. If your resolver doesn't answer the name, mdview falls back to printing http://127.0.0.1:<port>/. Setting PORT changes the default port, so mdview works as-is behind a local proxy like portless if you want the port gone entirely.

--palette takes classic, paper, nord, solarized, or high-contrast. It wins over both .mdview.json and the global config, and never writes to either. There is also a --vscode flag, used by the VS Code extension to run mdview as a sidecar; it implies --no-open and prints a single JSON ready line instead of the human-readable output.

--port and --palette both override a setting that belongs to a whole server, and the background one is shared with every other folder you have open — so each implies --foreground, giving you a server of your own. That also means every invocation that worked before still behaves exactly as it did; only the bare mdview [path] form returns the shell now.

--foreground closes when you Ctrl-C or kill it. The background server is stopped with mdview stop. Set MDVIEW_DEBUG=1 for full stack traces on unexpected errors.

Keyboard shortcuts

| Shortcut | Action | |----------|--------| | ⌘P / Ctrl+P | Quick file switcher (fuzzy search) | | ⌘F / Ctrl+F or / | Open in-doc search | | ⇧⌘F / Ctrl+Shift+F | Open folder-wide search | | ⌘B / Ctrl+B | Toggle file tree | | ⌘. / Ctrl+. | Toggle outline | | ⌘\ / Ctrl+\ | Toggle theme | | j / k | Next / previous heading | | gg / ⇧G | Top / bottom of document | | [ / ] | Previous / next heading at the same level | | ⇧H / ⇧L | Previous / next file in folder | | Ctrl+D / Ctrl+U | Half-page down / up | | Alt / + scroll | Fast scroll (~4×) in the main pane | | f / m | Toggle focus mode / minimap | | e / ⇧E | Expand all / collapse all sections | | Tab (in search) | Cycle Doc ↔ Folder scope | | Enter / Shift+Enter | Next / previous match in search | | Esc | Close search / lightbox / panel | | ? | Open shortcuts panel |

Click the keyboard icon in the header anytime to see the full list.

Features

Reading

  • 3-pane layout: folder tree, content, outline. Both sidebars collapse to a thin label rail; both have drag handles to resize (widths persist).
  • Editorial typography (serif body, italic accent H1, paper-grain background, JetBrains Mono in code blocks).
  • Light & dark theme — follows your OS preference, with a manual override that persists.
  • Five built-in palettes: classic / paper / nord / solarized / high-contrast. Pick one from the header palette swatch. Code blocks follow the palette (Nord syntax in Nord, Solarized in Solarized, etc.).
  • Reading-progress bar pinned to the bottom of the header.
  • Doc stats strip below the H1 (reading time, word count, heading count, "Updated N ago").
  • Focus mode dims everything except the section at the viewport center.
  • Optional minimap rail at the right edge: bars per heading, draggable to scroll, viewport indicator follows.

Navigation

  • Folder tree sidebar; click any file to load it. Cross-file [link](other.md) navigates inside the viewer.
  • Outline sidebar with scroll-spy and collapsible nesting. Six toggle pills (H1H6) filter which levels show.
  • Breadcrumbs in the header reflecting your current viewport heading; click any segment to jump.
  • Stable per-heading anchors. Hover any heading to reveal a # link that copies a deep-link URL.
  • Collapsible sections — every heading has a hover-revealed chevron that folds the section's content; anchor links auto-expand their target. e / ⇧E expand or collapse the whole doc.
  • ⌘P quick file switcher with fuzzy matching across the whole tree.

Rendering

  • CommonMark + GFM (tables, task lists, strikethrough, autolinks).
  • Server-side syntax highlighting via Shiki, palette-aware (10 variants per token — one for every palette/theme combination) — zero client highlighter bundle, no re-render on theme/palette swap.
  • Mermaid diagrams, lazy-loaded only when a doc contains a mermaid fence.
  • Math via KaTeX ($inline$ and $$block$$), lazy-loaded only when a doc contains math.
  • Custom-styled task list checkboxes (filled accent when checked, hollow when unchecked).
  • Front matter detected and shown as a small collapsible metadata block.
  • Inline HTML pass-through (your content, your trust).
  • Images render via a safe /__asset/* route with relative-path resolution against the file's folder. Click any image to open in a lightbox.
  • External links get an icon and open in a new tab with noopener noreferrer.

Live reload

  • File edits show up instantly. Scroll position and outline collapse state are preserved.

Search

  • In-doc search highlights all matches; counter shows current position; Enter/Shift+Enter step through them.
  • Folder-wide search greps every markdown file (⇧⌘F or the Folder toggle); results grouped by file with snippets, click any hit to open that file.
  • Three options on the search bar: Aa (case-sensitive), ab (whole word), .* (regex).

Polish

  • Loading skeleton while files first load.
  • Smooth transitions on theme swap, sidebar collapse, outline highlight.
  • Copy button on every code block.
  • Subtle hover tooltips on every header control.

Config

Two layered files, both optional, same schema:

  • Global: ~/.config/mdview/config.json (honours $XDG_CONFIG_HOME) — your machine-wide defaults.
  • Per-project: .mdview.json at the folder root — overrides global for this folder.
{
  "palette": "nord",
  "fontFamily": "serif",
  "lineWidth": "70ch",
  "defaultCollapsed": { "tree": false, "outline": false },
  "ignore": ["deps", "_site"]
}

All fields optional. Validated on load — invalid values fall back silently with a warning. Edit the per-project file while the server is running and the SPA picks up palette/font/lineWidth changes live; ignore is read once at startup (the file watcher's skip list is frozen — restart mdview after editing).

ignore extends the built-in skip list (which already covers node_modules, dist, build, out, target, coverage, vendor, __pycache__, venv, Pods, DerivedData, _build, plus every dotfile/dotdir). Add your own basenames here — handy when running mdview at a repo root with non-standard build dirs to avoid EMFILE: too many open files from the OS file-watch limit.

You can edit the ignore list from the CLI without opening the JSON:

mdview config path                  # print the global config path
mdview config ignore list           # show built-in + user-added entries
mdview config ignore add deps _site # add one or more basenames
mdview config ignore rm  deps       # remove one or more basenames

Stack

Node 20+, TypeScript, Fastify 5, markdown-it 14, Shiki 1, gray-matter, chokidar 4, Preact 10 + @preact/signals, KaTeX 0.16, mermaid 11 (lazy), JetBrains Mono via @fontsource, Vite 6, tsup 8, vitest 2.

Documentation

Tests

npm test            # vitest, server + client
npm run typecheck   # both tsconfigs
npm run build       # vite (client) + tsup (server CLI)

Reporting issues

Found a bug or have a feature request? File it at github.com/hardikg2907/mdview/issues.

License

MIT.