Java-first declarative document layout engine for cinematic PDFs.
Describe semantic document structure; GraphCompose handles layout, pagination, snapshots, and PDFBox rendering — with a designer-grade visual layer on top.
Most Java PDF libraries hand you low-level drawing commands. GraphCompose gives Java applications a semantic authoring model — you describe modules, paragraphs, tables, rows, layers, and themes; the engine measures, paginates, and renders.
- Author intent, not coordinates. Fluent builder for sections, modules, paragraphs, lists, tables, images, dividers, page-breaks, and layer stacks.
- Deterministic layout. Two passes — layout resolves geometry, render consumes resolved fragments. Snapshots are stable across runs and machines, so you can regression-test layout before any PDF byte is written.
- Atomic pagination, no manual paging. Tables split row-by-row, rows are atomic, layer stacks are atomic.
- Designer-grade output. Page backgrounds, section bands, soft panels, accent strips, column spans, layered hero blocks, fluent rich text, and a tokenised
BusinessThemeare all first-class — not workarounds. - PDFBox rendering, isolated. PDF backend lives behind a single backend interface. The DOCX backend (Apache POI) is ready for callers who need an editable file.
- Tested at every layer. 672 green tests on
develop(525 → 672 across v1.5), including cinematic-feature tests, shape-as-container clip-path invariants, transform CTM checks, table row-span / zebra / repeated-header tests, public-API leak guards, and aPdfVisualRegressionharness.
The current release is v1.5.1 — the "intuitive" release. v1.5 turns the surface intuitive: shape-as-container with clip path, rotate / scale + per-layer z-index, advanced tables (row span, zebra, totals, repeating header), and two new theme-driven cinematic templates (InvoiceTemplateV2, ProposalTemplateV2). v1.5 is fully source-compatible with v1.4 — every public record gained back-compat constructors that default the new fields. See docs/migration-v1-4-to-v1-5.md.
GraphCompose is built for server-side Java services that need to generate structured business PDFs — the kind of documents your application has to produce on demand from real data, not the kind a human types into Word.
- Invoices and quotes generated per request from order data (
InvoiceTemplateV2 + BusinessTheme.modern()is the canonical entry point). - Proposals, statements of work, and reports with consistent branding across teams (
ProposalTemplateV2, customBusinessTheme). - CVs and cover letters for ATS exports, hiring tools, and recruiter dashboards (seven modernised CV templates plus the
CvTheme.fromBusinessTheme(...)bridge). - Schedules, dispatch sheets, and operational reports with deterministic pagination on long data (advanced tables: row span, zebra, totals, repeating header on page break).
- Internal tooling and admin PDFs that ship through Spring Boot, Quarkus, Micronaut, Ktor, or any plain Java HTTP service —
writePdf(OutputStream)streams straight into a Servlet response without buffering in memory.
Reaching for iText for low-level page primitives or JasperReports for XML-template-driven layout? GraphCompose sits between them: a Java DSL describes the document semantically, the engine resolves layout and pagination deterministically, and the PDF backend renders the result with PDFBox.
The proposal screenshot above is built by CinematicProposalFileExample in the runnable examples/ module — a single Java file, no XML, no template engine.
📚 Browse the full examples gallery → — every one of the 22 examples with description, key DSL snippet, committed PDF preview, and source link.
Distributed through JitPack.
<repositories>
<repository><id>jitpack.io</id><url>https://jitpack.io</url></repository>
</repositories>
<dependency>
<groupId>com.github.DemchaAV</groupId>
<artifactId>GraphCompose</artifactId>
<version>v1.5.1</version>
</dependency>repositories { maven("https://jitpack.io") }
dependencies { implementation("com.github.demchaav:GraphCompose:v1.5.1") }The DOCX backend depends on org.apache.poi:poi-ooxml, declared as optional — add it explicitly when you call session.export(new DocxSemanticBackend()).
The fastest path to a designed PDF is the v1.5 cinematic stack: pick a BusinessTheme, drop a softPanel + accentLeft hero block on the page, and let the theme drive every colour, font, and table style.
import com.demcha.compose.GraphCompose;
import com.demcha.compose.document.api.DocumentPageSize;
import com.demcha.compose.document.api.DocumentSession;
import com.demcha.compose.document.theme.BusinessTheme;
import java.nio.file.Path;
public class QuickStart {
public static void main(String[] args) throws Exception {
BusinessTheme theme = BusinessTheme.modern(); // cream paper + teal/gold
try (DocumentSession document = GraphCompose.document(Path.of("output.pdf"))
.pageSize(DocumentPageSize.A4)
.pageBackground(theme.pageBackground())
.margin(28, 28, 28, 28)
.create()) {
document.pageFlow(page -> page
.addSection("Hero", section -> section
.softPanel(theme.palette().surfaceMuted(), 10, 14)
.accentLeft(theme.palette().accent(), 4)
.addParagraph(p -> p.text("GraphCompose").textStyle(theme.text().h1()))
.addParagraph(p -> p.text("A theme-driven hero, one page, no manual coordinates.")
.textStyle(theme.text().body()))));
document.buildPdf();
}
}
}For an HTTP response, S3 upload, or in-memory generation, use the writePdf(OutputStream) overload — it streams directly and does not close the caller's stream. See HttpStreamingExample for the Spring Boot @RestController pattern.
For built-in templates (InvoiceTemplateV2, ProposalTemplateV2) and the canonical authoring patterns (builder hierarchy, theme tokens, golden patterns, anti-patterns, 40-line new-template skeleton), read the Template authoring cheatsheet once before writing your own.
Five highlights — full notes in CHANGELOG.md.
- Shape-as-container with clip path.
addCircle / addEllipse / addContainerbuild aShapeContainerNodewhose children are clipped viaClipPolicy.CLIP_PATH,CLIP_BOUNDS, orOVERFLOW_VISIBLE. → recipe - Transforms + per-layer z-index.
rotate / scalechain naturally on every shape-shaped builder;LayerStackNode.Layer.zIndexlets layers declared earlier draw on top of layers declared later. → recipe - Advanced tables.
DocumentTableCell.rowSpan(int),zebra(odd, even),totalRow(...), andrepeatHeader()cover the four features most rendered reports need. → recipe - Two cinematic templates.
InvoiceTemplateV2(BusinessTheme)andProposalTemplateV2(BusinessTheme)— the same(theme, spec)shape, drop-in replacements for V1 when you want the cinematic look. CvTheme.fromBusinessTheme(BusinessTheme)bridges the business theme tokens into CV-specific layout slots (ADR 0002). The seven CV templates each gain a(CvTheme)constructor while keeping a no-arg one for legacy palettes.
- Public authoring lives in
com.demcha.compose,document.api,document.dsl,document.node,document.style,document.table,document.theme,font. Engine internals (com.demcha.compose.engine.*) are guarded byPublicApiNoEngineLeakTest— never reach into them from application code. - Two passes:
DocumentSession.layoutGraph()resolves geometry; rendering consumes the resolved fragments. This is what makes layout snapshots, pagination, and future backends practical. - Extension seams: implement
DocumentNode+ register aNodeDefinition; emit aFragmentPayload+ register aPdfFragmentRenderHandler; add aFixedLayoutBackend<R>orSemanticBackendto target a new format. Seedocs/architecture.mdfor the full map.
- Template authoring cheatsheet — read this once before writing your own template
- Examples gallery — 22 runnable examples with PDF previews
- Architecture · Lifecycle · Production rendering
- Recipes: shape-as-container · transforms · tables · shapes · themes · streaming · extending
- Layout snapshot testing · Performance numbers · Benchmark methodology
- Migration v1.4 → v1.5 · Canonical / legacy parity
- Contributing · Release process · v1.6 roadmap
v1.6 (the "expressive" release) is in the planning phase — nested lists, composed table cells, CanvasLayer for free-form drawing, a full DOCX backend pass, and the start of Maven Central publishing. Full plan in docs/v1.6-roadmap.md. Feature requests and bug reports welcome via GitHub Issues.
GraphCompose is released under the MIT License — see LICENSE.

