Developer guide

This part of the manual is for people who want to change Marginalia itself, write an extension for it, or just understand how it works inside. If you only want to install and use Marginalia, see the User guide.

Marginalia is a single Java web application. The browser UI is written in Java with Vaadin Flow, the services are plain Spring beans wired in XML, the data lives in one SQLite file accessed through Hibernate, and extensions are OSGi bundles that hook into the UI at runtime. The same WAR runs on a server (Docker, Jetty) and inside the desktop app.

Technology

Area Used
Language, build Java 25, Maven 3.9
User interface Vaadin Flow 25 (server-side Java components, Lumo theme, server push over WebSocket)
Application framework Spring 7 (XML configuration, no Spring Boot), AspectJ compile-time weaving for @Configurable and @Transactional
Persistence Hibernate 7 (JPA), SQLite (sqlite-jdbc, WAL mode), Flyway migrations
LLM access openai-java against any OpenAI-compatible API, JTokkit and server tokenizers for token counts
Templates Handlebars.java with SillyTavern-compatible macros
Extensions Apache Felix (OSGi), ByteBuddy agent for bytecode instrumentation of @Extendable classes
Server Any Jakarta EE 11 servlet container (Servlet 6.1) - Jetty 12 in Docker and in the desktop app
Tests JUnit 6, AssertJ, Spring Test, a fake OpenAI-compatible server
Manual Retype (sources in manual/, generated site in docs/)

Repository at a glance

Marginalia/
├── marginalia/            the application (Maven project, WAR packaging)
│   ├── src/main/java      application code (com.github.enerccio.marginalia)
│   ├── src/main/resources Spring XML, Flyway migrations, logging
│   ├── src/main/webapp    configuration.properties, persistence.xml
│   ├── src/main/frontend  CSS and JS used by the Vaadin frontend
│   ├── src/desktop        desktop launcher (tray icon, starts Jetty) and launch scripts
│   ├── src/test           tests
│   └── plugins/           the five bundled extensions, each a separate Maven project
├── manual/                this manual (Retype sources)
├── docs/                  generated manual, served by GitHub Pages
├── Dockerfile, docker-compose.yml
└── .github/workflows/     CI (desktop builds and releases)

Project structure describes the packages and files in detail.

Getting started

  1. Building from source - requirements, building the WAR, running Marginalia from your IDE or a local Jetty, running the tests, building the plugins.

  2. Architecture - how the pieces fit together: startup, Spring wiring, the UI, services and data, generation, extensions.

  3. Then read the page about the area you want to change.

The shortest path from a fresh clone to a running instance:

git clone https://github.com/Enerccio/Marginalia.git
cd Marginalia/marginalia
mvn package -DskipTests                     # target/marginalia-1.0.0.war

Deploy target/marginalia-1.0.0.war (or the exploded target/marginalia-1.0.0/ folder) to Tomcat 11 or Jetty 12, or use docker compose up --build from the repository root. Building from source has the details.

Pages in this guide

Page What it covers
Building from source Requirements, Maven builds, running locally, tests, plugins, the manual.
Architecture The big picture: layers, startup, wiring, threading, extension mechanism.
Project structure Packages, resources and what lives where.
Domain model Entities (books, parts, lorebooks, providers, protocols...), ownership, soft delete.
Database & migrations SQLite, Flyway migrations, adding an entity or a column.
Services Service and repository layer, transactions, the current user.
Generation pipeline How a story part is generated, step by step.
Templating & macros Prompt templates, template data, the macro translator.
User interface Routes, workspace, dialogs, push and background threads.
Plugin development Writing extensions: bundles, @Extendable hooks, extended attributes, UI extensions.
Testing Running tests, test bases, the fake LLM server, CRUD contracts, writing tests.
Packaging & releases WAR, Docker image, desktop app, CI, making a release.
Contributing Reporting bugs, workflow, commits, pull requests, code style, documentation.

Conventions used in this guide

  • Paths like ui/workspace/Workspace.java are relative to marginalia/src/main/java/com/github/enerccio/marginalia/ unless they start with marginalia/ or another top-level folder.

  • Book and part are the user-facing names of Manuscript and ChatMessage - the code still uses the old names. Likewise inference provider is AI, protocol is Protocol.

  • Commands are run from the marginalia/ folder unless said otherwise.