Tsunagu

Extension system

A repository is an index URL pointing to a Tachiyomi-style JSON extension list. Each entry carries a name, package name, download links for its APK or JAR, an icon, and the sources it provides.

What an extension is

Manga and anime extensions are unmodified Mihon/Tachiyomi/Aniyomi extension APKs. Novel extensions are plain JavaScript files following the LNReader plugin shape. Tsunagu ships with zero built-in sources, everything comes from an installed extension.

Loading an APK extension

  • The APK is downloaded and its package name and manifest are read directly from the archive.
  • It’s converted from Dalvik bytecode to a JVM-runnable jar, since the sandbox isn’t an Android runtime.
  • It loads through a child-first classloader, so the extension’s own dependency versions win over the sandbox’s.
  • The loaded source is then driven over gRPC by the sandbox’s extension service.

Novel plugins

Each .js plugin runs inside its own embedded JavaScript context with a small CommonJS-style module shim and a cheerio-like DOM query API, so unmodified LNReader plugin code runs without a Node process.

Go/JVM contract

The gRPC service between the two covers loading and unloading extensions, searching, fetching chapters and pages or episodes and streams, reading and writing source preferences, and rendering per-source filter UIs from a generic filter tree, all without any per-source code on the Go side.