https://github.com/demchaav/graphcompose
Declarative Java PDF layout engine for structured business documents β semantic node tree, atomic pagination, theme tokens, PDFBox-backed
https://github.com/demchaav/graphcompose
business-documents cv-templates declarative-api document-generation invoice-template java java-17 layout-engine maven pagination pdf pdf-generator pdf-lib pdf-library pdfbox3 report-generation snapshot-testing template-engine
Last synced: 3 days ago
JSON representation
Declarative Java PDF layout engine for structured business documents β semantic node tree, atomic pagination, theme tokens, PDFBox-backed
- Host: GitHub
- URL: https://github.com/demchaav/graphcompose
- Owner: DemchaAV
- License: mit
- Created: 2025-08-20T18:16:34.000Z (10 months ago)
- Default Branch: main
- Last Pushed: 2026-05-25T21:59:38.000Z (9 days ago)
- Last Synced: 2026-05-25T23:28:12.389Z (9 days ago)
- Topics: business-documents, cv-templates, declarative-api, document-generation, invoice-template, java, java-17, layout-engine, maven, pagination, pdf, pdf-generator, pdf-lib, pdf-library, pdfbox3, report-generation, snapshot-testing, template-engine
- Language: Java
- Homepage: https://demchaav.github.io/GraphCompose/
- Size: 55.7 MB
- Stars: 56
- Watchers: 1
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Codeowners: .github/CODEOWNERS
- Security: SECURITY.md
- Support: SUPPORT.md
- Roadmap: ROADMAP.md
Awesome Lists containing this project
README
# GraphCompose
Declarative Java DSL for structured business PDFs.
Describe what the document says; the engine resolves layout, pagination, themes, and PDFBox rendering. Cinematic by default.
> **Release status** β
> π’ **Latest stable**: [v1.6.5](https://github.com/DemchaAV/GraphCompose/releases/tag/v1.6.5)
> Β Β·Β π‘ **In develop**: v1.6.6 (Maven Central debut; zero breaking from v1.6.5)
> Β Β·Β βͺ **Planned next**: v1.6.7 (dependency cleanup), v1.7.0 (new canonical DSL primitives)
> Β Β·Β See [API stability policy](./docs/api-stability.md) for tier definitions.
Live Showcase
Β Β·Β
Examples Gallery
Β Β·Β
Changelog
## 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 + advanced tables 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](#output-support) 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.
## Scope and comparison
### Output support
| Format | Status | Notes |
|---|---|---|
| PDF | Production | Fixed-layout backend on PDFBox 3.0. Full DSL coverage. |
| DOCX | Partial | Semantic export via Apache POI. Unsupported nodes (`shape`, `line`, `ellipse`, `barcode`) are dropped silently β layout fidelity is best-effort for paragraph / list / table content. |
| PPTX | Skeleton | Validates 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 layouts** β `DocumentSession#layoutSnapshot()` makes layout changes visible in PRs before any byte ships.
- **Streaming PDFs from web backends** β Spring Boot `@RestController` writing straight to the response ([`HttpStreamingExample`](./examples/src/main/java/com/demcha/examples/features/streaming/HttpStreamingExample.java)).
- **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
| Library | API style | Layout | License | Best for |
|---|---|---|---|---|
| **GraphCompose** | Java DSL, semantic nodes | Two-pass, deterministic, snapshot-testable | MIT | Code-first business documents with layout regression tests |
| **PDFBox** | Low-level text / path primitives | Manual coordinates | Apache 2.0 | Direct PDF manipulation, parsing, extraction |
| **iText 7** | Low-level page primitives + high-level helpers | Manual + helpers | AGPL / commercial | When AGPL is acceptable or you have a commercial licence |
| **OpenPDF** | iText 4 fork | Manual + helpers | LGPL / MPL | Legacy iText 4 codebases |
| **JasperReports** | XML templates compiled to `.jasper` | Template-driven | LGPL | Tabular 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⦠| Surface | Entry point |
|---|---|---|
| Generate a one-off PDF programmatically | DSL | `GraphCompose.document(...).pageFlow(...)` β see [Hello world](#hello-world) below |
| Generate a CV / cover letter from data | Layered templates | `ModernProfessional.create().compose(session, cvDocument)` β see [layered templates](./docs/templates/v2-layered/README.md) |
| Add a custom visual primitive | Engine extension | `NodeDefinition` + `PdfFragmentRenderHandler` β see [extension guide](./docs/contributing/extension-guide.md) |
| Regression-test generated layouts | Layout snapshots | `DocumentSession#layoutSnapshot()` β see [snapshot testing](./docs/operations/layout-snapshot-testing.md) |
## Installation
```xml
io.github.demchaav
graph-compose
1.6.6
```
```kotlin
dependencies { implementation("io.github.demchaav:graph-compose:1.6.6") }
```
> **Distribution** β Maven Central is the canonical channel from **v1.6.6** onwards
> (`io.github.demchaav:graph-compose:`). Hosted Javadocs auto-publish to
> [javadoc.io/doc/io.github.demchaav/graph-compose](https://javadoc.io/doc/io.github.demchaav/graph-compose)
> shortly after each Central release. The legacy JitPack URL
> (`com.github.DemchaAV:GraphCompose:v`) 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](./docs/roadmaps/migration-v1-5-to-v1-6.md) 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`](./examples/src/main/java/com/demcha/examples/features/streaming/HttpStreamingExample.java).
## What's in v1.6 β "expressive"
- **Layered templates** β 14 CV and 14 paired cover-letter presets on the layered `cv.v2` / `coverletter.v2` architecture (data β theme β components β widgets β presets), one-liner `create()` factories over a typed `CvDocument` / `CoverLetterDocument`. Inline markdown, multi-column layouts. The going-forward standard for new template families. See [`docs/templates/v2-layered/README.md`](./docs/templates/v2-layered/README.md). (The earlier `BusinessTheme`-based preset surface is now deprecated.)
- **Composed primitives** β `ListBuilder.addItem(label, Consumer)` (nested lists), `DocumentTableCell.node(...)` (any node inside a cell), `CanvasLayerNode` (pixel-precise free-canvas placement).
- **Architecture hardening** β `@Internal` API stability marker, public `PdfFragmentRenderHandler` SPI, `DocumentRenderingException` on the convenience render path, documented thread-safety contract.
Full notes in [`CHANGELOG.md`](./CHANGELOG.md). Upgrade guide: [`docs/roadmaps/migration-v1-5-to-v1-6.md`](./docs/roadmaps/migration-v1-5-to-v1-6.md).
## v1.6 primitives in 30 lines
Three snippets, one per new primitive. Full runnable versions live in the [examples gallery](./examples/README.md).
**Nested list** β builder-callback child scopes with a per-depth marker cascade.
```java
document.pageFlow().addList(list -> list
.addItem("Backend platform", row -> row
.addItem("Java 21, Spring Boot, PostgreSQL")
.addItem("REST APIs and event-driven services"))
.addItem("Document generation", row -> row
.addItem("PDF rendering pipeline")
.addItem("Layout snapshot tests")));
```
**Composed table cell** β any composable node inside a cell, two-pass row measurement.
```java
DocumentTableCell richSummary = DocumentTableCell.node(
new ParagraphNode("Summary",
"**Q3 results** were *strong* β revenue grew 18% YoY.",
bodyStyle, TextAlign.LEFT, 1.0,
DocumentInsets.zero(), DocumentInsets.zero()));
```
**Canvas layer** β pixel-precise `(x, y)` placement inside a fixed bounding box.
```java
document.pageFlow().addCanvas(523, 360, canvas -> canvas
.clipPolicy(ClipPolicy.CLIP_BOUNDS)
.position(headline, 0, 60)
.position(rule(503, 1.4, accent), 10, 32));
```
## Documentation
π **[Full docs index](./docs/README.md)** β categorised map of every doc, ADR, and recipe. Start there to navigate the documentation.
### Templates
- π [**Templates β v2 layered architecture**](./docs/templates/v2-layered/README.md) β the canonical going-forward pattern for new template families (CV v2 is the reference implementation). Personas: [quickstart](./docs/templates/v2-layered/quickstart.md) Β· [using templates](./docs/templates/v2-layered/using-templates.md) Β· [authoring presets](./docs/templates/v2-layered/authoring-presets.md) Β· [contributing a new family](./docs/templates/v2-layered/contributor-guide.md).
- [Templates v1-classic landing](./docs/templates/v1-classic/README.md) β the older `BusinessTheme` / `CvSpec` CV / cover-letter / invoice / proposal preset library (**deprecated** β CV + cover letter are superseded by [v2-layered](./docs/templates/v2-layered/README.md); invoice / proposal / schedule are not yet ported). Cheat sheet: [authoring](./docs/templates/v1-classic/authoring.md).
### Architecture & operations
- [Architecture overview](./docs/architecture/overview.md) Β· [Lifecycle](./docs/architecture/lifecycle.md) Β· [Production rendering](./docs/operations/production-rendering.md) Β· [Layout snapshot testing](./docs/operations/layout-snapshot-testing.md)
### Recipes & examples
- [Recipes index](./docs/recipes.md) β [shape-as-container](./docs/recipes/shape-as-container.md) Β· [shapes](./docs/recipes/shapes.md) Β· [transforms](./docs/recipes/transforms.md) Β· [tables](./docs/recipes/tables.md) Β· [themes](./docs/recipes/themes.md) Β· [streaming](./docs/recipes/streaming.md) Β· [extending](./docs/recipes/extending.md)
- [Examples gallery](./examples/README.md) β every runnable example with PDF preview
### Contributing & releases
- [Contributing](./CONTRIBUTING.md) Β· [Code of conduct](./CODE_OF_CONDUCT.md) Β· [Security policy](./SECURITY.md) Β· [Release process](./docs/contributing/release-process.md)
- [API stability policy](./docs/api-stability.md) Β· [Which template system?](./docs/templates/which-template-system.md) Β· [Migration v1.5 β v1.6](./docs/roadmaps/migration-v1-5-to-v1-6.md)
## Companion projects
- [**graphcompose-ai-flow**](https://github.com/DemchaAV/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`](./LICENSE).