A personal collection of seanime custom-sources and plugins — track manga that isn't on AniList, mirror your reads to MangaUpdates, and tune the library grid.
Extensions · Quick Start · Tech Stack · Development · Contributing
seanime supports third-party extensions — TypeScript bundles it fetches and runs in a sandboxed goja runtime.
This repo is a small, manga-focused set of them. Each extension is a code.ts entry plus a manifest.json; the build transpiles it to a sibling code.js that seanime loads from a raw GitHub URL. Source and built payload are both committed, and a generated marketplace.json lets you install the whole set from the seanime UI.
| Extension | Type | What it does | |
|---|---|---|---|
| Local Catalog | custom-source | Serve a self-curated manga catalog for titles not on AniList / MangaUpdates. | |
| Local Catalog Manager | plugin | Add/edit/delete the local catalog from inside seanime and sync it (plus reading progress) to a GitHub Gist. | |
| MangaUpdates | custom-source | Add MangaUpdates as a search & details metadata source. | |
| MangaUpdates Sync | plugin | Push your reading progress, status and score to MangaUpdates. | |
| Library Grid Layout | plugin | Set cards-per-row of the library grids, per screen size. | |
| Manga Source Updates | plugin | Scan your reading list across all providers to find which sources have new chapters. |
Two are pairs: Local Catalog + Local Catalog Manager (the plugin curates the catalog the source serves), and MangaUpdates + MangaUpdates Sync (the source finds titles, the plugin tracks them). Library Grid Layout and Manga Source Updates are standalone.
Install everything from the marketplace — in seanime go to Settings → Extensions and set the marketplace URL to:
https://raw.githubusercontent.com/Carloss616/seanime-extensions/main/marketplace.json
Other install methods
- Single extension — Add Extension, then paste the raw URL of that extension's
manifest.json. - Local (no hosting) — copy the extension's
manifest.jsoninto$SEANIME_DATA_DIR/extensions/and reload extensions.
Each extension's own README covers its configuration.
| Tool | Role |
|---|---|
| Bun | Bundler + test runner + task runner |
| TypeScript | Source language (typechecked against the goja .d.ts surface) |
| Biome | Lint + format |
| goja | The Go JS engine seanime runs the bundles in (no Node, no browser) |
Repository layout
.
├── src/
│ ├── <type>/<id>/ one folder per extension
│ │ ├── code.ts entry source — registers hooks / UI
│ │ ├── code.js built payload, the payloadURI target (generated)
│ │ ├── manifest.json source-of-truth manifest
│ │ ├── assets/icon.png
│ │ ├── modules/ one file per goja-isolated callback (optional)
│ │ ├── utils/ helpers imported by modules (optional)
│ │ └── README.md
│ ├── _utils/ code shared across extensions
│ └── _components/ declarative $ui builders
├── types/ .d.ts surface for the goja runtime
├── scripts/build.ts build all + regen marketplace.json
└── marketplace.json generated index — never edit by hand
<type> is one of custom-source, manga-provider, anime-torrent-provider, onlinestream-provider, plugin.
Requires Bun on PATH. Run bun install once.
| Command | What it does |
|---|---|
bun run build |
Build every extension (code.ts → code.js) and regenerate marketplace.json. |
bun run typecheck |
tsc --noEmit over src/ + types/, and over scripts/. |
bun run check |
Biome lint + format check (check:fix to autofix). |
bun run test |
Unit tests, co-located as src/**/*.test.ts. |
Warning
marketplace.json is generated from each manifest.json — never edit it by hand; it's overwritten on the next build.
How extensions are bundled (the modules/ convention)
seanime runs each hook ($app.on*) and the $ui.register callback in an isolated goja runtime: it serializes the callback with .toString() and re-evals it there. A callback therefore cannot read module-scope variables — any helper it needs must live physically inside its own body.
The convention that keeps that DRY: put each isolated callback in modules/ (exporting one function), put shared helpers in utils/, and import them normally. The build bundles each modules/*.ts standalone and re-emits it as a self-contained function that carries its dependencies inline. See the wrapper comment in scripts/build.ts for the exact mechanic.
A custom-source isn't serialized per-callback, so it can be a single code.ts — see mangaupdates.
- MangaUpdates custom-source + reading-state sync
- Local Catalog custom-source + in-app manager
- Cross-device catalog & reading-progress sync via GitHub Gist
- Library grid column control
- Cross-provider new-chapter scanning (Manga Source Updates)
- Anime support in Local Catalog (
animenamespace is reserved, not served yet) - Pull-diff UI for MangaUpdates Sync (currently push-only)
- Configurable cron auto-scan for Manga Source Updates (scheduled background scans instead of manual only)
Fork → branch (feature/your-change) → bun run build && bun run typecheck && bun run test → open a PR. New extensions go under src/<type>/<id>/; see the bundling notes above and CLAUDE.md for the runtime constraints.
Carlos Espinoza. Licensed under MIT.