How perber/leafwiki works
1. Overall shape
LeafWiki is a single Go backend binary that serves both the API and the built frontend. It stores page content as Markdown on disk and uses SQLite for metadata/indexing state. The architecture is intentionally simple: a local data directory plus an HTTP server, with no external DB or queue dependencies.
2. Entry points and process startup
The main runtime is cmd/leafwiki/main.go. From there, the server is configured by CLI flags / env vars such as host, port, data directory, base path, auth mode, revision history, and link refactoring. The binary also exposes an admin reset command, and the Docker/container scripts mainly adjust defaults like binding to 0.0.0.0.
3. Backend layering
The backend is split into:
- internal/wiki/*: application use cases and route wiring
- internal/core/*: domain services and persistence-facing logic
- internal/http/*: HTTP router, middleware, DTOs, and static asset serving
This separation matters: the HTTP layer is thin, the wiki layer coordinates user-facing operations, and the core layer owns business rules like pages, links, tags, auth, search, revisions, and importing.
4. Primary domain boundary: pages and the tree
The central model is a hierarchical wiki tree, not a flat note list. Tree and slug behavior live in internal/core/tree, with page records, path lookup, and node storage. Higher-level page actions in internal/wiki/pages cover create, update, move, copy, delete, convert, and path ensuring. This is the main data model most other features hang off.
5. Save pipeline and side effects
Page saves are not a single write; they flow through internal/wiki/pagesave, which orchestrates effects after content changes. The save pipeline updates:
- link data
- tags
- properties / frontmatter
- search index
- revisions, if enabled
This is a key architectural boundary: editing a page triggers multiple synchronized subsystems.
6. Content intelligence: Markdown, links, tags, properties
Markdown parsing and frontmatter handling are in internal/core/markdown. Link extraction/refactoring/backlinks are in internal/links. Tags have their own service/store in internal/tags. Page metadata/property handling is in internal/properties. Together these form the content analysis layer that powers backlinks, broken links, tag views, page metadata, and link rewriting on rename/move.
7. Persistence model
Persistence is mixed:
- Markdown files / assets on disk for readable page content and uploads
- SQLite for structured state such as tree metadata, users/sessions, search index, tags/links/properties, and other app state
There are dedicated stores under internal/core/*/*_store.go, plus SQLite utilities in internal/core/shared/sqliteutil and search indexing in internal/search/sqlite_index.go. The filesystem is also used for revisions (internal/core/revision/fs_store.go) and imports/extracted archives.
8. Authentication, sessions, and security
Auth is a first-class subsystem under internal/core/auth and internal/wiki/auth. It supports roles (admin, editor, viewer), JWT-based sessions, password/login flows, and reverse-proxy auth via trusted headers. Security middleware adds CSRF protection, rate limiting, secure cookies, and secure transport checks. The app also supports --disable-auth and --public-access, which change the request authorization boundary substantially.
9. Import, backup, and maintenance operations
There are operational subsystems for content lifecycle outside normal page editing:
- internal/importer: ZIP extraction, workspace/planning, content transformation, import execution
- internal/backup: repository backup scheduling/status and .gitignore handling
- internal/core/tools: admin reset utilities
- internal/core/treemigration: structural migrations of the page tree
These are separate from the live editor flow and are exposed through their own routes/use cases.
10. HTTP API and route organization
internal/http/router.go and internal/http/registrar.go assemble the API, middleware, and route groups. The internal/wiki/*/routes.go files define feature-specific endpoints for pages, auth, search, tags, links, revisions, importer, assets, backup, branding, and health. This makes the public surface modular: each feature has its own route/use-case pair rather than one monolithic controller.
11. Frontend architecture
The UI lives in ui/leafwiki-ui as a React + Vite application. It is organized by feature folders rather than by generic component type:
- editor, viewer, tree, search, tags, auth, importer, backup, branding, users, shortcuts, toolbar, etc.
Frontend state is split across stores in src/stores, while API access is wrapped in src/lib/api/*. The app is built to consume the Go backend’s REST endpoints and render the wiki experience, including dialogs, sidebar tree, page viewer/editor, and mobile-friendly navigation.
12. Frontend-to-backend data flow
User actions in the UI typically flow as:
React feature component → store/API client → HTTP endpoint → wiki use case → core service/store → SQLite/filesystem
The reverse flow for display is the backend shaping DTOs in internal/http/dto and the frontend using those responses to populate the tree, viewer, editor, search, and metadata panels. This split is especially visible for page editing, where the UI must coordinate optimistic changes, autosave, navigation guards, and conflict handling.
13. Import/export and media handling
Assets are treated separately from page Markdown. The backend has an assets subsystem (internal/core/assets, internal/wiki/assets) and the UI includes asset managers and upload/preview features. Importing ZIP archives can bring in pages and attachments, with special handling for Obsidian-style wiki links and nested folder structures.
14. Testing and deployment signals
The repo is built around a strong test surface: Go unit/integration tests across core services, Playwright-based end-to-end tests in e2e, and a dedicated proxy-auth e2e harness in e2e-proxy/hacks/proxy-auth. CI workflows cover backend, frontend, E2E, linting, dependency review, and release. Deployment is mainly via Docker, a Linux installer, or a standalone binary, which reinforces the “single-process, self-hosted” architecture.
Main entry points: pagesave Save Pipeline · features Feature UI · wiki.go Wiki API · router.go HTTP Router
Components 21
Runtime
Single Go binary plus the built web UI it serves
- Main · CLI flags, env config, startup, and admin reset command
cmd/leafwiki/main.go
Backend
Go API, wiki use cases, domain services, and persistence
- HTTP Router · Registers middleware, routes, and static asset serving
internal/http/router.go - Route Registrar · Builds feature route groups and attaches handlers
internal/http/registrar.go - Middleware · Auth, CSRF, rate limiting, secure cookies, and proxy trust checks
internal/http/middleware - Wiki API · Coordinates feature-specific use cases and routes
internal/wiki/wiki.go - Pages · Create, update, move, copy, delete, convert, and path ensuring
internal/wiki/pages - Save Pipeline · Runs link, tag, property, search, and revision side effects after edits
internal/wiki/pagesave - Tree Model · Hierarchical page tree, slugs, lookups, node storage, and migrations
internal/core/tree - Markdown · Markdown and frontmatter parsing/serialization
internal/core/markdown - Links · Backlinks, outgoing links, extraction, and refactoring
internal/links - Tags · Tag extraction and tag store
internal/tags - Properties · Frontmatter-backed page properties and property store
internal/properties - Search · Search indexing and result retrieval
internal/search - Revisions · Filesystem-backed revision history and restore support
internal/core/revision - Auth · Roles, login, JWT sessions, proxy auth, and user/session stores
internal/core/auth - Assets · Uploads and asset lifecycle on disk
internal/core/assets
Frontend
React/Vite UI organized by feature
- UI App · Browser UI served by the backend binary
ui/leafwiki-ui/src/App.tsx - Feature UI · Editor, viewer, tree, search, tags, auth, importer, backup, and branding screens
ui/leafwiki-ui/src/features - API Client · Typed clients for backend REST endpoints
ui/leafwiki-ui/src/lib/api
Connections 28
- Main → HTTP Router: starts server · Main binary configures and launches the HTTP server
- Main → Wiki API: wires app · Bootstraps wiki services and use cases
- HTTP Router → Route Registrar: registers · Router composes feature route groups
- HTTP Router → Middleware: applies · Security and auth middleware wrap requests
- Route Registrar → Wiki API: dispatches to · Feature handlers call into wiki use cases
- Wiki API → Pages: pages · Page operations are coordinated through the wiki layer
- Wiki API → Auth: auth · Login, sessions, roles, and proxy auth flow through the auth subsystem
- Wiki API → Importer: import · Import routes and use cases execute content ingestion
- Wiki API → Backup: backup · Backup settings and status are exposed through wiki operations
- Pages → Tree Model: uses · Page actions operate on the hierarchical tree model
- Pages → Save Pipeline: saves through · Content edits flow into the save pipeline
- Save Pipeline → Markdown: parses · Save processing reads/writes markdown and frontmatter
- Save Pipeline → Links: updates · Link extraction and refactoring are synchronized after edits
- Save Pipeline → Tags: updates · Tag state is refreshed on save
- Save Pipeline → Properties: updates · Frontmatter properties are synchronized on save
- Save Pipeline → Search: indexes · Search index is refreshed after content changes
- Save Pipeline → Revisions: records · Revision history is written when enabled
- Links → Tree Model: renames with · Link refactoring follows tree moves and slug changes
- Search → Tree Model: indexes pages · Search uses page/tree metadata for lookup and results
- Importer → Tree Model: creates · Imports materialize content into the wiki tree
- Importer → Assets: extracts assets · ZIP imports can include attachments and media
- UI App → Feature UI: composes · Application shell mounts feature modules
- Feature UI → API Client: calls · Feature views use API clients for server data
- API Client → HTTP Router: requests · Frontend talks to backend REST endpoints
- Feature UI → Pages: edit pages · Editor, tree, viewer, and dialogs drive page operations
- Feature UI → Importer: run imports · Importer screen invokes import workflows
- Feature UI → Backup: manage backups · Backup settings and status are surfaced in the UI
- Feature UI → Auth: authenticate · Login and role-gated UI depends on auth state