GitPedia

GraphCompose

Declarative Java PDF engine for structured business documents — semantic layout, atomic pagination, theme tokens, native charts, SVG & gradients, deterministic, PDFBox-backed

From DemchaAV·Updated June 29, 2026·View on GitHub·

Declarative Java DSL for structured business PDFs. Describe what the document says; the engine resolves layout, pagination, themes, and PDFBox rendering. Cinematic by default. The project is written primarily in Java, distributed under the MIT License license, first published in 2025. Key topics include: business-documents, cv-templates, declarative-api, document-generation, invoice-template.

Latest release: v1.9.0GraphCompose v1.9.0
June 29, 2026View Changelog →

GraphCompose

<p align="center"> <img src="./assets/GraphComposeLogo.png" alt="GraphCompose logo" width="300"/> </p> <p align="center"> <b>Declarative Java DSL for structured business PDFs.</b><br/> Describe what the document <i>says</i>; the engine resolves layout, pagination, themes, and PDFBox rendering. <b>Cinematic by default.</b> </p> <p align="center"> <a href="https://github.com/DemchaAV/GraphCompose/actions/workflows/ci.yml?query=branch%3Amain"><img src="https://img.shields.io/github/actions/workflow/status/DemchaAV/GraphCompose/ci.yml?branch=main&style=for-the-badge&label=CI" alt="CI"/></a> <a href="https://github.com/DemchaAV/GraphCompose/releases/latest"><img src="https://img.shields.io/github/v/release/DemchaAV/GraphCompose?style=for-the-badge&label=Release" alt="Latest release"/></a> <a href="https://central.sonatype.com/artifact/io.github.demchaav/graph-compose"><img src="https://img.shields.io/maven-central/v/io.github.demchaav/graph-compose?style=for-the-badge&label=Maven%20Central" alt="Maven Central"/></a> <img src="https://img.shields.io/badge/Java-17%2B-orange?style=for-the-badge&logo=openjdk" alt="Java 17+"/> <img src="https://img.shields.io/badge/PDFBox-3.0-red?style=for-the-badge" alt="PDFBox 3.0"/> <img src="https://img.shields.io/badge/License-MIT-blue?style=for-the-badge" alt="MIT License"/> </p>

Release status
🟢 Latest stable: v1.9.0 — codenamed "navigable": in-document navigation (anchors, internal links, a clickable TOC, page references & bookmarks), multi-section documents, and inline chips / SVG icons / colour emoji. What's new in v1.9 ↓

 ·  🟡 In develop: next cycle — open (see CHANGELOG)
 ·  See API stability policy for tier definitions.

<p align="center"> <a href="https://demchaav.github.io/GraphCompose/"><b>Live Showcase</b></a> &nbsp;·&nbsp; <a href="./examples/README.md"><b>Examples Gallery</b></a> &nbsp;·&nbsp; <a href="./docs/README.md"><b>Docs</b></a> &nbsp;·&nbsp; <a href="./CHANGELOG.md"><b>Changelog</b></a> </p> <p align="center"> <img src="./assets/readme/repository_showcase_render.png" alt="GraphCompose render preview" width="780"/> </p> <p align="center"> <sub>☝ This banner is itself a GraphCompose document — <a href="./assets/readme/examples/engine-deck.pdf"><b>view the full capability deck (PDF)</b></a>, rendered by <a href="./examples/src/main/java/com/demcha/examples/flagships/EngineDeckExample.java"><code>EngineDeckExample</code></a>: native vector charts and real comparative benchmarks, all drawn by the engine. It renders its own marketing.</sub> </p>

Why GraphCompose

  • Author intent, not coordinates. Fluent DSL for sections, paragraphs, tables, lists, layer stacks, themes — the engine handles measurement, pagination, and rendering.
  • Deterministic by design. Two-pass layout. Snapshots are stable across machines, so layout regressions are catchable in tests before any byte ships.
  • Cinematic by default. BusinessTheme, soft panels, accent strips, transforms, native vector charts, and gradients are first-class primitives, not workarounds.
  • PDFBox isolated, DOCX optional. Single backend interface. Apache POI–backed DOCX export is available for compatible semantic content — see support matrix for limitations.

Sits between iText (low-level page primitives) and JasperReports (XML-template-driven layout): a Java DSL describes the document semantically, the engine renders.

What's new in v1.9

The "navigable" release — a rendered PDF becomes a document you can move through.

  • In-document navigation — named anchor(...) targets and internal link(...) jumps emitted as native PDF GoTo actions: clickable cross-references, [text](#heading)-style links, and bidirectional footnotes (DocumentLinkTarget unifies internal and external links).
  • Native table of contents & page referencesaddTableOfContents(toc -> toc.entry(label, anchor)) builds a clickable TOC with dot leaders and auto-resolved page numbers; addPageReference(anchor) prints a native "see page N" cross-reference; DocumentSession.pageIndex() resolves any anchor to its page.
  • Bookmarks & viewer preferencessection.bookmark(...) makes any section or container a PDF outline (bookmark-panel) target, and chrome().viewerPreferences(...) opens the reader on the outline panel, a chosen page layout, or the doc title in the window.
  • Multi-section documentsGraphCompose.documents() concatenates independently authored sections — each with its own page size, margins, and footer numbering — into one PDF, with anchors, links, and the outline resolving across section boundaries.
  • Richer row & page layoutrow.columns(auto(), weight(1), fixed(80)), main-axis flexSpacer() / arrangement(...), cross-axis verticalAlign(...), per-page pageMargins(...), and full-bleed bleed(...).
  • Inline chips, SVG icons & colour emoji — text on a rounded highlight chip, a parsed SvgIcon on the text baseline, and RichText.emoji(":star:", size) colour emoji via the new independently-versioned graph-compose-emoji module.
  • Render straight to imagesDocumentSession renders directly to BufferedImages with no PDF round-trip; plus page-number offset / restart / style and round / dotted line caps.

Core document APIs stay source- and binary-compatible with v1.8 — v1.9 is purely additive (two cover-letter / CV shim types are newly @Deprecated for 2.0). Full notes in CHANGELOG.md.

Installation

Requires Java 17+ (enforced by the build).

xml
<dependency> <groupId>io.github.demchaav</groupId> <artifactId>graph-compose</artifactId> <version>1.9.0</version> </dependency>
kotlin
dependencies { implementation("io.github.demchaav:graph-compose:1.9.0") }

Bundled fonts (from v1.8.0). The curated Google fonts no longer ship
inside the engine jar — they live in an independently-versioned
companion artifact so an engine upgrade never re-downloads ~18 MB of
fonts. Pure-text and standard-14 documents need nothing extra; to use the
bundled families, add:

xml
<dependency> <groupId>io.github.demchaav</groupId> <artifactId>graph-compose-fonts</artifactId> <version>1.0.0</version> </dependency>

Prefer a single "batteries-included" coordinate? Depend on
io.github.demchaav:graph-compose-bundle (same version as graph-compose
above) to pull the engine + fonts together. Full details and upgrade steps:
the v1.8.0 fonts migration note.

Colour emoji (from v1.9.0). RichText.emoji(":star:", size) resolves
GitHub-style shortcodes to inline vector glyphs from an independently-versioned
companion artifact (the same split model as the fonts above). Text without
emoji needs nothing extra; to render colour emoji, add:

xml
<dependency> <groupId>io.github.demchaav</groupId> <artifactId>graph-compose-emoji</artifactId> <version>1.0.0</version> </dependency>

An unknown shortcode falls back to its literal text, so a document that uses no
emoji — or runs without the artifact — renders unchanged. The
graph-compose-bundle stays fonts-only; emoji is opt-in.

Distribution — Maven Central is the canonical channel from v1.6.6 onwards
(io.github.demchaav:graph-compose:<version>). Hosted Javadocs auto-publish to
javadoc.io/doc/io.github.demchaav/graph-compose
shortly after each Central release. The legacy JitPack URL
(com.github.DemchaAV:GraphCompose:v<version>) remains resolvable for callers
pinned to v1.6.5 and earlier but is no longer the documented install option.

Upgrading from v1.5? Core document authoring stays source-compatible — engine, DSL, themes, and backend-neutral records carry v1.5 callers unchanged. Templates v2 replaces the legacy CV / cover-letter template classes; legacy classes were deleted, not deprecated. Read the migration guide before upgrading template-heavy code.

Hello world

java
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; class Hello { public static void main(String[] args) throws Exception { BusinessTheme theme = BusinessTheme.modern(); try (DocumentSession document = GraphCompose.document(Path.of("hello.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, no manual coordinates.") .textStyle(theme.text().body())))); document.buildPdf(); } } }

For a Spring Boot @RestController streaming the PDF straight to the response, see HttpStreamingExample.

Scope and comparison

Output support

FormatStatusNotes
PDFProductionFixed-layout backend on PDFBox 3.0. Full DSL coverage.
DOCXPartialSemantic export via Apache POI. Unsupported nodes (shape, line, ellipse, barcode) are dropped silently — layout fidelity is best-effort for paragraph / list / table content.
PPTXSkeletonValidates supported node types and emits a manifest. Not a real PowerPoint export yet — planned only if there is demand.

When to use GraphCompose

  • Server-side PDF generation in Java — invoices, CVs, reports, proposals, statements, schedules.
  • Templated documents from data — themed presets (ModernProfessional, InvoiceTemplateV2, …) you parameterise instead of re-styling every time.
  • Regression-tested layoutsDocumentSession#layoutSnapshot() makes layout changes visible in PRs before any byte ships; PdfVisualRegression adds a pixel-level gate for font and colour fidelity.
  • Streaming PDFs from web backends — Spring Boot @RestController writing straight to the response (HttpStreamingExample).
  • Higher-level than PDFBox, lighter than JasperReports — Java DSL describes semantics; no XML templates, no manual coordinates.

What GraphCompose is not

  • Not a hosted PDF rendering service — it is a library you embed.
  • Not a WYSIWYG editor — the DSL is code, not drag-and-drop.
  • Not a reporting engine like JasperReports — no datasource bindings, no XML templates, no compiled .jasper files.
  • Not a browser / HTML-to-PDF renderer — the engine has its own layout pipeline; HTML/CSS input is not supported.

Compared with similar Java libraries

LibraryAPI styleLayoutLicenseBest for
GraphComposeJava DSL, semantic nodesTwo-pass, deterministic, snapshot-testableMITCode-first business documents with layout regression tests
PDFBoxLow-level text / path primitivesManual coordinatesApache 2.0Direct PDF manipulation, parsing, extraction
iText 7Object/layout API + low-level canvasAutomatic layout with direct-positioning optionsAGPL / commercialWhen AGPL is acceptable or you have a commercial licence
OpenPDFiText 4 forkManual + helpersLGPL / MPLLegacy iText 4 codebases
JasperReportsXML templates compiled to .jasperTemplate-drivenLGPLTabular reports with datasource bindings

GraphCompose uses PDFBox under the hood as the rendering backend — the comparison is about authoring surface, not the renderer.

Which API should I use?

You want to…SurfaceEntry point
Generate a one-off PDF programmaticallyDSLGraphCompose.document(...).pageFlow(...) — see Hello world above
Generate a CV / cover letter from dataLayered templatesModernProfessional.create().compose(session, cvDocument) — see layered templates
Add a custom visual primitiveEngine extensionNodeDefinition + PdfFragmentRenderHandler — see extension guide
Regression-test generated layoutsLayout snapshotsDocumentSession#layoutSnapshot() — quickstart at Testing your document; full reference at snapshot testing
Pixel-test the rendered PDF (fonts, colours, anti-aliasing)Visual regressionPdfVisualRegression.standard()&hellip;assertMatchesBaseline(...) — see visual regression testing
See the live galleryStatic showcase siteShowcase — source under web/, deployed to GitHub Pages via the Pages workflow

Choosing a template surface — layered (cv.v2), classic (cv.presets), or the built-in *TemplateV2 family? See Which template system should I use? for the status matrix, decision tree, and classic → layered migration map.

v1.8 primitives in 30 lines

Three snippets from the new vector surfaces. Full runnable versions live in the examples gallery.

Native chart — categories + series in, native vector bars out (no rasterization).

java
ChartData revenue = ChartData.builder() .categories("Q1", "Q2", "Q3", "Q4") .series("2024", 12.4, 15.1, 9.8, 14.2) .series("2025", 14.0, 18.2, 11.3, 16.9) .build(); section.chart(ChartSpec.bar().data(revenue) .legend(LegendPosition.BOTTOM) .size(ChartSize.aspectRatio(16, 7)) .build());

Overshoot-free line — a smooth curve constrained to never overshoot the data range.

java
section.chart(ChartSpec.line().data(series) .interpolation(LineInterpolation.MONOTONE) .build());

SVG import + alignment — parse SVG to native geometry, seat any fixed node across the width.

java
SvgIcon globe = SvgIcon.parse(svgMarkup); flow.addSvgIcon(globe, 48, HorizontalAlign.CENTER); flow.addAligned(HorizontalAlign.RIGHT, anyFixedNode);

Architecture

GraphCompose splits into a public canonical surface you author against (com.demcha.compose.document.*) and an internal shared engine foundation (com.demcha.compose.engine.*, marked @Internal) that resolves geometry, pagination, and rendering behind it. You author intent; the engine resolves the rest.

mermaid
flowchart LR A["GraphCompose.document(...)<br/>DocumentSession · DocumentDsl"] --> B["DocumentNode tree<br/>document.node"] B --> C["LayoutCompiler<br/>document.layout"] C --> D["Engine foundation @Internal<br/>measure → paginate → place"] D --> E{Backend} E -->|PDF| F["PdfFixedLayoutBackend"] E -->|DOCX| G["DocxSemanticBackend · POI"] D -.->|layoutSnapshot| H["Deterministic snapshot<br/>(regression tests)"]

Full detail: architecture overview · package map · lifecycle.

Documentation

📚 Full docs index — categorised map of every doc, ADR, and recipe. Start there to navigate the documentation.

Templates

Architecture & operations

Recipes & examples

Contributing & releases

Companion projects

  • graphcompose-ai-flow — experimental sister project exploring an AI-assisted authoring flow on top of GraphCompose. Independent codebase, separate lifecycle — nothing in this repo depends on it. Track it if you are interested in agentic document composition driven by the same semantic node model.

License

MIT — see LICENSE.

Star History

<a href="https://www.star-history.com/?repos=DemchaAV%2FGraphCompose&type=date&legend=top-left"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=DemchaAV/GraphCompose&type=date&theme=dark&legend=top-left" /> <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=DemchaAV/GraphCompose&type=date&legend=top-left" /> <img alt="Star History Chart" src="https://api.star-history.com/chart?repos=DemchaAV/GraphCompose&type=date&legend=top-left" /> </picture> </a>

Contributors

Showing top 3 contributors by commit count.

View all contributors on GitHub →

This article is auto-generated from DemchaAV/GraphCompose via the GitHub API.Last fetched: 6/29/2026