Architecture
Tsunagu is two processes in one package: a Go backend that owns the database, the API, and the download queue, and a JVM sandbox that runs extension code. There’s no separate deployment step for the sandbox, the Go backend supervises it as a child process.
Backend and sandbox
The two talk over gRPC on loopback, using the contract in proto/sandbox/v1/sandbox.proto. The sandbox is spawned lazily on first use, health-checked, and reaped after idle_timeout_minutes of inactivity. If it dies or was never started, every non-sandbox route (library, folders, downloads already on disk) keeps working.
GraphQL layer
Built with gqlgen. schema.graphqls is the source of truth; codegen produces the generated model and exec code, but the resolver file itself is hand-maintained after codegen rather than fully regenerated, since gqlgen’s resolver pass would overwrite hand-written helpers.
Download queue
A small worker pool pulls from the queue with pause, resume, reorder, and cancellation support, and automatically requeues anything left orphaned by a crash or restart. What actually gets downloaded depends on content type: page images for manga, chapter HTML for novels, or a muxed video file for anime.
Content filtering
Keyword rules are loaded from the database into an in-memory matcher, checked against genre, tag, title, or description fields, each with its own block level. A global level (unrestricted, moderate, or strict) decides which block levels actually get hidden. This is the engine behind Moku’s content filtering settings.
Cloudflare bypass
Three modes: disabled, external (Tsunagu talks to a FlareSolverr instance you run yourself), or managed, where Tsunagu downloads and runs its own pinned FlareSolverr binary on demand. Managed mode is only available on Linux and Windows amd64, there’s no upstream FlareSolverr build for macOS or arm64.