animedb
animedb is a Rust-first metadata project for local media servers.
Advisory:
animedbstores and normalizes public metadata, but it does not override provider Terms of Service, attribution requirements, authentication rules, rate limits or mature-content restrictions. Before enabling bulk sync for a source, verify that your intended usage is allowed by that source and configure conservative sync budgets.
It has two consumption modes that can be used separately or together:
- local-first: manage a local SQLite catalog with schema, downloads, sync, FTS5 search and JSON source payloads
- remote-first: query normalized metadata from remote providers without forcing client applications to manage persistence or provider-specific normalization
The project also ships a Rust GraphQL API on top of the same crate.
See REFERENCE.md for the current library and API reference.
Supported providers
| Provider | Media kinds | Data source | Licensed under |
|---|---|---|---|
| AniList | Anime, Manga | GraphQL API | AniList Terms |
| Jikan (MyAnimeList) | Anime, Manga | REST API | Jikan MIT |
| Kitsu | Anime, Manga | REST API | Kitsu API Policy |
| TVmaze | Shows | REST API (api.tvmaze.com) |
CC BY-SA 4.0 |
| IMDb | Movies, Shows | Official TSV datasets (datasets.imdb.com) |
IMDb Conditions |
Workspace
crates/animedb— library crate with SQLite schema management, sync and query APIscrates/animedb-api— GraphQL API binary built on top ofanimedb
Feature flags
# Full featured (local SQLite + all providers) — default
= "0.2"
# Remote-only, no SQLite dependency (safe for sqlx-based projects)
= { = "0.2", = false, = ["remote"] }
local-db(default): local SQLite storage, sync state persistence, and the [AnimeDb] type. This feature pulls inrusqlitewith a bundled SQLite.remote(default): remote provider clients and the normalized data model. Zero native dependencies.
Why feature gates? local-db requires rusqlite (bundled SQLite). Many Rust projects
already use sqlx with its own SQLite linkage, and Cargo rejects putting both in the same
dependency graph. If your project uses sqlx, depend on animedb with only features = ["remote"]
to get all provider clients, normalization types, and sync data structures without any SQLite
conflict.
Current Rust surface
Local-first
use ;
let = generate_database_with_report?;
println!;
let updated = sync_database?;
println!;
let monster = db.anime_metadata.by_external_id?;
println!;
let show = db.show_metadata.search?;
let show = db.get_by_external_id?;
let movies = db.movie_metadata.search?;
println!;
# Ok::
Remote-first
use AnimeDb;
let remote = remote_anilist;
let results = remote.anime_metadata.search?;
let media = remote.anime_metadata.by_id?;
# Ok::
Or choose the provider dynamically:
use ;
let remote = remote;
let results = remote.show_metadata.search?;
# Ok::
Media kinds
All providers map to one of four supported kinds:
SQLite schema
The SQLite catalog is created and migrated by the crate itself. The current schema includes:
media— canonical normalized recordsmedia_alias— normalized aliases and synonymsmedia_external_id— source-specific identifierssource_record— raw per-source JSON payloads and source update metadatafield_provenance— winner-per-field audit trail for canonical merge decisionssync_state— persisted sync checkpoints/cursorsmedia_fts—FTS5index for title, alias and synopsis search
The connection is configured with:
PRAGMA journal_mode=WALPRAGMA synchronous=NORMALPRAGMA foreign_keys=ONPRAGMA busy_timeout=5000PRAGMA temp_store=MEMORY
GraphQL API
The GraphQL API is provided by animedb-api. Run it locally:
Environment variables:
ANIMEDB_DATABASE_PATH— SQLite file path, default/data/animedb.sqliteANIMEDB_LISTEN_ADDR— bind address, default0.0.0.0:8080
Query example (search shows and movies):
{
search(query: "breaking bad", options: { limit: 5, mediaKind: SHOW }) {
mediaId
titleDisplay
mediaKind
genres
externalIds { source sourceId }
}
}
Docker
Build and run the Rust GraphQL API:
Make targets
The repository includes a Makefile for common workflows:
make build— compile the workspacemake test— run the Rust test suitemake test-e2e— run the end-to-end integration test (scripts/e2e_test.sh)make docker-build— build the API imagemake docker-run— run the API image locallymake debug-api— run the GraphQL API directly withcargo run