Zim is a SQLite-only CLI and local web application for ZIM archives. The archive is authoritative; SQLite full-text and vector indexes are disposable derivatives that can always be rebuilt.
main -> cmd.App
|-- config + library
|-- indexer + search
`-- webui
|-- archive
`-- search
indexer/search -> indexstore + embeddings + archive
main owns process signals and the single exit-status translation. cmd.App owns one invocation's configuration and streams. Domain packages do not import cmd or webui.
- The instance-scoped configuration loader applies environment, canonical XDG, legacy, system, and default precedence.
- A concrete library service resolves CLI names beneath
library.path. - Web requests may select only a canonical archive beneath that root or the explicit startup archive.
- The archive manager caches handles by canonical path and closes every handle during server shutdown.
internal/indexstore.SQLiteStore owns the unchanged SQLite schema. The indexer owns bounded workers, article extraction, optional embeddings, batches, cancellation, progress events, and failed-run cleanup. Search owns FTS, semantic search, indexed-only all-library search, and the missing-index native-ZIM fallback.
zim serve <file> runs the embedded Svelte application and JSON API. zim ui <file> is a deprecated alias for the same implementation. Archive HTML is never inserted into the SPA. The SPA loads a separate document URL in a sandboxed iframe, and that response applies a restrictive CSP and rewrites validated archive links and resources while preserving the selected library.
The production Svelte bundle is tracked at internal/webui/dist and embedded by its owning Go package. Regenerate it from web/ with npm ci && npm run build; a clean Go checkout does not require Node to build or test.