Dokster3000 is a high-performance, standalone C++ CLI that serves any folder of Markdown files as a fast, live-reloading wiki.
- Fast & Lightweight.
- Live Reload: Uses Linux
inotifyto detect file saves. The browser updates automatically via WebSockets the moment you hit "Save" in your editor. - Native Wikilinks: Support for
[[Wiki Links]]. - Substring Search: Quick navigation with
Ctrl + Kto filter through all your pages instantly. - Theme: you can theme it with your own CSS.
Dokster3000 uses the Linux-native inotify subsystem to recursively monitor the served directory. Unlike other tools that "poll" for changes (which wastes CPU), Dokster3000 sleeps until the OS signals that a file has been modified.
When you request a page:
- Fetch: The raw
.mdfile is read from disk. - Render: The
md4cengine (the fastest C Markdown parser) converts the Markdown to GitHub Flavored HTML. - Embed: The HTML is injected into a lightweight UI shell embedded directly in the C++ binary.
A persistent WebSocket connection is maintained between your browser and the server. The server pushes two signals:
- On connect, the server immediately sends
TREE:<json>so the sidebar populates without an HTTP fetch. - When
inotifydetects a change, the server rebuilds the tree and broadcastsTREE:<json>followed by aREFRESHsignal. The browser applies the new tree and performs a "DOM Swap" of the page content without losing your scroll position.
The server holds the file tree in memory and rebuilds it only when the filesystem changes.
- CMake 3.20+
- A C++20 compatible compiler (GCC 10+ or Clang 12+)
- Linux/WSL2 (for
inotifysupport) - CPU (I'd be worried if you can see this but don't have it)
- RAM (optional but recommended)
git clone https://github.com/fady5523/Dokster3000.git
cd Dokster3000
cmake -S . -B build #this downloads the dependencies so it might take a while if you have a slow internet connection
cmake --build build -j./install.sh # → $HOME/.local/bin/dokster + man page./install.sh [prefix] # default prefix: $HOME/.local
Env vars:
PREFIX=... override the install prefix
DESTDIR=... stage installs for packaging
BUILD_DIR=... point at a different build directory (default: ./build)
dokster [options] [root_path]| Form | Effect |
|---|---|
dokster |
Serve the current working directory on http://0.0.0.0:3000 (LAN accessible) |
dokster ~/notes |
Serve a specific folder |
dokster --port 8080 ~/notes |
Custom port |
dokster --host 127.0.0.1 |
Restrict to localhost (no LAN access) |
dokster --help |
Full option list |
dokster --version |
Show version |
By default dokster binds to 0.0.0.0, so the server is reachable from your local network. Other devices on the same network can open http://<your-ip>:3000. To restrict to loopback only, pass --host 127.0.0.1.
Then open http://localhost:3000 (or http://<your-ip>:3000 from another device) in a browser:
- Browse your folder structure from the sidebar.
- Search with
Ctrl + K. - Edit any
.mdfile in your editor — the page updates the moment you save.
# Work on a project wiki
cd ~/projects/myapp/docs && dokster
# Quick personal notebook on a different port
dokster --port 9000 ~/notes
# Disable live reload (for benchmarks, CI, etc.)
dokster --no-watch ~/wiki
# Localhost only (don't expose to LAN)
dokster --host 127.0.0.1 ~/private-notesThe default content root is wherever you run it from.
index.mdis the default home page (/redirects to it).custom.css(optional, in the root) overrides the default theme..doksterignore(optional, in the root) for blacklisting files..doksterinclude(optional, in the root) for whitelisting files.
Pattern syntax:
*matches a single path component**matches zero or more components (only at the start or end of a pattern)?matches a single character- a bare name matches at any level —
buildmatchessub/build. A pattern containing/is anchored to the root;sub/buildmatches onlysub/build, nota/sub/build. - A leading
/anchors the pattern to the content root —/buildmatches the root-levelbuilddirectory and everything under it. - A trailing
/marks the pattern as directory-only — it matches directory entries but not regular files at that name.
See man dokster for the full reference, or man/dokster.1 in the source tree.
Usage: dokster [options] [root_path]
root_path Directory to serve (default: current working directory)
Options:
-p, --port <n> Port to listen on (default: 3000)
--host <addr> Address to bind (default: 0.0.0.0, serves LAN)
Use 127.0.0.1 to restrict to localhost
-w, --whitelist Use whitelist mode (default: blacklist)
-c, --config <file> Override ignore/include file
--no-watch Disable the inotify watcher
-h, --help Show this help and exit
-V, --version Show version and exit
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Usage error (bad flag, invalid port, port in use, conflicting options, whitelist without a config file) |
| 2 | Root path does not exist or is not a directory |
Dokster3000 is licensed under the GNU Affero General Public License v3.0.