https://github.com/perber/leafwiki
LeafWiki β A fast wiki for people who think in folders, not feeds. Single Go binary. Markdown on disk. No external database service.
https://github.com/perber/leafwiki
docker documentation file-based go knowledge-base markdown react runbooks self-hosted single-binary sqlite wiki
Last synced: 3 days ago
JSON representation
LeafWiki β A fast wiki for people who think in folders, not feeds. Single Go binary. Markdown on disk. No external database service.
- Host: GitHub
- URL: https://github.com/perber/leafwiki
- Owner: perber
- License: mit
- Created: 2025-03-25T21:24:11.000Z (11 months ago)
- Default Branch: main
- Last Pushed: 2026-01-25T01:11:15.000Z (10 days ago)
- Last Synced: 2026-01-25T10:57:01.538Z (10 days ago)
- Topics: docker, documentation, file-based, go, knowledge-base, markdown, react, runbooks, self-hosted, single-binary, sqlite, wiki
- Language: Go
- Homepage: https://demo.leafwiki.com
- Size: 5.03 MB
- Stars: 49
- Watchers: 1
- Forks: 10
- Open Issues: 39
-
Metadata Files:
- Readme: readme.md
- Changelog: CHANGELOG.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Codeowners: CODEOWNERS
Awesome Lists containing this project
README
# πΏ LeafWiki
**LeafWiki β A fast wiki for people who think in folders, not feeds**
Single Go binary. Markdown on disk. No external database service.
LeafWiki is a lightweight, self-hosted wiki for runbooks, internal docs, and technical notes β built for fast writing and explicit structure.
It keeps your content as plain Markdown on disk and gives you fast navigation, search, and editing β without running additional services.
---
## Live Demo
A public demo of LeafWiki is available here:
π **[demo.leafwiki.com](https://demo.leafwiki.com)**
Try: `Ctrl+E` to edit, `Ctrl+S` to save, `Ctrl+Shift+F` to open the search.
Login credentials are displayed on the demo site.
The demo instance resets automatically every hour, so all changes are temporary.
---
## Preview

---
**Mobile View:**
Mobile-friendly UI for reading (and editing) docs & runbooks on the go.
---
## What LeafWiki is good for today
LeafWiki focuses on personal and small-team documentation use cases today.
Team features will evolve over time, guided by real-world usage.
LeafWiki is currently well-suited for:
- Personal technical notes and documentation
- Project documentation maintained by one main contributor
- Runbooks, operational knowledge and engineering guides for small teams
- Structured content that benefits from explicit hierarchy and ordering
---
## Project Status
LeafWiki is stable for everyday use as a personal or primary-owner wiki.
The core features β writing, navigation, and search β are actively maintained and production-ready.
Collaboration is currently limited and follows a *last-write-wins* approach.
More advanced team-oriented capabilities are under development, with a focus on durability and predictable behavior.
**Current priorities:**
- Versioning
- Importing existing Markdown content
- Conflict handling for concurrent edits (optimistic locking)
Priorities are shaped by real-world usage, and development is iterative.
The platform will evolve cautiously toward team workflows while maintaining its principles of simplicity and low operational overhead.
> **LeafWiki** is actively developed and open to collaboration πΏ
See the [CHANGELOG](CHANGELOG.md) for release details.
---
## Why Another Wiki?
Most wiki tools become operational projects: databases, plugins, workflows, and setup decisions.
LeafWiki was designed around a few simple questions:
- Why require a complex database for Markdown content?
- Why should self-hosting a wiki require significant setup effort?
- Why canβt structure and navigation be handled explicitly while keeping files portable?
In practice, that means:
- Markdown on disk
- Explicit tree structure
- Single-binary or container deployment
- Minimal operational overhead
---
## Core principles
LeafWiki is built around a small set of clear principles:
- **Plain Markdown storage**
All content is stored as Markdown files on disk. This avoids vendor lock-in and keeps your data portable and transparent.
- **No external database required**
LeafWiki uses SQLite internally and does not require running or managing a separate database service.
- **Explicit structure management**
Structure is stored as metadata (JSON/SQLite) while page content stays plain Markdown.
- **Self-hosted by design**
Designed to run on a single server with minimal operational overhead.
---
### Data model
LeafWiki stores page content as Markdown files and uses a combination of JSON and SQLite for navigation, metadata, and search.
For details on the current model and its constraints, see [Known limitations](#known-limitations).
---
## What LeafWiki supports
- **Fast writing flow (editor + shortcuts)**
- **Explicit tree navigation**
- **Public read-only docs with authenticated editing**
- Built-in Markdown editor with live preview
- Brand customization (logo, favicon & site name)
- Full-text search across page titles and content
- Support for diagrams via Mermaid
- Image and asset support
- Dark mode and mobile-friendly UI
- Separation between admin, editor, and viewer users
- Keyboard shortcuts for common actions (like saving with Ctrl+S, ...)
## What LeafWiki is not
- Not a Confluence replacement
- Not real-time collaborative editing
- Not a workflow/approval/document-control platform
LeafWiki is designed to stay small, predictable, and easy to operate.
---
## Installation
LeafWiki is distributed as a single Go binary and can be run directly on the host or via Docker.
The sections below show a recommended quick start and a few common installation examples.
### Quick start
The easiest way to install LeafWiki is using the provided installation script:
```bash
sudo /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/perber/leafwiki/main/install.sh)"
```
This installs LeafWiki as a system service on the target machine.
The service is started automatically after installation.
> The installation script has been tested on Ubuntu.
> Feedback for other distributions is welcome via GitHub issues.
#### Deployment examples
- [Install LeafWiki with nginx on Ubuntu](docs/install/nginx.md)
- [Install LeafWiki on a Raspberry Pi](docs/install/raspberry.md)
#### Security notes
In interactive mode, environment variables appear in plain text in file `/etc/leafwiki/.env`.
Make sure that this file is accessible only to authorized users.
#### Installer script options
**Non-interactive mode**
The script supports non-interactive mode for automated deployments. Use the `--non-interactive` flag and provide configuration via an `.env` file.
An `.env.example` file is included showing all available environment variables. Copy and customize it as needed:
```bash
cp .env.example .env
# Edit .env with your configuration
sudo ./install.sh --non-interactive --env-file ./.env
```
### Docker
You can run LeafWiki as a container using Docker.
```bash
docker run -p 8080:8080 \
-v ~/leafwiki-data:/app/data \
ghcr.io/perber/leafwiki:latest \
--jwt-secret=yoursecret \
--admin-password=yourpassword
```
By default, the container binds to `0.0.0.0` so the wiki is reachable from your network.
The data directory inside the container is `/app/data`.
---
**Running as non-root user**
To avoid running the container as root, specify a user ID:
```bash
docker run -p 8080:8080 \
-u 1000:1000 \
-v ~/leafwiki-data:/app/data \
ghcr.io/perber/leafwiki:latest \
--jwt-secret=yoursecret \
--admin-password=yourpassword
```
Make sure that the mounted data directory is writable by the specified user.
The data directory inside the container will be `/app/data`..
---
### Manual installation
Download the latest release binary from GitHub, make it executable, and start the server:
```
chmod +x leafwiki
./leafwiki --jwt-secret=yoursecret --admin-password=yourpassword
```
**Note:** By default, the server listens on `127.0.0.1`, which means it will only be accessible from localhost. If you want to access the server from other machines on your network, add `--host=0.0.0.0` to the command:
```
./leafwiki --jwt-secret=yoursecret --admin-password=yourpassword --host=0.0.0.0
```
Default port is `8080`, and the default data directory is `./data`.
You can change the data directory with the `--data-dir` flag.
The JWT secret is required for authentication and should be kept secure.
## Authentication and admin user
### Reset Admin Password
If you need to reset the admin password, you can do so by running:
```bash
./leafwiki reset-admin-password
```
## Runtime Configuration
LeafWiki can be configured using command-line flags or environment variables.
These options control how the server runs after installation.
### CLI Flags
| Flag | Description | Default | Available since |
|---------------------------------|------------------------------------------------------------------------|---------------|-------------------|
| `--jwt-secret` | Secret used for signing JWTs (required) | β | β |
| `--host` | Host/IP address the server binds to | `127.0.0.1` | β |
| `--port` | Port the server listens on | `8080` | β |
| `--data-dir` | Directory where data is stored | `./data` | β |
| `--admin-password` | Initial admin password *(used only if no admin exists)* (required) | β | β |
| `--public-access` | Allow public read-only access | `false` | β |
| `--hide-link-metadata-section` | Hide link metadata section | `false` | β |
| `--inject-code-in-header` | Raw HTML/JS code injected into tag (e.g., analytics, custom CSS)| `""` | v0.6.0 |
| `--allow-insecure` | β οΈ Disables Secure & HttpOnly cookies (required for HTTP) | `false` | v0.7.0 |
| `--access-token-timeout` | Access token timeout duration (e.g. 24h, 15m) | `15m` | v0.7.0 |
| `--refresh-token-timeout` | Refresh token timeout duration (e.g. 168h, 7d) | `7d` | v0.7.0 |
| `--disable-auth` | β οΈ Disable authentication & authorization (internal networks only!) | `false` | v0.7.0 |
> When using the official Docker image, `LEAFWIKI_HOST` defaults to `0.0.0.0` if neither a `--host` flag nor `LEAFWIKI_HOST` is provided, as the container entrypoint sets this automatically.
### Environment Variables
The same configuration options can also be provided via environment variables.
This is especially useful in containerized or production environments.
| Variable | Description | Default | Available since |
|----------------------------------------|-------------------------------------------------------------------------|------------|-----------------|
| `LEAFWIKI_HOST` | Host/IP address the server binds to | `127.0.0.1`| - |
| `LEAFWIKI_PORT` | Port the server listens on | `8080` | - |
| `LEAFWIKI_DATA_DIR` | Path to the data storage directory | `./data` | - |
| `LEAFWIKI_ADMIN_PASSWORD` | Initial admin password *(used only if no admin exists yet)* (required) | β | - |
| `LEAFWIKI_JWT_SECRET` | Secret used to sign JWT tokens *(required)* | β | - |
| `LEAFWIKI_PUBLIC_ACCESS` | Allow public read-only access | `false` | - |
| `LEAFWIKI_HIDE_LINK_METADATA_SECTION` | Hide link metadata section | `false` | - |
| `LEAFWIKI_INJECT_CODE_IN_HEADER` | Raw HTML/JS code injected into tag (e.g., analytics, custom CSS) | `""` | v0.6.0 |
| `LEAFWIKI_ALLOW_INSECURE` | β οΈ Disables Secure & HttpOnly cookies (required for HTTP) | `false` | v0.7.0 |
| `LEAFWIKI_ACCESS_TOKEN_TIMEOUT` | Access token timeout duration (e.g. 24h, 15m) | `15m` | v0.7.0 |
| `LEAFWIKI_REFRESH_TOKEN_TIMEOUT` | Refresh token timeout duration (e.g. 168h, 7d) | `7d` | v0.7.0 |
| `LEAFWIKI_DISABLE_AUTH` | β οΈ Disable authentication & authorization (internal networks only!) | `false` | v0.7.0 |
These environment variables override the default values and are especially useful in containerized or production environments.
> When using the official Docker image, `LEAFWIKI_HOST` defaults to `0.0.0.0` if neither a `--host` flag nor `LEAFWIKI_HOST` is provided, as the container entrypoint sets this automatically.
### Security Overview - Since v0.7.0
LeafWiki includes several built-in security mechanisms enabled by default:
- **Secure, HttpOnly cookies** for session handling
- **Session-based authentication** backed by a local database
- **CSRF protection** for all state-changing requests
- **Rate limiting** on authentication-related endpoints
- **Role-based access** (admin, editor, viewer)
These features are **enabled by default** and provide safe defaults for most deployments.
β οΈ Disabling or weakening these protections (e.g. via `--disable-auth` or `--allow-insecure`)
should only be done in **trusted, internal environments**.
---
### β οΈ Security Warning: `--disable-auth`
> **β οΈ WARNING β USE WITH EXTREME CAUTION**
The `--disable-auth` flag **completely disables authentication and authorization** in LeafWiki.
When enabled:
- **Anyone with network access can edit, delete and modify all content**
- **No login, no roles, no session checks are enforced**
- **All security mechanisms are bypassed**
**This flag MUST NOT be used on public or internet-facing deployments.**
**Intended use cases only:**
- Local development
- Internal networks
- Environments protected by VPN and/or firewall
- Fully isolated test systems
If you use this flag, **you are fully responsible for securing access at the network level**.
**Safe example (local development only):**
```bash
./leafwiki --disable-auth --host=127.0.0.1
```
**For most setups, prefer:**
- Authentication enabled (default)
- `--public-access` for read-only public access
- Viewer role for read-only access
## Migrating existing Markdown content (community tool)
If you already have an existing folder of Markdown files, you can bootstrap a LeafWiki navigation tree using a small community-contributed helper script.
> **Community Tool**
> Useful for **initial migration** from existing Markdown structures into LeafWiki.
> Optional, provided βas isβ. Contributions are welcome
The script:
- Scans a Markdown directory (default: `data/root`)
- Normalizes folder/file names to LeafWiki conventions (lowercase, hyphens)
- Ensures every folder has an `index.md`
- Generates a `data/tree.json` so LeafWiki can navigate the structure
Location: `tools/generate-tree.py`
### preview changes (dry-run mode)
You can preview the changes without modifying any files using the `--preview` flag:
```bash
python3 tools/generate-tree.py --root data/root --preview
```
This will:
- show proposed renames, skipped files and added index.md files
- print a preview of the generated tree
- perform no changes.
### Generate tree.json and normalize Markdown structure
To actually apply the changes and generate `tree.json`, run:
```bash
python3 tools/generate-tree.py --root data/root --output data/tree.json
```
**Notes:**
- It will rename files/folders to enforce LeafWiki naming conventions (lowercase, hyphens)
- It will create blank `index.md` files in folders that lack them.
- This is intended as a one-time import step
- For ongoing structure management, use LeafWiki's UI.
> Contributed in [#523](https://github.com/perber/leafwiki/issues/523) - thanks to @nicgord
---
## Quick Start (Dev)
```
# 1. Clone the repo
git clone https://github.com/perber/leafwiki.git
cd leafwiki
# 2. Install frontend dependencies
cd ui/leafwiki-ui
npm install
npm run dev # Starts Vite dev server on http://localhost:5173
# 3. In another terminal, start the backend
cd ../../cmd/leafwiki
go run main.go --jwt-secret=yoursecret --public-access=true --allow-insecure=true --admin-password=yourpassword
# Note: The backend binds to 127.0.0.1 by default for security.
# If you need to access it from a different machine or network interface
# (e.g., testing on mobile or from another device), use:
# go run main.go --host=0.0.0.0
```
---
### Keyboard Shortcuts
| Action | Shortcut |
|----------------------------|--------------------------------------------|
| Switch to Edit Mode | `Ctrl + E` (or `Cmd + E`) |
| Switch to Search Pane | `Ctrl + Shift + F` (or `Cmd + Shift + F`) |
| Switch to Navigation Pane | `Ctrl + Shift + E` (or `Cmd + Shift + E`) |
| Save Page | `Ctrl + S` (or `Cmd + S`) |
| Bold Text | `Ctrl + B` (or `Cmd + B`) |
| Italic Text | `Ctrl + I` (or `Cmd + I`) |
| Headline 1 | `Ctrl + Alt + 1` (or `Cmd + Alt + 1`) |
| Headline 2 | `Ctrl + Alt + 2` (or `Cmd + Alt + 2`) |
| Headline 3 | `Ctrl + Alt + 3` (or `Cmd + Alt + 3`) |
`Ctrl+V` / `Cmd+V` for pasting images or files is also supported in the editor.
`Esc` can be used to exit modals, dialogs or the edit mode.
More shortcuts may be added in future releases.
---
## Known limitations
LeafWiki focuses on simplicity with a well-defined scope.
As a result, the following limitations apply today:
- **No built-in page history or versioning**
Saving changes overwrites the previous state. Versioning is a planned feature.
- **Basic concurrency handling**
Edits follow a last-write-wins model. Best suited for single maintainers or low-concurrency use.
- **Metadata not fully embedded in Markdown**
Page content is plain Markdown, but structure, metadata, user accounts, and search indexes are stored in SQLite.
- **Minimal access control**
No role-based permissions or fine-grained restrictions at this time.
---
### Available Builds
LeafWiki is available as a native binary for the following platforms:
- **Linux (x86_64 and ARM64)**
- **macOS (x86_64 and ARM64)**
- **Windows (x86_64)**
- **Raspberry Pi (tested with 64-bit OS)**
---
## Contributing
Contributions, discussions, and feedback are very welcome.
If you have ideas, questions, or run into issues, feel free to open an issue or start a discussion.
## Stay in the loop
Follow the repository to get updates about new releases and ongoing development.