@philvr/wiki-viewer
v0.8.1
Published
A tiny local CLI for viewing a directory of Markdown files as a browsable wiki.
Readme
@philvr/wiki-viewer
A tiny local CLI for viewing a directory of Markdown files as a browsable, read-only wiki.

Features
- Recursive page navigation, breadcrumbs, and an on-page outline.
- Search across page titles, paths, headings, and body text with
/or Cmd/Ctrl+K. - YAML frontmatter titles and configurable metadata fields.
- Rewritten relative Markdown links and safely contained local asset routes.
- Copy actions for Markdown source and fenced code blocks.
- Syntax highlighting plus responsive light and dark themes.
Usage
npx @philvr/wiki-viewer wiki --openThen open the URL printed by the command (usually http://127.0.0.1:4173).
The npm package runs a bundled native Rust binary on supported platforms. If a native binary is unavailable, the npm CLI shim falls back to the legacy Bun implementation, so Bun must be installed for that fallback path. You need Node.js 18 or newer to run the npm CLI shim.
The CLI reference below describes the flagship Rust binary. The legacy Bun
fallback supports the primary serving and configuration options, but not
--print-config, shell completion generation, or automatic port selection.
Options
wiki-viewer [options] [wiki-directory]
Options:
--dir, --wiki-dir <path> Directory of Markdown files. Default: wiki
--host <host> Hostname to bind. Default: 127.0.0.1
--port, -p <port> Exact port to bind. Otherwise finds one from 4173
--title <title> Browser title suffix and default brand. Default: current project directory
--brand <brand> Header brand text. Default: value of --title
--open Open the wiki in your default browser after startup
--log-requests Print each HTTP request with status and duration
--print-config Print effective config as JSON and exit
--generate-completions <shell> Print shell completions for bash, zsh, or fish
--public Bind to 0.0.0.0 and confirm network access with a warning
--version, -v Show version
--help, -h Show helpUse --public to make the wiki reachable from other devices on your network:
wiki-viewer wiki --publicBecause this serves local files from the wiki directory, any --host other than
localhost or a literal loopback address requires --public. The Rust server
also validates the address actually bound, rather than relying only on the
spelling passed to --host. It rejects unrelated HTTP Host headers; public
mode accepts IP address hosts and an explicitly configured hostname, such as
--public --host wiki.internal.
--log-requests prints one line per HTTP request with method, path, status, and elapsed time, for example: [request] GET /page/index -> 200 OK in 1.2ms.
Environment variables:
WIKI_HOSTWIKI_PORTWIKI_TITLEWIKI_BRAND
Without an explicit port, the Rust server prefers 4173 and automatically
selects an available port if it is occupied. The selected URL is printed and
used by --open. Ports supplied by --port, WIKI_PORT, or a configuration
file are treated as exact so configuration mistakes are not hidden.
By default, the title is the name of the current Git repository root. Outside a Git repository, it falls back to the current directory name.
Use --print-config to inspect the resolved configuration without starting the
server. Use --generate-completions bash, zsh, or fish to print a shell
completion script.
Configuration file
You can put wiki-viewer.config.json or .wiki-viewerrc in the directory where you run wiki-viewer:
{
"dir": "wiki",
"title": "Team Wiki",
"brand": "Docs",
"logRequests": false,
"metadataFields": ["type", "status", "owner", "updated"],
"ignoredPaths": ["drafts/", "private.md"]
}Supported keys: dir, wikiDir, host, port, title, brand, open, public, logRequests, metadataFields, ignore, and ignoredPaths.
Environment variables override config file values, and CLI options override both.
metadataFields selects top-level YAML frontmatter fields to display. Its
default is type, status, confidence, and updated. ignore and
ignoredPaths exclude both pages and assets; they accept exact paths, directory
prefixes, * within one path segment, and ** across directories.
Development
The flagship and default implementation is Rust. A current stable Rust toolchain is sufficient for application development:
cargo fmt --manifest-path ports/rust/Cargo.toml --check
cargo check --manifest-path ports/rust/Cargo.toml --all-targets --all-features
cargo clippy --manifest-path ports/rust/Cargo.toml --all-targets --all-features
cargo test --manifest-path ports/rust/Cargo.toml --all-features
cargo run --manifest-path ports/rust/Cargo.toml -- --dir ../some-project/wikiRoot package, fallback, release, and screenshot tooling additionally requires
Node.js 18 or newer and Bun 1.3.14 (the version pinned in package.json).
The repository is organized for three implementations under ports/:
ports/rust— flagship native binary implementation with parity/security tests and CI coverage.ports/bun— legacy TypeScript/Bun implementation and fallback/reference implementation.ports/go— simple native binary port with parity tests and CI coverage.
The root npm package prefers the Rust binary and uses the Bun implementation only as a legacy fallback. Go is maintained as a secondary native port and separate artifact.
bun install
bun run test:rust
bun run lint:rust
bun run build:rust
bun run dev:rust -- --dir ../some-project/wikibun install installs Lefthook Git hooks. The commit-msg hook rejects commit messages that do not follow Conventional Commits, for example feat: add search or fix(cli): handle missing wiki directory.
The legacy Bun and secondary Go ports retain their own test and build scripts in
package.json, but they are not the default development target.
Refresh the README screenshot
The screenshot harness builds and starts the Rust app against a deterministic demo wiki, waits for it to become ready, and captures it with Playwright:
bun run screenshot:install # one-time Chromium install
bun run screenshotThe default command replaces docs/assets/wiki-viewer.png. It also supports custom routes, fixtures, themes, viewport sizes, and output paths for future website assets:
bun run screenshot -- --theme dark --output docs/assets/wiki-viewer-dark.png
bun run screenshot -- --helpStandalone native binary
Build the Rust flagship executable for your current platform:
bun run build:binary
./build/wiki-viewer-linux-x64 --dir ../some-project/wikiThe output filename depends on your platform; run node scripts/build-binary.mjs --help to list target names.
Release CI builds each platform natively, with the Linux x64 package built on Ubuntu 22.04 so it works with Ubuntu 22.04's GLIBC version.
Each standalone artifact places LICENSE and THIRD_PARTY_LICENSES.html
beside the executable.
The binary contains the server code, but it still reads Markdown files from the --dir directory at runtime.
Standalone binaries are platform-specific; the publish workflow ships native Rust binaries for Linux x64, macOS arm64, and Windows x64. Unsupported platforms use the Bun fallback path when Bun is installed.
Native port artifacts
Build the Go and Rust ports from the repository root:
bun run build:go
bun run build:rust
bun run smoke:go
bun run smoke:rustThe native outputs are:
dist/wiki-viewer-godist/wiki-viewer-rust
The Rust binary is the flagship binary and reports the root package version. The Go binary reports the root package version with a -go suffix.
Releases
Releases are managed with Release Please and Conventional Commits.
- Merge changes to
mainusing Conventional Commit messages, such asfeat: add searchorfix: handle missing wiki directory. - Release Please opens or updates a release PR with the next version and
CHANGELOG.mdupdates. - Merge the release PR to create a GitHub Release.
- The npm publish workflow runs when the GitHub Release is published. It tests the project, builds the standalone Rust binaries, and publishes the package to npm.
Publishing uses npm trusted publishing from GitHub Actions.
Security
Do not report vulnerabilities in a public issue. See the security policy for the private reporting process and supported versions.
License
The wiki-viewer application is MIT licensed. Copyright (c) 2026 Phil Van Raalte. See
LICENSE.
Licenses for third-party crates used to build the Rust release binaries are
collected in THIRD_PARTY_LICENSES.html. Install
cargo-about 0.9.1 with its cli feature and run bun run licenses:rust after
changing ports/rust/Cargo.lock; CI verifies that the checked-in report remains
current. Licenses and required notices for agent tooling vendored in the source
repository are preserved in
.agents/THIRD_PARTY_NOTICES.md.
Notes
- The Rust server is read-only. Requested page content and assets are read from disk at request time; navigation and search summaries use a short-lived cache.
- Relative Markdown links to
.mdfiles are rewritten to wiki routes. - Relative image links are served from the wiki directory through safe
/assets/*routes. - Asset responses disable MIME sniffing. HTML, XML, PDF, and similar active documents download instead of executing, while SVG remains viewable under a browser sandbox policy.
- The Rust renderer highlights fenced code blocks with Syntect using styles selected for the system light or dark color scheme. The legacy Bun fallback uses Shiki.
- HTML in Markdown is escaped by the bundled renderer.
