Kioku is anime-manga-light novel app tracker, with notifications, etc...
  • Go 64.4%
  • Svelte 22.6%
  • TypeScript 11.7%
  • JavaScript 0.6%
  • Shell 0.3%
  • Other 0.2%
Find a file
Toxuki 8800f838e6 docs(backlog): what naming titles out of the library by the catalog would need
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-28 18:57:42 +01:00
.agent docs(backlog): what naming titles out of the library by the catalog would need 2026-10-28 18:57:42 +01:00
.forgejo/workflows docs: release notes for 1.0.0 and a release workflow 2026-10-14 00:47:30 +02:00
api feat(seasons): the season deck's passes hold on every device 2026-10-28 13:42:53 +01:00
cmd fix(security): the ways into the app kept to who they are for 2026-10-28 11:25:24 +01:00
deploy docs(release): notes for 2.158.0 2026-10-28 18:51:34 +01:00
docs docs(release): notes for 2.158.0 2026-10-28 18:51:34 +01:00
extension fix(watch): the review of the streaming flow and the copies, and release notes for 2.141.0 2026-10-23 21:17:43 +02:00
internal test(accounts): plain words in a test's note 2026-10-28 18:50:40 +01:00
scripts feat(deploy): a helm chart for running the server on kubernetes 2026-10-20 03:44:59 +02:00
tools fix(release): the review of the flatpak 2026-10-27 17:45:12 +01:00
web feat(questions): every no about one's tags holds on every device 2026-10-28 16:22:57 +01:00
.air.toml feat(desktop): run as a desktop app with a window of its own 2026-10-13 19:19:51 +02:00
.containerignore feat(server): kioku-server with accounts and a podman deployment 2026-10-15 23:38:51 +02:00
.gitignore feat(deploy): compose, a script and a full read-me for hosting 2026-10-18 00:23:51 +02:00
.golangci.yml feat(mal): myanimelist provider with pkce login and xml import/export 2026-10-13 16:01:24 +02:00
anime-tracker-agent-prompt.md build: skeleton with makefile, embed pipeline, budget and slopcheck 2026-10-13 14:39:46 +02:00
DONE.md docs: release notes for 1.0.0 and a release workflow 2026-10-14 00:47:30 +02:00
go.mod feat(server): passkeys to sign in without a password 2026-10-20 02:02:42 +02:00
go.sum feat(server): passkeys to sign in without a password 2026-10-20 02:02:42 +02:00
Makefile feat(server): the server's website is the Kioku app itself 2026-10-16 19:52:43 +02:00
mise.toml build: skeleton with makefile, embed pipeline, budget and slopcheck 2026-10-13 14:39:46 +02:00
package feat(update): look for new releases and install them 2026-10-13 23:09:11 +02:00
README.md fix(security): pictures alone at the image address, and the third review 2026-10-28 12:18:59 +01:00
release docs: release notes for 1.0.0 and a release workflow 2026-10-14 00:47:30 +02:00
slopcheck feat(i18n): interface in English and Slovak, texts in JSON files 2026-10-13 21:12:51 +02:00

Kioku

Local-first tracker for anime, manga and light novels. One Go binary is both a desktop app (made first for Windows, also on macOS and Linux) and a self-hosted server: the library lives in SQLite on your computer and syncs two ways with AniList, MyAnimeList and AniDB. Kioku plays your episodes in mpv, reads your manga and light novels, watches together with friends over Syncplay, shares lists, and keeps airing schedules, streaming links and episode notifications from AniList. It speaks English and Slovak.

Install

make app builds the downloads in dist/ (see Development). Each one carries a short read-me; this is what it says.

System Download First start
Windows 10 and 11 Kioku-<version>-windows.zip Unzip, double-click Kioku.exe. Kioku is not signed, so Windows may show "Windows protected your PC": click "More info", then "Run anyway". It adds itself to the Start menu.
macOS 12 and later (Apple silicon and Intel) Kioku-<version>-macos.zip Drag Kioku to Applications and open it. Kioku is not notarized, so the first time go to System Settings > Privacy & Security and click "Open Anyway" (on macOS 14 and older, right-click the app and choose Open). If macOS calls the app damaged: xattr -dr com.apple.quarantine /Applications/Kioku.app.
Linux (x64, arm64) Kioku-<version>-linux-x64.tar.gz Extract and run ./kioku. It adds itself to the application menu.
Linux x64, Flatpak Kioku-<version>-linux-x64.flatpak flatpak install --user Kioku-<version>-linux-x64.flatpak (GNOME's runtime comes from Flathub), then open Kioku from the application menu. It opens the same library as the archive; a new release is installed the same way. Inside it the window is always WebKitGTK, Kioku's own player cannot reach mpv (episodes open in your default player), and folders outside Videos, Downloads and Kioku's own need flatpak override --user --filesystem=<folder> space.toxik.Kioku.

Kioku opens in a window of its own: on Windows through WebView2 (part of Windows 10 and 11), on Linux through WebKitGTK when it is installed, otherwise through an app window of Microsoft Edge, Google Chrome, Brave, Vivaldi or Chromium, and in the default browser as a last resort. With NVIDIA's driver, Linux uses such an app window even when WebKitGTK is installed: WebKitGTK crashes on that driver's GPU paths and is slow without them (KIOKU_WINDOW=native keeps WebKitGTK, drawn on the CPU; KIOKU_SOFTWARE_RENDERING=0 keeps it on the GPU). Episodes play in Kioku's own window through the window's video support; on Linux, WebKitGTK plays them with GStreamer's good, bad and libav plugins (gst-plugins-good, gst-plugins-bad, gst-libav). Connecting AniList needs no setup in these builds: Sync > AniList > Connect, approve, done.

Run

./kioku                      # desktop app: opens a window, quits when it closes
./kioku --background         # desktop app without a window (start at login uses this)
./kioku serve                # server: http://127.0.0.1:7777, no window, logs to stderr
./kioku serve -addr 0.0.0.0:7777   # reachable from the network; set a password first
./kioku serve -data-dir /srv/kioku -config /etc/kioku.toml
./kioku -profile Mika         # open a profile other than the last one used
./kioku -version

Without a graphical session (a server, an SSH login) ./kioku behaves like ./kioku serve. Only one Kioku runs per data directory: starting another one shows the running Kioku's window instead, unless the one started is a newer version, which takes over from the running one.

In the desktop app, Settings > App can keep Kioku running after the window closes (so notifications keep arriving), start it at login, show the data folder and quit it. Links to other sites open in the default browser. The app logs to kioku.log in the data directory, crash reports included, and shows startup errors in a dialog. If another program uses port 7777, the app moves to a free port and says so; AniList logins need 7777, so close that program and start Kioku again.

Data lives in the platform's app data directory unless -data-dir or KIOKU_DATA_DIR says otherwise:

OS Default data directory
Linux $XDG_DATA_HOME/kioku or ~/.local/share/kioku
macOS ~/Library/Application Support/Kioku
Windows %LOCALAPPDATA%\Kioku

It holds kioku.db (SQLite), backups/ (a snapshot and a JSON export before every sync or import that changes the library, the last 10 kept), images/ (cover thumbnail cache), cache/ (unpacked RAR archives for the reader), tools/ (yt-dlp and Deno when Kioku installs them), window/ (the app window's browser profile), kioku.log and config.toml if you create one there.

Password

Kioku listens on loopback by default and needs no login there. Before exposing it, set a password:

printf '%s' 'a long passphrase' | ./kioku hash-password

and put the printed hash in the config as auth.password_hash (or KIOKU_AUTH_PASSWORD_HASH). Add every host name you open Kioku under to allowed_hosts, and set base_url to the address the browser uses; provider redirects and notification links are built from it. Behind a reverse proxy on another computer or another port, base_url must be the proxy's own address (or the proxy must pass the browser's Host on, proxy_set_header Host $http_host in nginx): Kioku takes changes only from pages at the address they were opened by, so another app on the same machine cannot make them.

Secrets

Provider tokens, the AniDB password, notification credentials and the Web Push key are kept out of the database:

  • secrets.backend = "auto" (default): the OS keychain (Secret Service on Linux, Keychain on macOS, Credential Manager on Windows), or, when there is none, an AES-256-GCM encrypted file secrets.enc whose key comes from KIOKU_SECRET_KEY (32 bytes, base64; for example openssl rand -base64 32). The desktop app, where nobody sets environment variables, generates that key into secrets.key (readable only by you) instead; a keychain protects better, so servers keep requiring the variable.
  • "keyring" or "file" force one of them.

The AniDB password is stored only in the OS keychain; on a machine without one, AniDB cannot be connected.

Home

On a computer's first start, a short tour points at the library, search and commands, Sync and Settings; Take the tour in the command palette (Ctrl+K) shows it again.

Kioku opens on Home: the titles you are watching and reading with their next episode or chapter (Play or Read when the file is on this computer, Watch on your first streaming service otherwise, + to count one more), Next in the series (sequels of titles you finished that are not in your library, out ones first, then announced ones by date), Recommended for you (what people on AniList recommend next to the titles you rated 70 or more, the higher rated counting more, with the title each comes from), what airs this week from your list, first episodes further out, a random pick from Planning when you cannot decide, and finished titles still waiting for a score. The x on a suggestion keeps it away. The whole library is under Library, Anime, Manga and Light novels.

Library

Library, Anime, Manga and Light novels show your entries as covers, a list or a table, with status tabs, filters (among them the titles' AniList tags, filled in for the whole library in the background), saved presets and sorting; the keyboard works too (? lists the keys). Select picks several titles (click, Shift for a range, x for the focused one, Ctrl+A for all shown) to set their status or score, add or take off a tag, put them on a list or remove them, all at once; removing asks first and can be undone.

Light novels count by volume: +1, the lists and Home show the volumes read, and reaching the last volume finishes the title; chapters stay in each title's editor next to the volumes. Titles counted only by chapter so far stay so, and Settings can count every light novel by chapter.

The command palette (Ctrl+K) goes to any page or title and runs Kioku's commands: on a title's page it counts one more, marks it completed or removes it; elsewhere it syncs one service or all of them, backs up, checks the database, switches theme, density, contrast or profile, pairs a phone and looks for updates. Commands that match the words best come before titles.

History of changes (command palette, Ctrl+K) lists the last changes to the library, newest first: edits, titles added and removed, and changes made to many titles at once as one line. Undo puts one back as a whole (a removed title returns with its values, an added one goes, changed fields return unless they changed again since, and the other fields stay as they are); Ctrl+Z outside a text field undoes the newest change and keeps stepping back.

Finding titles

Search (sidebar) looks through AniList's anime, manga and light novels: type a name, or browse what is trending with filters for format, status, season, year, genres and tags, sorted by trend, popularity, score, date or title. Tags are AniList's 400-odd tags (Isekai, Time Manipulation, Female Protagonist and so on): click one once to require it, twice to leave out every title that has it; a title must have all the required ones. Source switches the search to another service Kioku is set up for: MyAnimeList, AniDB (anime, through its title list), Kitsu, or MangaBaka, which knows many manhwa, manhua and light novels AniList lacks. Those are searched by title only. The + on a cover adds the title to your library with the status chosen under "Add as"; covers of titles you already have show their status. A title that is on no provider can be added by hand from the bottom of the page.

A title's page has your entry, its tags (each finds more titles with it; spoiler tags stay hidden until asked for), where to watch (with the region a link is meant for when its address or AniList's note says so, such as Japan, United States or Southeast Asia, and a mark on links for other regions than the one set in Settings), the airing schedule and, from AniList, characters with their voice actors, staff, studios and recommendations (+ puts one in Planning); related titles open with a click and the trailer plays in mpv (in the browser without yt-dlp). Arrange sections picks which parts show and in what order.

Characters, staff and studios

Characters, Staff and Studios (sidebar) are the other half of the library: the characters, people (voice actors, directors, authors) and studios you keep, with their pictures. The heart on their pages, in Search (Characters, Staff and Studios next to the title kinds) or on cards adds them; with AniList connected, Import from AniList brings in your favourites from there, and only adds (Kioku never changes AniList's favourites). Their pages come from AniList: a character's details, description (spoilers hidden until clicked) and the works they appear in with their voice actors, a person's voice roles and other credits, a studio's works, newest first. Characters, staff and studios on a title's page lead to these pages. Favourites travel in the library file and in backups.

Seasons, schedule, notifications and stats

Seasons shows each anime season's titles (also the ones still airing from earlier seasons and the announced ones) with countdowns, the services they stream on and one-click adding; Schedule is the week's airing timetable in your time zone, with your list highlighted. Kioku tells you when a new episode of what you watch is out: in the app, as a desktop notification, through Web Push in a browser, or through ntfy, Gotify, a Discord webhook or any webhook, with a delay after broadcast, quiet hours, a daily digest and per-title mute (Settings > Notifications). It also tells you when a sequel of a title you finished or are watching is announced or comes out (titles are read again from AniList weekly), unless it is in your library already or you waved it away on Home. Stats sums up time watched, chapters read, scores, genres and your activity, and Your year reviews any year by the finish dates: titles finished per kind and month, time watched, mean score, top genres, tags and studios, the highest rated and the longest.

Achievements on Stats are milestones in the library: ten titles, a hundred finished, a thousand episodes or chapters, fifty anime and others, each with how far you are and the day it was reached. They come from the Kioku server when it can be reached (its admins, and people with the achievements role, add and change them at /achievements in its web version) and otherwise from the ones Kioku starts with; profiles on the server show the ones reached.

Calendar

Schedule > Calendar gives an address that calendar apps on this computer (Thunderbird, Outlook, Apple Calendar) can subscribe to: the next four weeks of episodes from your list, refreshed every few hours. Calendars on the web cannot reach your computer, so Save the file and import it there instead. The address carries its own key, so it works with a password set; New address replaces it.

Friends

Friends (sidebar) opens with what the people you follow on AniList and on your Kioku server were busy with most in the last two weeks and a leaderboard of the episodes and chapters you and they marked in the last 7 or 30 days, then shows the people you follow on AniList and what they watched and read lately, with + to put a title in Planning; a title's page lists what they have of it, with their scores and their average once two of them scored it, together with the people you follow or are friends with on your Kioku server when a Kioku account is connected (friends first; only those whose library you may see, never private entries). It reads AniList's public data for the AniList account connected under Sync, so following people happens on AniList. Each person opens a comparison with their AniList lists (when public): a taste match from the scores you both gave (at least five), the titles you share, their favourites you have not seen, the ones you both love, where you disagree, and your favourites they have not seen.

Lists and sharing

Lists (sidebar) are your own lists of any titles, in your order and with a note for each: favourites, recommendations, a season plan. "Save to a list" on a title's page puts it on one. Share (on a list or a title) gives a link that opens in a friend's Kioku, the same as text with AniList pages for friends without Kioku, and for long lists a file. Your friend sees what you shared first and then keeps it as a list, adds the titles to their library, or picks single ones; list files are imported under Lists.

A list can also live in a folder that syncs between your and your friends' computers (Syncthing, Dropbox, OneDrive, Nextcloud): Keep in a shared folder on the list writes it there as a .kioku-list.json file, friends choose Join a shared list under Lists, and every Kioku merges its changes with the file's about every 30 seconds. Each title carries who changed it and when, removed titles stay marked for 90 days, and copies the sync program makes on conflicts are merged too and never deleted. Titles travel by their AniList and MyAnimeList IDs; titles of your own stay on your computer.

Sync > Export a profile page writes the library as one HTML file to put on any web host: anime, manga and light novels by status with covers, progress, scores and links to AniList, a few numbers at the top, light and dark. Private entries, notes and tags stay out, planned titles only when asked, adult titles only when you show them in Kioku.

Sharing a title or a list can also make a picture of it (Make an image in the share dialog), and Stats > Your year has Share as an image: cards in the app's colours with the covers, your score, where you are and your note, or the year's numbers, months and best-rated titles, to save as PNG or copy.

Watching

Episodes on this computer

Add the folders that hold your episodes under Settings > Player. Kioku reads the file names (release groups, seasons, episode numbers, extras, specials), links them to titles in the library and lists them on each title's page; files it cannot place wait there for you to assign, with an offset for absolute episode numbers.

Episodes play in mpv (install it; Kioku looks in the usual places, or set its location). Kioku queues the following episodes, resumes where an episode stopped, marks an episode watched once most of it played (85% by default), and skips openings and endings from chapter names and AniSkip, on its own or when you press Tab. The bar under the page shows what plays and controls it. Its scissors mark an opening, ending or recap AniSkip does not know yet: skipped from then on for that episode, and shared with AniSkip under a random ID of this installation when you leave "Share with AniSkip" on (it needs the title's MyAnimeList link). Its note button keeps a moment of the episode with a line about it; the episode list shows the moments and plays the file from each.

Prefer another player? Settings > Player and files > Play files in > Default player opens episodes in whatever program your system opens videos with, and Kioku follows it as described under Other players (streams and watch together keep using mpv).

Free official streams (YouTube, Bilibili) from a title's where-to-watch links play in mpv too, through yt-dlp and, for YouTube, Deno. Settings > Player installs both from their official releases, checks them against the published checksums and keeps them up to date; copies you installed yourself are used as they are.

The queue and playlists

Kioku's own window plays a queue, as a music player does: Play next and Add to queue (a title's menu, the library's right click, Q, an episode, a notice, an opening) put things in it, and when what plays ends the queue comes first, before the title's own next episode. Up next, a list, a shelf of the Watch page (the files on this computer too), Continue watching and whatever the library shows (its More menu) play from the start with Play, one episode of each title. Play their openings, for titles selected in the library (a tag becomes a playlist), a list or a whole franchise, plays their openings one after another from AnimeThemes. The Watch page lists the queue to drag into order, shuffle, repeat, play from any item, clear or keep: its titles as a list, its openings as a playlist of openings on a Kioku account. A playlist's own page adds songs: find a title in the library and put its openings and endings on it. A paired phone shows the queue and starts it on the computer.

Other players

The desktop app follows the players you watch in yourself: VLC, MPC-HC, MPC-BE, PotPlayer, SMPlayer, KMPlayer, GOM Player, mpv, mpv.net and the Media Player app on Windows (from their window titles), and on Linux every player that speaks MPRIS (VLC, Celluloid, Haruna, SMPlayer, mpv with its MPRIS script) plus the window titles on Hyprland, Sway and i3. Kioku reads the file's name the way it reads your folders, finds the title in your library (a scanned file of that name first, with what you assigned to it) and shows it in a bar under the page. The next episode counts as watched once most of it played: the percentage set for mpv where the player tells where playback is (MPRIS), and two thirds of the episode's length the file stayed open otherwise. A toast offers to undo it. An episode further ahead than the next one waits for Mark watched, so a skipped episode never moves your list on its own; episodes you already watched leave it alone. A file Kioku cannot place offers Choose title, and Kioku remembers the choice for every file with that title in its name, in your folders too. Turn it off under Settings > Player; window titles never leave the computer.

Episodes with a file on this computer but no still from Kitsu or the streaming links show a frame of the file instead, taken with ffmpeg when it is installed and otherwise with mpv (without a window) and kept in the data folder; the spoiler shield hides them like the others.

Organising files

Organise, above a title's files, gives its episode files one kind of name inside the folder Kioku watches: renamed where they are ("Title - 05.mkv"), in one folder per title ("Title/Title - 05.mkv") or with season folders as Jellyfin and Plex like them ("Title/Season 01/Title - S01E05.mkv"), in the title language you chose. The renames are shown before anything moves; subtitles named after a file move with it, files matched by hand stay matched, folders left empty are removed, no file is overwritten, and the toast's Undo moves everything back. Specials, extras and files without an episode number stay as they are.

Disk space

Settings > Player and files shows how much space the files in your folders take, per title, and how much of it is episodes you already watched. Free up, above a title's files, moves its watched episode files (and the subtitles named after them) to the system's trash: the Recycle Bin on Windows, the Finder's Trash on macOS, and the freedesktop.org trash on Linux. Nothing is deleted; the trash gives them back until you empty it. Specials and extras stay.

Subtitles

The subtitles button beside each episode file finds subtitles on Jimaku (Japanese subtitles, found by the title's AniList ID) and OpenSubtitles (by title, season and episode, and by the file's own hash, whose matches come first and are marked as made for the file), in the languages set for mpv. The one you save goes beside the episode as <episode name>.<language>.<ext>, which mpv loads with it; a file of that name is replaced only when you say so. ZIP archives from Jimaku give up the episode's file. Both sites need keys of your own, kept in the system keychain: a Jimaku API key, and for OpenSubtitles an API consumer key (or a build or configuration that carries one) plus the account's user name and password, since downloads count against an account. Settings > Player and files has the fields.

Streaming sites in the browser

The Kioku extension for Chromium-based browsers (Chrome, Edge, Brave, Vivaldi, Opera) and Firefox recognises the episode you watch on Crunchyroll, Netflix, HIDIVE, YouTube, Bilibili, Disney+, Prime Video, Hulu, Max and ADN and marks it watched in Kioku. It reads the series and episode from the page (its structured data, the player's media session or its title) and finds the title in your library: by the page's address when Kioku has it among the title's streaming links, otherwise by name, seasons included. When the video passes the share set in the extension (85% unless changed), the next episode of a title found for sure is marked on its own and a short note appears in the page; anything else, such as a title it is not sure about or an episode further ahead, waits in the toolbar button, where Not this title picks another one and the choice is kept for that site.

Every release carries Kioku-<version>-extension-chromium.zip and Kioku-<version>-extension-firefox.zip. In a Chromium-based browser, unzip it, open the extensions page, turn on Developer mode and choose Load unpacked. In Firefox, load it from about:debugging (until the browser restarts), or for good in Firefox Developer Edition or Nightly with xpinstall.signatures.required off. The extension folder of this repository loads unpacked as it is.

To connect it, open Settings > Browser extension in Kioku, choose Connect a browser and paste the address and token into the extension's settings; each browser has its own token and can be disconnected there. The token opens only the extension's calls (/api/ext/), which work beside a password and from the extension's own origin. A Kioku account works too: on the Kioku server make an API token with the Library and Read scopes and choose "A Kioku account" in the extension.

Discord

Settings > Player can show what plays in mpv, or in another player Kioku follows, as your Discord status: the title, the episode, the time left and the cover, with a link to the title on AniList, while the Discord app runs on the same computer. Discord shows the status under an application's name: builds made with make app DISCORD_APP_ID=... carry one (create an application named Kioku on the Discord Developer Portal); otherwise paste your own application's ID in Settings, or set discord.app_id.

Reading

A manga or light novel's page shows where to read it officially: MANGA Plus, VIZ, K MANGA, Comikey, WEBTOON, J-Novel Club, BookWalker and the other platforms AniList lists for it, your services first, with the region a link is meant for when Kioku can tell. The links are read from AniList when the page is opened, at most once a week, and changes reach you as streaming changes do.

Manga, comics and light novels in the same folders open in Kioku's reader: CBZ, ZIP, CBR and RAR archives, folders of images, PDFs and EPUBs. Comics read right to left, left to right, two pages at a time (double pages, as their size tells, show on their own) or as a long strip (remembered per title), with plain margins cut off if you like, zoom (double-click the middle, Ctrl and the wheel, + and -) and dragging the zoomed page around; EPUBs follow the app's colours with a text size of your choice. Colours sets a tone for both (sepia, night or grey) and a lower brightness. Bookmarks keep places with a note each, and in EPUBs selected text can be highlighted; the bookmark list jumps back to any of them. In the long strip, Space, Page Down and the arrows scroll smoothly, and A (or the button in the bar) scrolls on its own at one of seven speeds ([ and ] change it); wheeling or touching holds it for a moment. Both readers learn how fast you read (seconds a page for comics, characters a minute for books, kept in the browser) and, after a couple of minutes of reading, show the time left in the chapter and the book. For learners, Settings > Player and files downloads the JMdict Japanese-English dictionary (about 10 MB, by the Electronic Dictionary Research and Development Group, CC BY-SA 4.0); with Look up words on in the EPUB reader, pointing at a Japanese word shows its reading and meanings, conjugations undone (食べました is 食べる, polite past). Kioku remembers the page where you stopped, counts a chapter or volume as read when you reach its end and offers the next one.

A Calibre library added as a folder is read through its metadata.db: books are named by their series and number in it rather than by their file names, and numbers that are not whole (2.5, a side story) count as specials. Sync > Import light novels from Calibre takes the same metadata.db and imports the series that look like light novels (tagged so, from a light novel publisher, or in Japanese; every book when none do): each as Planning, or Reading up to the highest volume read when the library has a yes or no Read column, scored by the volumes' average rating. Like every import it is a preview first and only fills gaps.

Books on your own Komga or Kavita server join them: in Settings > Player and files, Add a server takes the address and an API key (Komga: Account settings > API keys, or your email and password; Kavita: Settings > 3rd Party Clients). Kioku lists the server's series with your titles, and its reader shows comics page by page from the server and downloads PDFs and EPUBs to read them; where you stop goes back to the server, and books read to the end are marked read there. The key is kept in the system keychain. Nothing on the server is changed besides reading progress.

Watch together

Watch together (sidebar) puts you and your friends in a room on a Syncplay server: the public ones at syncplay.pl or one of your own. Pausing, seeking and moving on to the next episode happen for everyone, and the room has a chat. Copy invite gives a link that opens the room in a friend's Kioku, and the server and room name for friends who use Syncplay itself. Each person plays their own copy of the episode; between Kioku users the room knows which episode everyone is on, so whoever starts the next episode first waits at its start until the others have it, and "play along" starts it on your side when it is on your computer. Anyone who knows the room name can join, so keep the generated one.

In a room, Up next by vote collects what people suggest to watch next (a title from your library and an episode); everyone votes, the most wanted comes first, and Play starts it from your computer and takes it off the queue. Kioku clients keep the queue from short [queue] chat lines, so it works on any Syncplay server, and someone joining later is told what is queued; Syncplay users see those lines as chat.

Comparing tastes with someone you follow also lists the anime you both plan to watch, each with Watch together. Friends > Watch together starts a room now: choose what to watch (or decide in the room), send the invite as a message to friends on your Kioku server, copy it for anyone else, and open the room.

Plan a session sets a title, an episode and a time: Kioku makes a room for it, reminds you a quarter of an hour before (on every notification channel turned on), puts it in the calendar feed, and offers Join from half an hour before. Copy invite gives a line with the time and a link; a friend's Kioku shows the plan and keeps it in their plans with one click, so they are reminded too.

Profiles

People who share a computer (and its user account) can each keep their own Kioku: Settings > Profiles adds a profile with a library, lists, settings, connected accounts and window of its own. Kioku has one profile open at a time and opens the one used last; the profile button at the foot of the sidebar (or Switch in Settings) starts Kioku again in another. The first profile is the data folder itself, the others are folders in its profiles folder, and all of them share the config file; their logins are kept apart in the keychain. Removing a profile only takes it off the list: its folder, with the library, stays where Settings says. kioku -profile NAME (or KIOKU_PROFILE) opens a profile by name, which is also how a server runs one.

Phone

Settings > Phone opens Kioku to phones and tablets on the same network as the computer, in the phone's browser with nothing to install: the library, title pages, progress, scores and lists. Turn on phone access, choose Pair a phone and scan the code with the phone's camera (or open its link there); the code works once, for ten minutes, and the phone keeps a token of its own, so it stays paired until you unpair it in the list below the code or it stays away for over a year. Phone access listens on port 7778 (or a free one when that is taken, kept for next time) and answers only paired phones; pairing more phones and turning it off stay on the computer, and so does starting playback in mpv there. It speaks plain HTTP on your network, so use it on one you trust, such as your home Wi-Fi; if the phone cannot open the page, allow Kioku through the computer's firewall (on Windows, on private networks when asked). With Tailscale, its address is offered too. [phone] host and port in the config pin the address and port.

Backups and moving to another computer

Kioku backs up the library before every sync or import that changes it, and once a day when it changed, and keeps the last ten in the data folder's backups. Settings > Data lists them with Back up now; Restore puts one back after backing up the library as it is, and restarts Kioku (a server finishes at its next start). Keep copies in names a second folder, such as one OneDrive, Google Drive or Dropbox keeps safe: every backup is copied there too (the newest ten stay), so a lost disk does not take the library with it. With that folder shared between your computers (by the same sync service), Kioku also shares where episodes stopped: each computer writes its own small kioku-positions-<id>.json there every two minutes and picks up the others' newer stops, so an episode resumes where you left it on any computer that has the file. The stops are named by the title's AniList or MyAnimeList ID and the episode number; finished episodes and stops older than 90 days stay out. Turn it off under Keep copies in.

Diagnostics (linked from Settings > About) checks the database on request: damage to the file, records left pointing at removed ones, sync records of services that are no longer connected (stale bases, queued pushes, open conflicts and deletions) and values that no longer parse. Repair backs the library up first and then removes the leftovers, closes the stale questions and resets unreadable values; a damaged file is only reported, since restoring a backup is the way back from that.

Settings > Data > Settings file exports your preferences and saved filters (sidebar smart lists included) to one file and imports such a file on another computer or into another profile: its preferences take the place of yours and its saved filters join yours, while the importing computer keeps its own mpv program, backup folder and notification channels. Accounts and logins never go into the file.

To move to another computer, either copy the newest kioku-....db from the old computer's backups folder and choose Restore from a file on the new one (everything comes along; accounts need logging in again, since their logins stay in the old computer's keychain), or Export the library file on the old one and Import it on the new one, which adds the titles that are not there yet with their status, progress, score, dates, notes and tags.

Updates

Kioku looks for new releases twice a day and says so in the sidebar. Settings > About lists what every release since yours brought, newest first, not only the latest. On Windows and Linux it installs the update (checked against the release's checksums) and restarts into it; on macOS it links to the download.

Appearance and languages

Settings > Appearance sets the theme (light, dark or the system's), the interface colour and the language. The colour is Kioku's blue, one of the presets, any colour you pick or one taken from a picture of your choice; Kioku works out light and dark versions of it that keep text readable, and the backgrounds can take its hue too.

Contrast (Settings > Appearance) follows the system's wish for more contrast, or is set to standard or high on this device: high contrast makes text and lines near black on white (or white on black), keeps muted text readable and thickens the focus ring, over any custom interface colour.

Compact density (Settings > Appearance) fits more rows on screen in the library's lists and tables and in the sidebar.

Title pages open under the title's banner picture or, when it has none, a band in the colour of its cover; Settings > Appearance can keep to the colour band or turn the top off. Covers whose service sends no colour (Kitsu, MyAnimeList, MangaBaka and others) get one taken from the cover itself in the background, for the band, the page's accent and the placeholders in lists; black and white covers keep none.

Kioku speaks English, Slovak and Czech. Interface texts are in web/src/lib/i18n/<language>.json, the texts Kioku writes elsewhere (notifications, messages in mpv) in internal/i18n/locales/<language>.json; a language that comes with the app needs both files and an entry in web/src/lib/i18n/index.ts. Other languages are translated on the Kioku server by people with the translator grant, at /translate in its web version, text by text against the English, and published when ready; the app's language list then offers them under "Translated on the Kioku server", downloads the texts and keeps them for when the server cannot be reached, with English for anything not translated yet.

Kioku server

kioku-server is the start of Kioku's own accounts at kioku.toxik.space: sign-up by invite code (or open registration, switched by an admin), logins for the app and the web with a list of signed-in devices, email address checks and password resets, invite codes members can hand to friends, roles, rate limits and an audit log, on PostgreSQL. It runs as podman containers under systemd; deploy/README.md walks through installing it, the proxy, the first admin account, backups and updates. In the app, Sync > Kioku logs in to an account there (or creates one with an email and an invite code; another server's address can be given) and syncs the library both ways like any other service: every title goes along, those no service knows too, so a second computer that logs in gets the whole library, and AniList and the rest keep syncing beside it. The server also serves the web version at its address: log in from any browser or phone to see and change the library (status, progress with +1, score, dates, notes, tags), make invite codes for friends, manage your devices and password, and, for admins, decide who can sign up. Friends and discussions follow.

Providers

Builds made with make carry an AniList client (ANILIST_CLIENT_ID, see Development), so AniList works without setup on the default address. MyAnimeList and AniDB need a client registration you create yourself: Sync > Set up walks through it and stores it (secrets in the keychain), or put the values in the config file or KIOKU_<SECTION>_<KEY> environment variables. Values entered in the app win over the config file. Kitsu and MangaBaka need no registration. Connect accounts in Sync. Connecting starts the first sync, which is always a preview that changes nothing until you apply it.

When an entry meets a service for the first time, a filled-in value beats an empty one on either side: connecting a second service fills in its notes, dates and scores and never wipes yours. After that, changes go the way they were made, and two different changes to the same field are settled by time (or the provider order) or left for you to choose.

A change waits for its service however long that takes when the service is down for everyone (AniList turned its API off for days in October 2026) or this computer cannot reach it; Services says why it waits and when it tries next, and Send now tries at once. Only a change the service refuses as wrong, or a title it does not have, is given up, and those wait under Services with Retry.

AniList

To use your own client instead of the built-in one (for example on another address):

  1. Create a client at https://anilist.co/settings/developer.
  2. Redirect URL: <base_url>/api/oauth/anilist/callback if you also set the client secret (authorization code flow), otherwise <base_url>/oauth/anilist (implicit flow). With the default address that is http://127.0.0.1:7777/api/oauth/anilist/callback.
  3. Set anilist.client_id (and anilist.client_secret for the code flow).

A client for the built-in slot needs http://127.0.0.1:7777/oauth/anilist as its redirect URL and no secret.

AniList tokens last a year and cannot be refreshed; Sync warns two weeks before expiry. A token can also be pasted directly in the connect dialog.

MyAnimeList

  1. Create a client at https://myanimelist.net/apiconfig (app type "web").
  2. App redirect URL: <base_url>/api/oauth/mal/callback.
  3. Set mal.client_id (and mal.client_secret if the client has one).

Logins use PKCE (plain) and refresh themselves. Lists can also be imported from and exported to MAL's XML format in Sync, without an API client.

AniDB

  1. Register a client for the HTTP and UDP APIs on anidb.net (see https://wiki.anidb.net/API).
  2. Set anidb.client and anidb.client_version.

AniDB has no secure login for applications: the account password travels unencrypted, over UDP to update the list and, if list reading is turned on, inside a plain HTTP address. Kioku warns before both. Limits are strict and enforced: one HTTP request per 2 seconds and 200 a day, one UDP packet per 4 seconds, metadata cached for a week and never requested twice in a day, one list read and one titles download a day. A ban takes AniDB offline for 24 hours with a notice in Sync. Title search uses the daily anime-titles dump; if AniDB refuses the download, download anime-titles.xml.gz in a browser and upload it in Sync.

Kitsu

Connect with your Kitsu email or profile name and your password. The password goes to Kitsu once, in exchange for a login token, and is not kept; the token renews itself. Anime, manga and light novels sync both ways: status (rewatching included), progress, score, dates, rewatch count, notes and privacy. Kitsu scores are 1 to 10 in half steps and its dates whole days. Kitsu sits behind Cloudflare, which now and then asks visitors to prove they are human; Kioku cannot answer that, so it waits and tries again later. kitsu.client_id and kitsu.client_secret are only for an app registered with Kitsu; without them Kioku logs in the way Kitsu's documentation allows for apps.

MangaBaka

MangaBaka is an open database of manga, manhwa, manhua and light novels. Search and title details need no account. To sync your library, create an API key in your MangaBaka account settings and paste it in the connect dialog; it is stored like every other secret. Status, chapters, volumes, a 0 to 100 score, dates, rereads, notes and privacy sync both ways. Library entries that come without their series are looked up once, at most 60 a minute, so the first sync of a large library can take a few minutes.

Shikimori

Shikimori keeps anime, manga and light novel lists, and names every title by its MyAnimeList ID, so titles map without a search. Shikimori lets apps in only through an application you register yourself: create one at shikimori.one/oauth/applications with the redirect address Sync shows, then enter its name, Client ID and Client secret in Sync (Shikimori wants the application's name with every request). Status, episodes or chapters, volumes, score (whole points of 10), rewatches and notes sync both ways; Shikimori keeps no dates, tags or private flag, so those stay in Kioku. Kioku stays under Shikimori's limit of 5 requests a second and 90 a minute.

Simkl

Simkl tracks anime alongside TV and films; Kioku syncs the anime list. Register an application at simkl.com/settings/developer with the redirect address Sync shows and enter its Client ID and Client secret in Sync. Status, episodes watched and ratings (whole points of 10) sync both ways: episodes go to Simkl as the ones watched since the last sync, and come off again when progress goes down. Simkl has no rewatching status, notes, dates or tags on its lists, so those stay in Kioku; titles marked not interesting there are left out.

Bangumi

Bangumi keeps anime, manga and light novel collections. Create a personal access token at next.bgm.tv/demo/access-token (for the longest time it allows) and paste it in the connect dialog; Kioku asks for a new one when it runs out. Status, episodes (marked on Bangumi episode by episode), chapters and volumes, score (whole points of 10), comment, tags and the private flag sync both ways; Bangumi names titles by its own IDs, so they are matched by their names, and books are light novels when Bangumi or their tags say so. Bangumi's API cannot take a title off a collection, so removing one stays in Kioku.

Trakt

Trakt keeps a history of shows and films. Kioku sends your anime there: plans go on the watchlist, episodes watched go to the history, and scores become ratings (whole points of 10). Trakt has whole shows with seasons and no anime IDs, so each season of a show stands for one title, found by searching (search results list a show's seasons, named the way anime services name sequels, which Find links on Trakt in Sync matches like other services), and films stand for themselves. Register an application at trakt.tv/oauth/applications with the redirect address Sync shows and enter its Client ID and Client secret in Sync. Kioku only writes: Trakt's history never comes back, and nothing is removed from it.

Shared folder

Sync > Shared folder keeps one library on two or more computers without an account anywhere, through a folder that Syncthing, Dropbox, OneDrive, Nextcloud or a network drive keeps the same on each of them. Give every computer the same folder (its full path there) and a name. Each computer writes only its own <id>.kioku-library.json in the folder, with every title, its status, progress, score, dates, notes and tags, and when each of those last changed; syncing reads all the files and, field by field, the latest change wins, so a score set on one computer and a note written on the other both stay. Titles go by their AniList, MyAnimeList, Kitsu, AniDB or MangaBaka ID, so the same work meets itself on every computer, and titles no service knows come along too. Taking a title off on one computer asks first, as with any service, and the others then ask before taking it off themselves. It syncs every five minutes by default; a file the sync program is still bringing in stops the sync until it is whole, instead of making titles look removed.

Cross-references

Works are linked across providers with the anime-offline-database (ODbL 1.0), downloaded weekly, with the IDs Kitsu and MangaBaka records give for AniList, MyAnimeList and Kitsu, and by title matching; uncertain matches wait in Sync for review.

Configuration

All keys are optional. Every key has an environment variable: KIOKU_<KEY> at the top level, KIOKU_<SECTION>_<KEY> in sections (KIOKU_ANILIST_CLIENT_ID). Lists are comma-separated.

addr = "127.0.0.1:7777"
base_url = ""                 # default http://<addr>
data_dir = ""
log_level = "info"            # debug, info, warn, error
allowed_hosts = []            # extra Host names to accept

[auth]
password_hash = ""            # from `kioku hash-password`

[secrets]
backend = "auto"              # auto, keyring, file

[anilist]
client_id = ""
client_secret = ""
requests_per_minute = 25

[mal]
client_id = ""
client_secret = ""
requests_per_second = 1

[anidb]
client = ""
client_version = 0
daily_request_cap = 200
udp_local_port = 0            # fixed port helps behind NAT

[kitsu]
api_base = "https://kitsu.io/api/edge"
token_url = "https://kitsu.io/api/oauth/token"
client_id = ""                # only for an app registered with Kitsu
client_secret = ""

[mangabaka]
api_base = "https://api.mangabaka.org"

[trakt]
client_id = ""
client_secret = ""
api_base = "https://api.trakt.tv"

[bangumi]
api_base = "https://api.bgm.tv"

[simkl]
client_id = ""
client_secret = ""
api_base = "https://api.simkl.com"

[shikimori]
client_id = ""
client_secret = ""
app_name = "Kioku"
base = "https://shikimori.one"

[mapping]
offline_db_url = "https://github.com/manami-project/anime-offline-database/releases/download/latest/anime-offline-database.jsonl.zst"

[notify]
vapid_subject = "mailto:kioku@example.com"   # contact shown to push services

[update]
url = "https://git.toxik.space/api/v1/repos/Toxuki/kioku/releases/latest"   # empty turns update checks off

[discord]
app_id = ""                   # Discord application for the Discord status

[dict]
jmdict_url = "http://ftp.edrdg.org/pub/Nihongo/JMdict_e.gz"

[phone]
host = ""                     # one address for phone access; empty listens on all of them
port = 0                      # 0 uses 7778, or a free port when that one is taken

[subtitles]
jimaku_api_base = "https://jimaku.cc"
opensubtitles_api_base = "https://api.opensubtitles.com"
opensubtitles_api_key = ""    # an OpenSubtitles API consumer key; the user's own in Settings wins

Notification channels (Web Push, desktop, ntfy, Gotify, Discord, webhook), streaming services and the time zone are set in the app under Settings.

Development

Requirements: Go 1.27, Node 24 with pnpm, golangci-lint and sqlc. With mise installed, mise install provides the pinned versions.

make deps         # Go modules and web packages
make build        # web UI (only when web/ changed) + bin/kioku
make dev          # Go live reload (air) + Vite dev server on :5173
make check        # lint, tests, build, build-time budget, slopcheck
make gen          # regenerate sqlc queries, OpenAPI spec and TS client
make bench        # performance targets on a seeded 10k-entry database
make screens      # Playwright screenshots into .agent/screens
scripts/a11y.sh   # axe-core on every screen of the app (CONTRAST=more for high contrast)
scripts/a11y-server.sh  # the same for the server's web version, on a throwaway PostgreSQL in podman
make release      # stripped binaries for linux/amd64, linux/arm64, windows/amd64, darwin/arm64
make app          # the downloads in dist/: Windows zip, macOS app zip, Linux archives
make icons        # redraw the web app icons from tools/package/icon.go
make hooks        # commit-msg hook with the same copy rules

make app builds Kioku.exe as a Windows GUI program with its icon, version information and manifest (made with go-winres, fetched by go run on first use), a universal macOS app bundle for Apple silicon and Intel, and Linux archives for x64 and arm64. APP_VERSION sets the version (default 1.0.0), ANILIST_CLIENT_ID the built-in AniList client (default 53714; empty for none) and DISCORD_APP_ID the built-in Discord application (default none). It also writes SHA256SUMS, which Kioku checks before installing an update. The icon is drawn by code in tools/package/icon.go, so every size is rendered rather than scaled. The builds are not code signed, which is why Windows and macOS ask once before the first start.

make dev runs kioku serve; the desktop window is not involved during development.

scripts/a11y.sh runs axe-core on every screen.

A release is a tag (v1.2.0) with the files from make app APP_VERSION=1.2.0 attached, SHA256SUMS included: Kioku finds the newest release through update.url. Write the notes in docs/releases/<version>.md, with what the release brings under ## New in <version>, commit, then run scripts/release.sh 1.2.0: it tags the current commit (and pushes the tag), builds the files (the app for each system, a Flatpak when the flatpak command and the runtime org.gnome.Platform//51 are on the computer, and Kioku-server-<version>-linux-*.tar.gz with the server and its podman units), rebuilds bin/kioku so the local build carries the release's version too, and publishes the release with the notes. The release page shows the notes' introduction, this release's "New in" section and the download table, with links to the full notes and to earlier releases, so the files are near the top; Kioku's update panel reads each release's own "New in" section. Running it again for the same version updates the notes and attaches only what is missing; --no-build publishes what dist/ already holds. It needs a Forgejo token with repository read and write access (git.toxik.space > Settings > Applications), in FORGEJO_TOKEN or in .release-token (one line, ignored by git).

The apps are signed when certificates are given, and go out unsigned otherwise. KIOKU_SIGN_WINDOWS_PFX (a code signing certificate with its key, PKCS#12) and KIOKU_SIGN_WINDOWS_PASSWORD_FILE sign Kioku.exe with osslsigncode, time stamped by KIOKU_SIGN_TIMESTAMP (DigiCert's by default). KIOKU_SIGN_MACOS_P12 (a Developer ID Application certificate) and KIOKU_SIGN_MACOS_PASSWORD_FILE sign Kioku.app with the hardened runtime using rcodesign, which runs on Linux; with KIOKU_NOTARY_KEY (an App Store Connect API key, as rcodesign encode-app-store-connect-api-key writes it) the app is also notarized and the ticket stapled. Keep these files outside the repository. Pushing a tag also runs .forgejo/workflows/release.yml, which does the same where a runner is available. Screenshots, the benchmark and the accessibility check use the system Chromium (CHROMIUM overrides /usr/bin/chromium).

Tests never reach provider APIs: requests to anything but loopback fail during go test, and providers are tested against recorded or synthesized fixtures and local fake servers.

The API is described in api/openapi.yaml; web/src/lib/api/generated.ts is generated from the same route table.