Files
MangaCircus/docs/library-format.md
T

14 KiB
Raw Blame History

The file system library

MangaCircus has no import database for content. The library folder is the source of truth. The app reads it in place (read-only access is enough), and anything that can write files can add manga: a scraper, a sync tool, or a person with a file browser.

This document is the format specification. import.md describes how the app reads it, and scraper-guide.md is a rule book for tools that write it.

Goals of the format

Goal How the format meets it
Readable without the app Plain image files in plain folders. Zero-padded numbers make alphabetical order equal reading order in every file browser and picture viewer
Fast, simple indexing Everything the app needs is in folder names, file names and a few small JSON files. Image contents are never decoded. Only the first bytes of each image are read once to learn its size
Self-describing Page roles (cover, double page, extra, rotated) are visible in the file name, not hidden in a database
Several sources One manga can list several upstream sources. One chapter can exist in several versions side by side
Room for irregular releases In-between chapters (10.5), extra chapters and extra books outside the numbering

Layout

Always three folder levels, Manga / Book / Chapter, with the pages inside the chapter folder:

<library>/
  <Manga>/                          manga folder; its name is the manga's id
    manga.json                      optional
    cover.<ext>                     optional
    <Book>/                         e.g. "v01 Spring"
      book.json                     optional
      cover.<ext>                   optional
      <Chapter>/                    e.g. "c0001 The Seed" (one folder per chapter version)
        chapter.json                recommended
        0001_cover.<ext>
        0002.<ext>
        ...

Series without volumes (most webtoons, ongoing magazine series) still need the book level. Use a single v01, or seasons (s01 Season 1).

Anything else is ignored:

  • files at the library root,
  • files other than manga.json / cover.* in a manga folder,
  • files other than book.json / cover.* in a book folder,
  • non-image files and sub-folders inside a chapter folder,
  • every file or folder whose name starts with ..

Manga folders

  • Any name that does not start with .. The folder name is the manga's id: URLs, reading progress, follows, votes and the "already seen chapters" list all refer to it. Renaming the folder turns it into a new manga for the app.
  • The displayed title comes from manga.json → title, and falls back to the folder name.
  • Manga without a single readable chapter are left out (and logged).

Book and chapter folder names

<letters>[ ]<number>[<separator><title>][ [<source>]]
Part Rule Examples
letters Only letters (any case), optionally followed by one space. Free choice and just a hint for humans, except x, which means "extra" v, c, s, vol, Ch , Chapter , x
number Digits, optionally one decimal part. It decides the order and the identity. Zero-pad it so file browsers sort it right (4 digits for chapters, 2 for books) 0001, 12, 0010.5
separator The number must be followed by the end of the name, a space, _, -, [ or (. Use a space: _ sorts after ., which breaks the order of decimal chapters in file browsers , -
title Anything. Used as the title when the JSON file has none. Leading -, : or . are trimmed The Seed
[source] Optional, at the very end. Names the version (scan group, site) when chapter.json has no source [MangaDex]

Valid: v01, v01 Spring, c0001 The Seed, c0002 Roots [MangaDex], c0002.5 Tea Time, x01 Character Sheets, Vol 3, Chapter 12 - Title, c0010.5[Official].

Ignored, with a warning in the log:

  • c0012a: a letter right after the number.
  • Ch.12: a dot is not a letter.
  • Specials: no number.
  • - c0001: the name must start with the key.

The key

The number is normalised: leading zeros and trailing decimal zeros are dropped (0010.50 → 10.5), and an x prefix is kept. The result is the key:

Folder Key
v01 Spring 1
c0002.5 Tea Time 2.5
x01 Artbook x1
  • Book keys must be unique within a manga. A second folder with the same book number is ignored and logged.
  • Chapter id = <book key>/<chapter key>, for example 1/2.5 or x1/x1. Moving a chapter to another book, or renumbering it, therefore makes it a different chapter: reading progress and votes stay behind, and followers are told about a "new" chapter.
  • Because the key is a number, c0010.1 and c0010.10 are the same key (10.1). Avoid trailing zeros in decimals.

Order

Inside a manga, books sort by (regular before extra, number). Inside a book, chapters sort the same way. The reading order of the whole manga is books in order, each with its chapters in order:

v01: c0001, c0002, c0002.5, x01, x02   <- extras of book 1 come after its regular chapters
v02: c0003, c0004
x01: x01                               <- extra books come after all regular books

Extras

Something "extra" can be skipped while reading (user setting Skip extra pages and extra chapters) and gets an "extra" badge in the chapter list:

  • A chapter whose letters are exactly x (x01 Character Sheets) is extra. It sits outside the continuous numbering and is listed after the regular chapters of its book.
  • Every chapter in an extra book (x01 Specials) is extra.
  • "extra": true in chapter.json or book.json marks something as extra without moving it. Use it for an in-order omake such as c0010.5.

Chapter versions

Several chapter folders in the same book with the same chapter key are versions of one chapter, for example two scan groups or an official release plus a fan translation:

c0002 Roots [MangaDex]/
c0002 Roots [Official]/
  • The version id is the folder name. Votes and reading progress refer to it, so don't rename version folders.
  • Users vote versions up or down. The chapter opens in the version with the highest total. Ties go to the higher "priority" in chapter.json (default 0), then to the first folder name in sort order.
  • Users can still open any other version from the chapter list or the reader's version picker.
  • Each version has its own chapter.json, page count and page tags. When versions have different titles, the chapter title comes from the first version (in folder order) that has one.
  • Versions without any image are ignored.

Pages

A chapter folder contains its pages as plain images: jpg, jpeg, png, webp, gif, avif or bmp (extension case doesn't matter).

<number>[_<tag>]...<.ext>
  • Order is the natural sort order of the file names. Zero-pad the number (0001 … 9999) so every picture viewer agrees. For more than 9999 pages, use 5 digits throughout.
  • Tags follow the number, each introduced by _, and are case-insensitive: 0012_double.jpg, 0030_extra.png, 0007_double_rot90.jpg.
Tag Meaning Effect in the reader
cover Chapter cover / title page. It is also the chapter's image: the fallback cover for the book or manga when those have none Stands alone in Book mode. Can be skipped (Skip chapter cover pages)
double One image showing two facing pages (a spread) Stands alone in Book mode. In Flow mode it has the height of a single page, so it is twice as wide, but never wider than the screen
extra Extra content: translator notes, credits, recruitment pages, ads Can be skipped (Skip extra pages…)
rot90, rot180, rot270 The image is stored turned. The viewer turns it clockwise by this angle Width and height swap for rot90 / rot270
  • A page whose (rotated) image is wider than tall counts as a double page even without the tag. Tag it anyway; it documents the intent.
  • Unknown tags are ignored, so tools may add their own (0005_color.jpg) without breaking anything.
  • A file name without a leading number (page-a.jpg) is still a page. It is just sorted by name, which you rarely want.

Covers

Level Cover Fallback
Manga (library tile, manga page) cover.<ext> in the manga folder cover of the first book
Book cover.<ext> in the book folder first cover-tagged page (else the first page) of the first chapter's first version
Chapter first page tagged cover first page

Covers are served at their original size. A cover around 600×900 px keeps the library page light.

Metadata files

UTF-8 JSON (a BOM is tolerated). All fields are optional, and unknown fields are kept and ignored. A broken file is logged and treated as empty, so the folder still works with its name-based defaults.

manga.json

Field Type Meaning
title string Display title (default: folder name)
altTitles string[] Other titles
authors string[] Authors / artists
status string Free text, e.g. ongoing, completed, hiatus
year number First release year
tags string[] Genres / tags
description string Synopsis (line breaks are kept)
direction "rtl" | "ltr" | "ttb" How the pages are read. rtl (the default): manga, right to left. ltr: comics, printed manhwa. ttb: webtoon, one vertical strip cut into slices (aliases vertical, webtoon)
sources {name, url}[] Upstream sources the manga was scraped from. Several are allowed

The whole file is sent to logged-in users as part of the manga page. Don't put secrets in it (scraper tokens, cookies).

book.json

Field Type Meaning
title string Book title (default: title part of the folder name)
direction as above Overrides the manga's direction for this book
extra boolean Marks all its chapters as extra without renaming the folder
Field Type Meaning
title string Chapter title without "Chapter N" (default: title part of the folder name)
source {name, url} or string Where this version came from (default: [source] in the folder name)
added ISO date/time string Release (or download) date, used for "recently updated" (default: the folder's modification time)
extra boolean Marks the chapter as extra without moving it
priority number Tie-breaker between versions with equal votes. Higher wins (default 0)
direction as above Overrides book/manga direction, e.g. a colour webtoon special inside a printed series

direction is inherited chapter → book → manga → rtl, and each version can carry its own.

Picture-viewer compatibility

  • Alphabetical order of chapter folders and page files equals reading order, as long as numbers are zero-padded and separated from titles by a space.
  • In-between chapters sort correctly: c0010 Title < c0010.5 Omake < c0011 (a space sorts before .).
  • Extras (x…) sort after the numbered folders. That is also where the app lists them.
  • The one thing a plain viewer can't do is apply rot… tags.

Examples

Manga with everything

Moon Garden/
  manga.json  cover.png
  v01 Spring/
    book.json  cover.png
    c0001 The Seed/            chapter.json  0001_cover.png 0002.png … 0006_double.png … 0012.png
    c0002 Roots [MangaDex]/    chapter.json  0001_cover.png … 0014.png
    c0002 Roots [Official]/    chapter.json  0001_cover.png … 0011.png     <- second version of ch. 2
    c0002.5 Tea Time/          chapter.json  0001.png … 0004.png           <- in-between chapter
    x01 Character Sheets/      chapter.json  0001_extra.png …              <- extra chapter
  v02 Summer/
    c0003 The Tide/            … 0009_rot90.png … 0014_extra.png 0015_extra.png
  x01 Specials/
    x01 Artbook/               …                                           <- extra book

Webtoon (manga.json: "direction": "ttb")

Skyline Tower/
  v01 Season 1/
    c0001 Episode 1/   0001.png … 0008.png      <- slices of one strip, same width, no gaps

Bare minimum (no JSON at all: titles and ids come from the folder names)

Blank Slate/
  v01/
    c0001/  0001.png 0002.png …

One-shot: a manga with one book and one chapter (Oneshot Title/v01/c0001/…), or an extra book inside the related series (x01 Oneshots/x01 Title/).

Renaming: what survives

Change Effect
Title part of a book folder (v01 Spring → v01 Early Spring) Nothing lost
Title part of a chapter folder (c0003 Tide → c0003 The Tide) Same chapter (the key is unchanged), so progress and notifications are fine. The full folder name is the version id, though, so votes for that version are lost, and saved progress is re-mapped proportionally
manga.json / chapter.json content Picked up on the next scan. Nothing lost
Manga folder name New manga: progress, follows, votes and seen-chapters are gone
Book number, chapter number, or moving a chapter to another book New chapter id: progress/votes stay with the old id, and followers are notified again
Version folder name Votes for that version are lost. Progress falls back to the best version at a proportional page
Page files replaced in place (same file names) Cached image sizes may be stale until an admin runs Full rescan