# LeafWiki: A Single Go Binary Wiki With Markdown on Disk

> LeafWiki stores pages as Markdown files and a SQLite index behind one Go binary, aimed at homelabs and small teams that find Wiki.js or Outline too heavy to operate. The trade-off is deliberate narrowness: no real-time collaboration, no enterprise permission model.

**perber/leafwiki** — LeafWiki - Self-hosted wiki. Single Go binary, SQLite, Markdown on disk. No external database required.

- Repository: https://github.com/perber/leafwiki
- Website: https://leafwiki.com
- Stars: 1,159 · Forks: 89
- Language: Go
- License: MIT
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/perber-leafwiki

## The problem LeafWiki picks: documentation you can back up with cp -r

Most self-hosted wikis ask you to run a database. Wiki.js and Outline both expect external services, and the README names exactly that friction: if you looked at them and thought the stack was too much to operate for what you need, LeafWiki is aimed at you. The project's answer is to keep page content as Markdown files on disk next to a SQLite index, all behind a single Go binary. No Node.js at runtime, no Redis, no Postgres. The README states the backup story plainly: page content is readable outside the app, and backup is cp -r, with the caveat that you stop the app first.

The audience is narrow and stated: personal wikis, engineering notebooks, runbooks, internal team or homelab documentation, and existing Markdown or Obsidian vaults that need a structured UI. The README also lists who should walk away: organizations needing complex enterprise permissions or approval workflows, anyone wanting real-time collaborative editing, and teams shopping for a Confluence or Notion replacement. That honesty about scope is the most useful thing in the document.

## How the binary, SQLite index and Markdown files fit together

The repository layout tells you most of the architecture. cmd/ holds the entry point, internal/ the Go packages, ui/leafwiki-ui/ a Vite single-page app, and the Makefile copies the built SPA into internal/http/dist so it can be embedded in the binary with go:embed. The Dockerfile confirms this in three stages: Node builds the frontend, Go builds the backend with EmbedFrontend=true and Environment=production, and the final image copies a single leafwiki executable onto Alpine. That is why there is nothing else to install.

On the storage side, go.mod pulls in modernc.org/sqlite, a pure-Go SQLite implementation, which is consistent with CGO_ENABLED=0 in the build. Markdown rendering uses goldmark, and bluemonday handles sanitizing inline HTML, which the feature list mentions. The rest of the dependency list maps to visible features: go-git for the experimental Git backup, golang-jwt for tokens, pquerna/otp for what looks like TOTP, and prometheus/client_golang for metrics. The data flow is therefore: Markdown files and assets live in the data directory, SQLite carries the index and metadata that make search, tags, backlinks and ordering work, and the embedded SPA talks to the Go HTTP layer.

## Installing LeafWiki with Docker and editing your first page

The README's shortest path is a single docker run. It publishes port 8080, mounts a data directory, and passes the JWT secret and admin password as flags. The --allow-insecure=true flag is required for plain HTTP; the README says to omit it when serving over HTTPS and to make sure the reverse proxy forwards X-Forwarded-Proto: https.

```bash
docker run -p 8080:8080 \
    -v ~/leafwiki-data:/app/data \
    ghcr.io/perber/leafwiki:latest \
    --jwt-secret=yoursecret \
    --admin-password=yourpassword \
    --allow-insecure=true
```

After the container starts, open http://localhost:8080 and log in as the admin account you just configured. If you would rather not run anything yet, the README points at demo.leafwiki.com, which resets hourly and uses Ctrl+E to edit and Ctrl+S to save.

For a Compose deployment, the README gives the same settings as environment variables, with the LEAFWIKI_ prefix. Note the user: 1000:1000 line: the data directory must be writable by that user, which is the most common first-run failure.

```yaml
services:
  leafwiki:
    image: ghcr.io/perber/leafwiki:latest
    container_name: leafwiki
    user: 1000:1000
    ports:
      - "8080:8080"
    environment:
      - LEAFWIKI_JWT_SECRET=yourSecret
      - LEAFWIKI_ADMIN_PASSWORD=yourPassword
      - LEAFWIKI_ALLOW_INSECURE=true
```

Beyond Docker, the README lists Docker Compose, a Linux installer (install.sh, driven by .env.example values such as LEAFWIKI_ARCH and LEAFWIKI_VERSION) and plain binaries. The Makefile builds the self-contained binary with make build, which runs the frontend build first; make build-api produces an API-only binary for local Vite development. There is also an update.sh at the repository root for upgrades.

## Feature flags, access modes and the operational edges worth knowing

Several capabilities are opt-in rather than default, and that shapes what you actually get. Revision history is behind --enable-revision, with LEAFWIKI_MAX_REVISION_HISTORY and a LEAFWIKI_REVISION_COALESCE_WINDOW defaulting to 5m. Automatic link rewriting when pages are renamed or moved is behind --enable-link-refactor. Git backup, added in v0.11.3, is marked experimental. SMTP for password reset and invitations arrived in v0.13.0 and is disabled when LEAFWIKI_SMTP_HOST is unset. API keys for programmatic and agent access are described as admin-managed and read-only, and the README says they are in development and not yet ready for use, so do not plan automation around them.

Access control has three modes: fully internal, public read with login-only editing (LEAFWIKI_PUBLIC_ACCESS), or open editing without login (LEAFWIKI_DISABLE_AUTH). Roles are admin, editor and viewer. Reverse-proxy authentication via a trusted HTTP header exists from v0.10, configured through LEAFWIKI_ENABLE_HTTP_REMOTE_USER, LEAFWIKI_HTTP_REMOTE_USER_HEADER_NAME and LEAFWIKI_TRUSTED_PROXY_IPS. That last variable is the one to think about: trusting a header means anything that can reach the app and set it is effectively authenticated, so the trusted IP list is not optional decoration. There is also a Unix socket option from v0.11.3 and a --base-path flag for subpath hosting.

## Where LeafWiki is the wrong tool

Concurrent editing is the clearest boundary. The README lists optimistic locking for concurrent edits, which prevents silent overwrites but is not collaborative editing, and the project explicitly says real-time collaboration is not a fit. If two people need to work in the same page at the same time, this is the wrong product.

Permissions are the second boundary. Roles stop at admin, editor and viewer, and the README says complex enterprise permissions and approval workflows are not a fit. There is no review queue, no per-space ACL model described.

The Markdown importer is the third. It is a ZIP-based importer for editors and admins that supports Obsidian-style wiki link rewriting, and the README admits it works best with a reasonably clean folder structure and is not a fully automatic converter for all source formats. Expect manual cleanup on a messy vault.

Two smaller edges: KaTeX support covers $$...$$ blocks but the README states inline $...$ is not supported, and the backup procedure requires stopping the app before cp -r. Anyone who wants hot backups should read that as a constraint, not a footnote. The README does not document rollback for a failed upgrade.

## LeafWiki compared with Wiki.js, BookStack and Otterwiki

The related searches around this project are mostly other wiki names, and the comparison is fair to make. Wiki.js and Outline are the two the README itself names as the systems people find too heavy; both are Node.js applications that expect a database server, which is the operational difference LeafWiki is built around. BookStack takes a different route again: it is a PHP application with a MySQL or MariaDB backend and a book, chapter and page hierarchy. LeafWiki's hierarchy is a tree with manual ordering, where sort order is explicit rather than derived from the filename, and its storage is files on disk rather than rows in MySQL. Otterwiki is closer in spirit, a Python wiki that also keeps Markdown files on disk, but it is a Python application rather than a single Go binary with an embedded React frontend.

The practical distinction is not features, it is what you operate. LeafWiki asks you to run one container and keep a writable data directory. The others ask you to run an application plus a database, and in the Wiki.js case a Node runtime as well. If your documentation set is small and your patience for infrastructure is smaller, that difference decides the choice.

## Licence, maintenance and the cost of upgrading

LeafWiki is MIT licensed, and the Dockerfile carries the matching org.opencontainers.image.licenses label. That is permissive: you can run it commercially, modify it and redistribute it, provided you keep the copyright notice and licence text. The repository also ships a SECURITY.md and a CODE_OF_CONDUCT.md, and the build pipeline includes .trivyignore files, which suggests container scanning is part of the release process. This is not legal advice; read the LICENSE file for the actual terms.

On maintenance, the last push was on 2026-09-10, and v0.13.0 was released on 2026-09-08, with v0.12.0 and v0.12.1 before it in July and August 2026. The release cadence visible in the repository is roughly monthly. The repository is not archived.

Upgrade cost is where the version numbers matter. The database is SQLite and the content is Markdown, so the risky part of an upgrade is the schema and the index, not the files. The repository provides update.sh, and the README documents resetting the admin password and restoring a snapshot offline, which is the recovery path you would use if an upgrade goes wrong. What the README does not document is a downgrade procedure, so pin a version tag rather than tracking latest if you care about being able to step back. Feature flags add a second axis: enabling revisions or link refactoring later changes behaviour on existing pages, so decide those before the wiki fills up.

## Conclusion

Adopt LeafWiki if you want a small internal wiki or runbook store where the source of truth is a folder of Markdown files you can copy with cp -r while the app is stopped, and if tree navigation matters more than collaborative editing. Skip it if you need approval workflows, enterprise permissions or several people editing the same page at once. Before committing, verify three things yourself: that the operating mode you pick (LEAFWIKI_PUBLIC_ACCESS, LEAFWIKI_DISABLE_AUTH) matches your exposure, that --jwt-secret and the admin password are set rather than left at defaults, and that a restore from your data directory actually produces a working wiki on the version you pinned.

## FAQ

### What is the best open-source wiki platform?

There is no single answer, and LeafWiki does not claim to be one. The README positions it for engineers and self-hosters who want structured, long-lived documentation such as personal wikis, runbooks and homelab docs, and says it is intentionally narrower than systems like Confluence or Notion.

### Is Wiki.js free to use?

That is a question about Wiki.js, not LeafWiki, and the repository does not describe Wiki.js licensing. LeafWiki itself is MIT licensed, and the README names Wiki.js only as an example of a system some users find too heavy to operate.

### What is the most common wiki software used?

The repository does not track adoption of other wikis, so it cannot answer this. LeafWiki's own README lists three access modes and roles of admin, editor and viewer, and describes itself as a fit for small teams that want tree navigation over flat note feeds.

### What are GitHub wikis?

That is a question about GitHub's own wiki feature, which LeafWiki's documentation does not cover. LeafWiki is a separate self-hosted application: a single Go binary with SQLite and Markdown stored on disk, installed by Docker, a Linux installer or a plain binary.

## Sources

- [License: MIT](https://github.com/perber/leafwiki/blob/main/LICENSE)
- [perber/leafwiki on GitHub](https://github.com/perber/leafwiki)
- [Project website](https://leafwiki.com)
- [README](https://github.com/perber/leafwiki/blob/main/README.md)
- [Releases](https://github.com/perber/leafwiki/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/perber-leafwiki
