Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion astro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const nimbusConfig = defineNimbusConfig({
site: "https://kmworks.date",
title: "kmworks",
description:
"kmworks is an open-source comic and manga reading ecosystem: server and native clients, drop-in compatible with Komga.",
"kmworks is an open-source reading ecosystem: KMReader, a native Apple client, and KMServer, a full-featured Komga drop-in replacement in Rust with additional capabilities and a small memory footprint.",
locale: "en",
github: "https://github.com/kmworks",
editPattern: "https://github.com/kmworks/website/edit/main/{path}",
Expand Down
11 changes: 11 additions & 0 deletions src/content/docs/server/compatibility.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ sidebar:

The compatibility target is **komga 1.29.0**: the Flyway migrations, the OpenAPI document, and the behavior fixtures are taken from that release, and API behavior is ported from it. Improvements and intentional behavior differences are listed under [Enhancements](/server/enhancements); accepted gaps under [Known limitations](/server/limitations).

## Compatibility scope

KMServer is a full-featured drop-in replacement, not a CBZ/CBR-only or API-only subset. Its scope includes:

- **Libraries and media**: CBZ/ZIP, CBR/RAR, PDF, and EPUB scanning, metadata extraction, thumbnails, and page/resource serving
- **APIs and clients**: REST, OPDS v1.2/v2, SSE, Kobo and KOReader sync, authentication, and the bundled web UI
- **Existing installations**: the same port, mounts, and `KOMGA_*` environment variables, with in-place upgrades of `database.sqlite` and `tasks.sqlite` that remain readable by Java Komga
- **Additional capabilities**: smart lists, reading trackers, CJK cross-search, outbound webhooks, reading statistics, and the other [Enhancements](/server/enhancements)

The accepted gaps and intentional scope exclusions are explicit: see [Known limitations](/server/limitations).

## Differential test harness

`tests/diff/diff.py` starts the Java komga and kmrs side by side over the same fixture library and compares ~105 endpoints (status, normalized JSON/XML bodies, headers, zip structure):
Expand Down
32 changes: 28 additions & 4 deletions src/content/docs/server/intro.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ sidebar:
order: 0
---

KMServer is a drop-in, API-compatible reimplementation of the [Komga](https://komga.org) comic/manga server in Rust, distributed as the `kmrs` binary: a single static executable.
KMServer is a full-featured drop-in replacement for [Komga](https://komga.org) in Rust — same library formats, API, and database, plus additional capabilities. It is distributed as the `kmrs` binary: a single static executable with no JVM and a small memory footprint.

*The name: Keep Manga Reading Simple.*

Expand All @@ -25,15 +25,39 @@ Try KMServer at [demo.kmworks.date](https://demo.kmworks.date): the latest image

- **Drop-in replacement** for `gotson/komga`: same port (25600), same `/config` and `/data` mounts, same `KOMGA_*` environment variables
- **Data-level compatibility**: opens and upgrades existing komga data directories (`database.sqlite`, `tasks.sqlite`) in place, and the Java version can still open libraries written by KMServer
- **Library formats**: CBZ/ZIP, CBR/RAR, PDF, and EPUB — scanning, metadata extraction, thumbnails, and Komga-compatible page/resource serving
- **API parity**: REST `/api/**`, OPDS v1.2/v2, SSE, Kobo sync, and KOReader progress sync, with endpoints, DTOs, pagination, error shapes, and authentication behavior matching the Java version
- **Verified against the Java version**: byte-for-byte Flyway migrations, a differential test harness comparing ~105 endpoints against a live Java instance, and schema contract tests
- **Efficient by design**: no JVM, bounded memory, and container caches that avoid reopening books for every page
- **Beyond Komga**: smart lists, reading trackers, CJK cross-search, outbound webhooks, reading statistics, and [more](/server/enhancements)

## Supported formats

KMServer scans the same library file types as Komga. Each library can independently enable or disable CBX (CBZ/ZIP and CBR/RAR), PDF, and EPUB scanning.

| Format | Support |
| ------ | ------- |
| **CBZ / ZIP** | Image pages, `ComicInfo.xml` metadata, thumbnails, and page serving. |
| **CBR / RAR** | RAR 4 and RAR 5 image archives, with the same metadata, thumbnail, and page-serving flow. |
| **PDF** | Page analysis, thumbnails, and on-demand JPEG rendering through libpdfium. The Docker image includes libpdfium; standalone installations must provide it at runtime. |
| **EPUB** | OPF metadata, tables of contents, landmarks, reading positions, and resource serving. Compatible readers render reflowable and fixed-layout books; image-based EPUBs can also use DIVINA page reading. |

Webtoon is a reading presentation, not a file format. For webtoons and long strips, choose Webtoon in a compatible reader; the book itself still uses one of the formats above.

For media-type restrictions and PDFium lookup details, see [Known limitations](/server/limitations#media-formats).

## Enhancements

On top of drop-in compatibility, KMServer adds improvements the Java version does not have:
On top of drop-in compatibility, KMServer adds capabilities the Java version does not have:

- **Smart lists**: saved searches evaluated live per user, with sharing scopes and generated covers
- **Reading trackers**: reading-progress sync with AniList, MyAnimeList, Bangumi, and MangaBaka
- **Search**: simplified ↔ traditional Chinese cross-search and CJK boundary unigrams (e.g. `3月` matches `3月的狮子`)
- **Outbound webhooks**: library events delivered as signed JSON payloads
- **Reading statistics**: per-user totals, daily activity, and reading streaks
- **Sorting**: natural sort of numbered titles ("Page 2" < "Page 10") with a configurable ICU locale (`server.sort-locale`)

- **Search**: simplified ↔ traditional Chinese cross-search and CJK boundary unigrams (e.g. `3月` matches `3月的狮子`). See [Search](/server/search).
- **Sorting**: natural sort of numbered titles ("Page 2" < "Page 10") with a configurable ICU locale (`server.sort-locale`). The full list: [Enhancements](/server/enhancements).
See the full list under [Enhancements](/server/enhancements).

## Migrating from Komga

Expand Down
4 changes: 2 additions & 2 deletions src/pages/architecture.astro
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ export const prerender = true;
const blocks = [
{
title: "Server",
body: "KMServer is a single static Rust binary (kmrs). It scans your library directories in place and serves everything over HTTP on port 25600. The kmweb UI is embedded in the binary, so the browser interface works out of the box.",
body: "KMServer is a full-featured Komga drop-in replacement with additional capabilities, distributed as a single static Rust binary (kmrs) with no JVM and a small memory footprint. It scans your library directories in place and serves everything over HTTP on port 25600. The kmweb UI is embedded in the binary, so the browser interface works out of the box. Bounded memory and container caches keep resource use predictable and page serving efficient.",
icon: "ph:hard-drives",
},
{
title: "API",
body: "The Komga-compatible surface: REST under /api, OPDS v1.2/v2 catalogs, SSE live updates, and Kobo and KOReader sync. A differential harness compares about 105 endpoints against a live Java instance of the compatibility target (komga 1.28.1).",
body: "The Komga-compatible surface: REST under /api, OPDS v1.2/v2 catalogs, SSE live updates, and Kobo and KOReader sync. A differential harness compares about 105 endpoints against a live Java Komga instance.",
icon: "ph:plugs-connected",
},
{
Expand Down
12 changes: 12 additions & 0 deletions src/pages/faq.astro
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,18 @@ const faqs = [
q: "Can I continue using other Komga clients?",
a: "Yes. KMServer speaks the same API: REST, OPDS v1.2/v2, SSE, Kobo and KOReader sync. Your existing clients reconnect without changes.",
},
{
q: "Is KMServer a full Komga replacement or a lightweight subset?",
a: "KMServer is a full-featured drop-in replacement for Komga, not a CBZ/CBR-only subset. It supports the same library formats, API, and database, and adds capabilities such as smart lists, reading trackers, CJK cross-search, webhooks, and reading statistics. It also runs without a JVM, with bounded memory and container caches for efficient page serving.",
},
{
q: "Which file formats does KMServer support?",
a: "KMServer scans CBZ/ZIP, CBR/RAR, PDF, and EPUB books. Webtoon is a reading presentation for compatible books, not a separate file format.",
},
{
q: "How can KMServer support PDF and EPUB while staying lightweight?",
a: "PDF pages are rendered on demand by libpdfium instead of PDFBox on a JVM. The Docker image includes libpdfium; standalone installations must provide it. EPUB packages are parsed on the server, while compatible readers handle layout using the served metadata, navigation, and resources.",
},
{
q: "Does KMReader work offline?",
a: "Yes. Downloaded books stay fully readable offline: pages, covers, metadata and progress are stored locally.",
Expand Down
20 changes: 14 additions & 6 deletions src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ const dockerRun = `docker run -d \\
ghcr.io/kmworks/kmrs`;

const serverFeatures = [
{ title: "One binary", icon: "ph:package" },
{ title: "Small footprint", icon: "ph:package" },
{ title: "Cross-platform", icon: "ph:devices" },
{ title: "Komga-compatible", icon: "ph:plugs-connected" },
{ title: "Komga + enhancements", icon: "ph:plugs-connected" },
{ title: "Web UI included", icon: "ph:browser" },
{ title: "Existing libraries", icon: "ph:books" },
{ title: "Existing database", icon: "ph:database" },
Expand All @@ -32,7 +32,7 @@ const serverFeatures = [

<BaseLayout
title="Native Komga Clients & Compatible Server"
description="kmworks is an open-source comic and manga reading ecosystem: KMReader, a native Apple client, and KMServer, a Komga-compatible server. Works with your existing Komga library."
description="kmworks is an open-source reading ecosystem: KMReader, a native Apple client, and KMServer, a full-featured Komga drop-in replacement in Rust with additional capabilities and a small memory footprint."
>
<div class="flex flex-col min-h-screen km-landing">
<Header />
Expand All @@ -47,7 +47,8 @@ const serverFeatures = [
<p class="heroSub">
An open-source ecosystem for your comic and manga library:
KMReader, a native Apple client, and KMServer, a
Komga-compatible server in Rust.
full-featured Komga drop-in replacement in Rust with a small
memory footprint.
</p>
<div class="ctaRow">
<a class="btnPrimary" href={appStoreUrl} target="_blank" rel="noopener">
Expand Down Expand Up @@ -167,8 +168,9 @@ const serverFeatures = [
<p class="eyebrow">KMServer</p>
<h2 class="sectionTitle">Your library. One server.</h2>
<p class="sectionSub">
Komga reimplemented in Rust: one static binary, a bounded
footprint, and the web UI included.
A full-featured Komga drop-in replacement in Rust: the same
formats, API and database, plus additional capabilities — in
one static binary with no JVM and a small memory footprint.
</p>
<div class="miniGrid" style="margin-top: 1.8rem;">
{serverFeatures.map((f) => (
Expand All @@ -178,6 +180,12 @@ const serverFeatures = [
</div>
))}
</div>
<div class="chipRow" style="margin-top: 1rem;" aria-label="Supported library formats">
<span class="chip">CBZ</span>
<span class="chip">CBR</span>
<span class="chip">PDF</span>
<span class="chip">EPUB</span>
</div>
<div class="ctaRow" style="margin-top: 2rem;">
<a class="btnPrimary" href={releasesUrl} target="_blank" rel="noopener">
Download KMServer
Expand Down
24 changes: 14 additions & 10 deletions src/pages/server/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ const clients = [
---

<BaseLayout
title="KMServer — Komga-Compatible Comic & Manga Server, in Rust"
description="KMServer is a lightweight, Komga-compatible comic and manga server written in Rust, with the web UI included. Same API, same database: point it at your existing Komga library."
title="KMServer — Full-Featured Komga Drop-in Replacement in Rust"
description="KMServer is a full-featured Komga drop-in replacement in Rust: CBZ/CBR/PDF/EPUB, the same API and database, a bundled web UI, additional capabilities, and a small memory footprint."
>
<div class="flex flex-col min-h-screen km-landing">
<Header />
Expand All @@ -64,16 +64,20 @@ const clients = [
<p class="eyebrow">KMServer</p>
<h1 class="heroTitle">Your library. One server.</h1>
<p class="heroSub">
Komga reimplemented in Rust: one static binary, a bounded
footprint, and the web UI included.
A full-featured Komga drop-in replacement in Rust: the same
formats, API and database, plus additional capabilities — in
one static binary with no JVM and a small memory footprint.
</p>
<div class="chipRow" style="margin-top: 0; margin-bottom: 2rem;">
<span class="chip">Written in Rust</span>
<span class="chip">Komga-compatible</span>
<span class="chip">Komga + enhancements</span>
<span class="chip">CBZ · CBR · PDF · EPUB</span>
<span class="chip">Existing libraries</span>
<span class="chip">Existing database</span>
<span class="chip">Cross-platform</span>
<span class="chip">Single binary</span>
<span class="chip">Small footprint</span>
</div>
<div class="ctaRow">
<a class="btnPrimary" href={releasesUrl} target="_blank" rel="noopener">
Expand Down Expand Up @@ -148,11 +152,11 @@ const clients = [
<div class="cardIcon">
<Icon name="ph:memory" class="w-[26px] h-[26px]" />
</div>
<h3 class="cardTitle">Bounded memory</h3>
<h3 class="cardTitle">Small footprint, efficient serving</h3>
<p class="cardBody">
A 16 MiB SQLite page-cache budget per database and capped
allocator arenas keep the footprint flat, whatever the
hardware. <a href="/server/enhancements">Enhancements</a>
A 16 MiB SQLite page-cache budget per database, capped
allocator arenas, and bounded container caches keep memory
predictable and page serving efficient. <a href="/server/enhancements">Enhancements</a>
</p>
</article>
<article class="card">
Expand Down Expand Up @@ -186,8 +190,8 @@ const clients = [
<h3 class="cardTitle">API parity, verified</h3>
<p class="cardBody">
REST, OPDS v1.2/v2, SSE, Kobo and KOReader sync. A differential
harness compares about 105 endpoints against a live Java
instance of the compatibility target (komga 1.28.1).
harness compares about 105 endpoints against a live Java Komga
instance.
</p>
<Code code={diffRun} lang="bash" />
</div>
Expand Down
Loading