Help us shape the future of Go! Take the 2026 Go Developer Survey

suchi

module
v0.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 24, 2026 License: AGPL-3.0

README

suchi

suchi

A self-hosted document archive that files itself.
Sanskrit सूची — "an index, a catalog, a list"; pronounced SOO-chee, like kimchi.

Homepage

Live demo · Quick start · Docs · Why I built it

Drop in a scan, an email attachment or a photo. Suchi reads it, gives it a useful title and files what it is sure about into a numbered category tree. Anything it is unsure about waits in the Inbox for you instead of being guessed. Originals are never modified, and the archive is also rendered as a plain folder tree you can browse without the app.

Suchi began as a personal and household archive. The same principles apply more broadly, so the built-in filing trees also include approachable starting points for freelancers and smaller teams.

  • One binary. Go, SQLite and files on disk. No Postgres, Redis, queue or telemetry service. Nothing calls out until you enable an integration.
  • One filing model. Numbered categories in the Johnny.Decimal style instead of overlapping tags, types and storage paths. Start from a built-in tree or import your own.
  • Deterministic automations first. Suchi calls its explicit text-matching rules automations; they run before any model. An optional model, either local (Ollama, llama.cpp) or any OpenAI-compatible endpoint, suggests titles, categories and dates. Sending document text to a hosted model requires explicit acknowledgement.
  • Capture from anywhere. Browser upload, watched folders, your own IMAP mailbox, and the Suchi Companion app for iOS and Android, which can queue and keep scans while offline.
  • Find it and follow up. OCR and full-text search, a calendar of dates linked to the text they came from, and document questions answered with links to the documents used.

[!NOTE] Suchi is early (v0.4.1). Back up the data directory, test a restore before relying on it, and read the database compatibility policy before upgrading.

Capabilities

Suchi combines SQLite, content-addressed storage, a Svelte interface, and a scoped HTTP API in one static Go binary. Original and derived bytes are stored immutably by SHA-256; SQLite metadata and the API—not the content store—enforce access.

  • OCR, thumbnails, barcodes, encrypted PDFs, ZUGFeRD invoices, and common image, ebook, Office, OpenDocument, mail, archive, and text formats.
  • Full-text search, numbered filing, physical archive serial numbers, retained QR-label scan splitting, version notes, typed custom fields, named exact-document links, saved Views, and folder layouts.
  • Filing systems with permanent codes, direct membership plus document ACLs, and SYS.AC category addresses after introduction; a single archive shows category codes. Numeric document IDs remain separate.
  • Browser, watched-folder, IMAP, and mobile intake; takeout exports, supported third-party imports, document versions, backups, and restore tooling.
  • Automations, approvals, selective rescans, optional model classification, Ask your documents, and suggested dates. Model use is optional and hosted egress requires acknowledgement.
  • Groups, object ACLs, OIDC, local authenticator/recovery-code 2FA, scoped tokens, Network-only and Public share links, audit events, MCP, and the Android/iOS Suchi Companion.

Reproducible binary-size and startup measurements live under hack/bench/latest-published/. See the comparison and architecture for scope and tradeoffs.

Container images · Releases · Actions

Quick Start

The versioned standard image is a convenient local evaluation starting point:

docker volume create suchi-data
docker run -d --name suchi --restart unless-stopped \
  -p 127.0.0.1:8000:8000 \
  -e PUBLIC_URL=http://127.0.0.1:8000 \
  -v suchi-data:/data \
  ghcr.io/johnnybravo-xyz/suchi:v0.4.1
docker logs suchi 2>&1 | grep token_minted

Open http://127.0.0.1:8000, enter the one-time setup token, and create the first admin account. The token expires after 24 hours; attempting to use an expired token writes a replacement to the server log. A minimal compose.yaml is also provided for operators who want editable mounts, networks, and image pins. See Getting started for direct binary, reverse-proxy, NAS, and production deployment paths.

After creating the administrator, choose a filing tree in Settings > Archive configuration > Filing tree. This is the only required archive setup step; the reminder remains until a preset, imported tree, or explicit Blank choice is saved.

This quick start is bound to loopback and pins the v0.4.1 image. A production server, including one reached by the mobile app, must use HTTPS and pin the selected release by its published image digest.

Images

  • v0.4.1 / latest: Alpine. Supports all listed formats and indexes scanned PDFs with Tesseract.
  • v0.4.1-full / latest-full: Debian. Adds OCRmyPDF so downloaded scanned PDFs can retain a searchable text layer.

Both images include anydoc, DjVu, HEIC/HEIF, and Outlook MSG support. The full image changes only the scanned-PDF archive behavior. See Supported file types for the exact routing and bare-metal dependencies.

Development

The workspace requires Go 1.27.3 or newer; plugin-api remains compatible with Go 1.24. SPA and documentation development require Bun.

git clone https://github.com/johnnybravo-xyz/suchi.git
cd suchi
make install-hooks
make check
make run

make run uses /tmp/suchi-dev and listens on http://127.0.0.1:8000. Useful verification commands:

make test
make lint
make ui-check
make smoke
make smoke-ingest
./hack/smoke-anydoc-docx.sh
make smoke-mail

The ci workflow runs formatting, vet, tests, static analysis, and the SPA build. The smoke workflow boots both images and verifies real PDF OCR and Outlook MSG ingestion.

Repository

plugin-api/   shared extension interfaces and types
core/         API, database, ingest pipeline, jobs, auth, and embedded UI
plugins/      local auth, OIDC, and LLM classifier modules
distro/       importable app assembly and shipped suchi / suchi-mcp entry points
ui/           Svelte SPA source
deploy/       self-hosting templates and mail intake sidecar
docs/         published documentation source
hack/         fixtures, benchmarks, smoke tests, and developer tools

The root module contains the shipped application; plugin-api stays separate for external plugins and the utilities under hack/ keep isolated dependency graphs. The empty ui module keeps Go tooling out of frontend dependencies. make build uses Bun to install locked frontend dependencies, generates the ignored SPA bundle, and produces dist/suchi; suchi doctor inventories configured egress, pipeline tools, schema and taxonomy state, data-directory writability, and selected job, backup, audit, upload-limit, and CAS indicators.

Documentation

Works with Johnny.Decimal, a trademark of Coruscade Pty Ltd. Suchi is independent and not endorsed by them. The built-in filing trees are CC0-1.0, unreviewed and not compliance advice. Filing systems share one server, SQLite/FTS and CAS; server administrators and host/backup operators remain trusted. A code prefix is not separate infrastructure or a legal-independence guarantee. See Permissions for the application boundary.

License

Copyright (c) 2026 Ritesh Shrivastav. Suchi is available under two licenses:

  • GNU Affero General Public License v3.0 — free for everyone. Note that if you modify Suchi and let others interact with it over a network, AGPL section 13 requires you to offer them its complete corresponding source.
  • Commercial license — for embedding Suchi in a proprietary product, or for running a modified instance as a service without that source-offer obligation. Write to contact@suchi.page.

Every feature, including OIDC, access controls, approvals and MCP, is in the AGPL version; no paid tier holds features back. The CLA exists so contributions can also be offered under the commercial license.

The AGPL offer begins with Suchi's first public release. Before that release, its repository and container images were private development artifacts and were not distributed to any third party.

The plugin interfaces in plugin-api/ are a separate module licensed under the Apache License 2.0, so third-party plugins may be released under any license, including proprietary ones.

Third-party components and their terms are listed in NOTICE. Contributions are accepted under the Contributor License Agreement.

Directories

Path Synopsis
core
api
Package api owns the JSON HTTP surface — endpoints under /api/*.
Package api owns the JSON HTTP surface — endpoints under /api/*.
approvals
Package approvals is suchi's state-machine engine for routing docs through review/approval chains, sign-offs with deadlines, and timeout-driven escalation.
Package approvals is suchi's state-machine engine for routing docs through review/approval chains, sign-offs with deadlines, and timeout-driven escalation.
archivelock
Package archivelock prevents multiple processes from opening one Suchi archive.
Package archivelock prevents multiple processes from opening one Suchi archive.
asn
Package asn validates archive serial numbers and their external QR labels.
Package asn validates archive serial numbers and their external QR labels.
audit
Package audit writes append-only audit_events rows.
Package audit writes append-only audit_events rows.
auth
Package auth is the authenticator chain.
Package auth is the authenticator chain.
authz
Package authz owns the decision layer: "may this user do X to this object?" The interface lives here so wiring stays boring, and so downstream builds can swap the implementation without touching handlers.
Package authz owns the decision layer: "may this user do X to this object?" The interface lives here so wiring stays boring, and so downstream builds can swap the implementation without touching handlers.
automations
Archive classification applies high-confidence filing metadata from similar documents when enabled by policy, retaining other candidates for review.
Archive classification applies high-confidence filing metadata from similar documents when enabled by policy, retaining other candidates for review.
backup
Package backup owns the periodic VACUUM INTO snapshot loop.
Package backup owns the periodic VACUUM INTO snapshot loop.
blob
Package blob is the content-addressed store.
Package blob is the content-addressed store.
config
Package config is the env-var-first config loader.
Package config is the env-var-first config loader.
crypto
Package crypto is the small AEAD envelope suchi uses to seal operator-supplied secrets (password-manager style) before they land in SQLite.
Package crypto is the small AEAD envelope suchi uses to seal operator-supplied secrets (password-manager style) before they land in SQLite.
customfield
Package customfield is the per-type dispatch layer for document_custom_field_values.
Package customfield is the per-type dispatch layer for document_custom_field_values.
db
Package db is suchi's SQLite bootstrap.
Package db is suchi's SQLite bootstrap.
db/compatibility
Package compatibility embeds frozen pre-stable database migrations.
Package compatibility embeds frozen pre-stable database migrations.
db/migrations
Package migrations embeds the active stable schema and prepares it for use.
Package migrations embeds the active stable schema and prepares it for use.
documentstate
Package documentstate binds inferred proposals to durable source and field generations.
Package documentstate binds inferred proposals to durable source and field generations.
emailaccounts
Package emailaccounts is the CRUD + secret-sealing surface for the `email_accounts` table.
Package emailaccounts is the CRUD + secret-sealing surface for the `email_accounts` table.
gc
Package gc is the blob mark-and-sweep for the CAS.
Package gc is the blob mark-and-sweep for the CAS.
httpx
Package httpx is the HTTP layer glue: middleware stack, security headers, request-id, auth wiring, rate limiting.
Package httpx is the HTTP layer glue: middleware stack, security headers, request-id, auth wiring, rate limiting.
i18n
Package i18n loads the server-rendered UI string catalogs.
Package i18n loads the server-rendered UI string catalogs.
importer/bundle
Package bundle imports an export bundle from an existing DMS.
Package bundle imports an export bundle from an existing DMS.
ingest
Package ingest contains the small contracts shared by ingest producers.
Package ingest contains the small contracts shared by ingest producers.
ingest/emailwatch
Package emailwatch is the third canonical ingest path (design principle 9): IMAP polling for "forward it, forget it" archival.
Package emailwatch is the third canonical ingest path (design principle 9): IMAP polling for "forward it, forget it" archival.
ingest/emailwatch/oauth
Package oauth wraps Microsoft's MSAL-Go PublicClient for the IMAP device-code flow.
Package oauth wraps Microsoft's MSAL-Go PublicClient for the IMAP device-code flow.
ingest/fswatch
Package fswatch is the read-only filesystem-watching ingest producer.
Package fswatch is the read-only filesystem-watching ingest producer.
ingest/sidecar
Package sidecar is the JSON sidecar spec every ingest producer (fs-watch, email-ingest, third-party scanners, cron scripts) can target.
Package sidecar is the JSON sidecar spec every ingest producer (fs-watch, email-ingest, third-party scanners, cron scripts) can target.
intelligence
Package intelligence defines validated, reviewable facts extracted from documents.
Package intelligence defines validated, reviewable facts extracted from documents.
jd
Package jd owns the Johnny.Decimal taxonomy: the neutral first-boot baseline, the built-in presets, and the inbox-category invariant.
Package jd owns the Johnny.Decimal taxonomy: the neutral first-boot baseline, the built-in presets, and the inbox-category invariant.
jd/importer
Package importer owns preview and atomic application of validated taxonomies.
Package importer owns preview and atomic application of validated taxonomies.
jd/presetfile
Package presetfile validates raw HuML and TOML taxonomy files before normalizing them into the application's filing tree.
Package presetfile validates raw HuML and TOML taxonomy files before normalizing them into the application's filing tree.
jd/systems
Package systems owns filing-system identity and entry, independently of the taxonomy tree and document permissions.
Package systems owns filing-system identity and entry, independently of the taxonomy tree and document permissions.
jobs
Package jobs is the durable outbox dispatcher.
Package jobs is the durable outbox dispatcher.
logx
Package logx configures the process-wide slog handler.
Package logx configures the process-wide slog handler.
mimeutil
Package mimeutil owns Suchi's document MIME registry.
Package mimeutil owns Suchi's document MIME registry.
netutil
Package netutil contains shared network-boundary checks.
Package netutil contains shared network-boundary checks.
pipeline/anydoc
Package anydoc extracts EPUB and office documents through the anydoc CLI.
Package anydoc extracts EPUB and office documents through the anydoc CLI.
pipeline/barcode
Package barcode extracts QR, DataMatrix, and Aztec values from images.
Package barcode extracts QR, DataMatrix, and Aztec values from images.
pipeline/djvu
Package djvu extracts text from DjVu files via djvutxt (from djvulibre-bin on Debian).
Package djvu extracts text from DjVu files via djvutxt (from djvulibre-bin on Debian).
pipeline/docsplit
Package docsplit plans opt-in PDF splitting from legacy disposable separator sheets or retained archive-serial-number QR labels.
Package docsplit plans opt-in PDF splitting from legacy disposable separator sheets or retained archive-serial-number QR labels.
pipeline/eml
Package eml parses RFC 5322 email messages (message/rfc822) for the ingest pipeline.
Package eml parses RFC 5322 email messages (message/rfc822) for the ingest pipeline.
pipeline/imgpdf
Package imgpdf wraps raster images in a PDF so the standard OCR path can extract text.
Package imgpdf wraps raster images in a PDF so the standard OCR path can extract text.
pipeline/msg
Package msg converts Outlook .msg files to RFC 822 bytes via msgconvert.
Package msg converts Outlook .msg files to RFC 822 bytes via msgconvert.
pipeline/ocrmypdf
Package ocrmypdf wraps the ocrmypdf CLI for the ingest pipeline.
Package ocrmypdf wraps the ocrmypdf CLI for the ingest pipeline.
pipeline/pageanalyze
Package pageanalyze rasterizes a PDF's pages to greyscale and computes a per-page whiteness score.
Package pageanalyze rasterizes a PDF's pages to greyscale and computes a per-page whiteness score.
pipeline/pdfinspector
Package pdfinspector routes a PDF between the "text-native shortcut" and the "scanned → OCR" paths.
Package pdfinspector routes a PDF between the "text-native shortcut" and the "scanned → OCR" paths.
pipeline/pipeconfig
Package pipeconfig holds tiny helpers that read pipeline knobs from the process environment.
Package pipeconfig holds tiny helpers that read pipeline knobs from the process environment.
pipeline/pipefile
Package pipefile holds small filesystem helpers shared by pipeline stages.
Package pipefile holds small filesystem helpers shared by pipeline stages.
pipeline/postingest
Package postingest runs extraction, classification, and rendering after a document lands.
Package postingest runs extraction, classification, and rendering after a document lands.
pipeline/preconsume
Package preconsume runs an optional operator script before built-in ingest.
Package preconsume runs an optional operator script before built-in ingest.
pipeline/qpdf
Package qpdf is the PDF normalization pre-step.
Package qpdf is the PDF normalization pre-step.
pipeline/tessocr
Package tessocr is the lightweight OCR path: pdftoppm rasterizes each page to a PGM, tesseract reads it back as text, we concatenate.
Package tessocr is the lightweight OCR path: pdftoppm rasterizes each page to a PGM, tesseract reads it back as text, we concatenate.
pipeline/zugferd
Package zugferd extracts structured invoice data from ZUGFeRD / Factur-X / XRechnung PDF/A-3 files.
Package zugferd extracts structured invoice data from ZUGFeRD / Factur-X / XRechnung PDF/A-3 files.
render/index
Package index projects the current tree-only taxonomy snapshot into a managed HuML file.
Package index projects the current tree-only taxonomy snapshot into a managed HuML file.
render/paths
Package paths renders bounded storage-path templates.
Package paths renders bounded storage-path templates.
render/view
Package view is the rendered-view projection: the human-browsable file tree at $DATA_DIR/rendered/...
Package view is the rendered-view projection: the human-browsable file tree at $DATA_DIR/rendered/...
sandbox
Package sandbox is the shared subprocess-invocation wrapper.
Package sandbox is the shared subprocess-invocation wrapper.
settings
Package settings is a thin typed wrapper over the settings key-value table.
Package settings is a thin typed wrapper over the settings key-value table.
slug
Package slug provides canonical slugs for taxonomy rows.
Package slug provides canonical slugs for taxonomy rows.
taxonomy
Package taxonomy is admin tooling over tags and correspondents.
Package taxonomy is admin tooling over tags and correspondents.
trash
Package trash owns permanent document deletion and fixed retention.
Package trash owns permanent document deletion and fixed retention.
ui
Package ui is the small browser-side glue the SPA depends on: form-based cookie login, first-boot bootstrap, direct-URL blob serving (preview + download), and a static /assets mount for the login/bootstrap chrome.
Package ui is the small browser-side glue the SPA depends on: form-based cookie login, first-boot bootstrap, direct-URL blob serving (preview + download), and a static /assets mount for the login/bootstrap chrome.
uiassets
Package uiassets verifies that generated frontend assets match their sources.
Package uiassets verifies that generated frontend assets match their sources.
distro
app
Package app assembles the compiled Suchi server.
Package app assembles the compiled Suchi server.
cmd/suchi command
Command suchi is the single-binary entry point.
Command suchi is the single-binary entry point.
demo
Demo-mode reset ticker removes expired visitor records, never CAS bytes.
Demo-mode reset ticker removes expired visitor records, never CAS bytes.
hack
asnfixture command
Command asnfixture writes a deterministic feeder-scan PDF with two retained ASN QR marker pages.
Command asnfixture writes a deterministic feeder-scan PDF with two retained ASN QR marker pages.
ui-assets command
plugin-api module
plugins
llm-classifier
SPDX-License-Identifier: AGPL-3.0-or-later
SPDX-License-Identifier: AGPL-3.0-or-later
local-auth
Package localauth is the built-in Authenticator plugin.
Package localauth is the built-in Authenticator plugin.
oidc
Package oidcauth is the generic OpenID Connect authenticator plugin.
Package oidcauth is the generic OpenID Connect authenticator plugin.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL