This release includes 7 breaking changes for platform teams planning a safe upgrade.
✓ No known CVEs patched in this version
Topics
+12 more
Affected surfaces
ReleasePort's take
Moderate signalGraphCompose 2.0 removes several template presets, design‑token bundles, DSL aliases, PDF overloads, linkOptions accessor, unused Font method, dormant ECS internals, and drops the `.v2` suffix from layered template packages.
Why it matters: All breaking changes have severity 70; update code to use builder(), paragraph(), backend‑neutral metadata APIs, new linkTarget API, layout compiler for font sizing, remove references to removed ECS components, and adjust import statements before migrating to v2.0.0.
Summary
AI summaryBroad release touches Packaging, Build, Public API, and Internal.
Changes in this release
| Type | Severity | Summary | CVE |
|---|---|---|---|
| Breaking | High |
Removed classic CV and cover-letter template presets; use layered templates. Removed classic CV and cover-letter template presets; use layered templates. Source: llm_adapter@2026-07-15 Confidence: high |
— |
| Breaking | High |
Removed standalone BusinessTheme design-token bundle; use explicit DocumentColor/DocumentTextStyle. Removed standalone BusinessTheme design-token bundle; use explicit DocumentColor/DocumentTextStyle. Source: llm_adapter@2026-07-15 Confidence: high |
— |
| Breaking | High |
Removed DSL name-aliases DocumentSession.builder() and DocumentDsl.text(); use builder() and paragraph(). Removed DSL name-aliases DocumentSession.builder() and DocumentDsl.text(); use builder() and paragraph(). Source: llm_adapter@2026-07-15 Confidence: high |
— |
| Breaking | High |
Removed PDF‑typed document‑chrome overloads on DocumentSession; use backend‑neutral metadata/watermark/protect/header/footer. Removed PDF‑typed document‑chrome overloads on DocumentSession; use backend‑neutral metadata/watermark/protect/header/footer. Source: llm_adapter@2026-07-15 Confidence: high |
— |
| Breaking | High |
Removed linkOptions() accessor; use linkTarget() and ExternalLinkTarget.options(). Removed linkOptions() accessor; use linkTarget() and ExternalLinkTarget.options(). Source: llm_adapter@2026-07-15 Confidence: high |
— |
| Breaking | High |
Removed dormant ECS engine internals (EntityManager, SystemECS, Entity components, render pipeline). Removed dormant ECS engine internals (EntityManager, SystemECS, Entity components, render pipeline). Source: llm_adapter@2026-07-15 Confidence: high |
— |
| Breaking | High |
Package rename: layered template packages dropped `.v2` suffix; update imports. Package rename: layered template packages dropped `.v2` suffix; update imports. Source: llm_adapter@2026-07-15 Confidence: high |
— |
| Feature | Medium |
Added reproducible PDF output (`@Beta`) via PdfFixedLayoutBackend.builder().deterministic(). Added reproducible PDF output (`@Beta`) via PdfFixedLayoutBackend.builder().deterministic(). Source: llm_adapter@2026-07-15 Confidence: high |
— |
| Feature | Low |
Multi‑section documents support reproducible PDF via MultiSectionDocument.toPdfBytes() and writePdf(). Multi‑section documents support reproducible PDF via MultiSectionDocument.toPdfBytes() and writePdf(). Source: granite4.1:30b@2026-07-15-audit Confidence: low |
— |
| Deprecation | Medium |
Removed unused Font.adjustFontSizeToFit(...) method; text auto‑sizing handled by layout compiler. Removed unused Font.adjustFontSizeToFit(...) method; text auto‑sizing handled by layout compiler. Source: llm_adapter@2026-07-15 Confidence: high |
— |
| Refactor | Low |
Split monolithic engine into modules: graph-compose-core, graph-compose-render-pdf, graph-compose-templates, etc. Split monolithic engine into modules: graph-compose-core, graph-compose-render-pdf, graph-compose-templates, etc. Source: llm_adapter@2026-07-15 Confidence: high |
— |
| Refactor | Low |
Bounded process-wide image caches with LRU eviction to prevent unbounded memory growth. Bounded process-wide image caches with LRU eviction to prevent unbounded memory growth. Source: granite4.1:30b@2026-07-15-audit Confidence: low |
— |
Full changelog
[!NOTE]
Documentation clarificationGraphCompose
v2.0.0is the current stable, module-first release. For the drop-in PDF-capable setup, useio.github.demchaav:graph-compose:2.0.0. For a lean setup with an explicitly selected backend, usegraph-compose-core.The
README.mdpreserved inside this immutable tag still contains an outdated status line namingv1.9.1as the latest stable release. The tagged code, Maven coordinates, and release itself are2.0.0.The tag has intentionally not been modified or force-moved. For current documentation, see the
mainbranch, the module selection guide, and the 2.0 migration guide.
v2.0.0 — 2026-07-13
The 2.0 development line. Binary-breaking by design — japicmp runs report-only
for this cycle.
Removed
- The classic (pre-layered) CV and cover-letter template presets have been removed.
The layered template stack —templates.cv.*,templates.coverletter.*,
templates.invoice.*, andtemplates.proposal.*, all onBrandTheme— is now the
single template surface. - The standalone
BusinessThemedesign-token bundle (and itsDocumentPalette/
SpacingScale/TextScale/TablePresetcompanions) is no longer part of the
library. It lives on only as a styling helper inside the examples module; author
documents with explicitDocumentColor/DocumentTextStylevalues or a template
BrandTheme. - The DSL name-aliases
DocumentSession.builder()andDocumentDsl.text()have been
removed. UseDocumentSession.dsl()andDocumentDsl.paragraph(). - The PDF-typed document-chrome overloads on
DocumentSession—
metadata(PdfMetadataOptions),watermark(PdfWatermarkOptions),
protect(PdfProtectionOptions),header(PdfHeaderFooterOptions)and
footer(PdfHeaderFooterOptions)— have been removed in favour of the canonical,
backend-neutral overloads (metadata(DocumentMetadata),watermark(DocumentWatermark),
protect(DocumentProtection),header(DocumentHeaderFooter),
footer(DocumentHeaderFooter)). The PDF option types remain available on
PdfFixedLayoutBackend.builder()for advanced backend-level configuration. - The
linkOptions()accessor on the document nodes and inline runs (paragraph, table,
image, shape, ellipse, line, barcode, and the inline image / shape / text runs) has
been removed. UselinkTarget()and read the external URI from
ExternalLinkTarget.options(). - The unused engine-internal
Font.adjustFontSizeToFit(...)(and itsPdfFont/
WordFontimplementations) has been removed; text auto-sizing is resolved by the
layout compiler. - The dormant Entity-Component-System engine internals have been removed: the
EntityManager/SystemECSruntime, theEntitycomponent model with its
geometry / coordinator / renderable companions, the ECS render pipeline
(engine.render.*and the guide renderers underengine.render.guides), and
LayoutSnapshotExtractor. None were reachable from the live render path —
DocumentSession→ layout compiler → fixed-layout backend — so document layout,
PDF output, and the publicguideLines(...)overlay are unchanged.
Public API
- Reproducible PDF output (
@Beta).PdfFixedLayoutBackend.builder().deterministic(true)
(or.deterministic(Instant)for an explicit timestamp) pins the document
CreationDate / ModDate and derives the PDF/IDfrom the document metadata instead
of PDFBox's time-seeded default, so the same document renders to byte-identical PDF
bytes across runs — for reproducible builds and byte-level output tests. Off by
default (output keeps the live timestamp and/ID). PDF encryption viaprotect(...)
can reintroduce randomness (AES-256 uses random salts), so an encrypted document is
not byte-reproducible even with this enabled. Multi-section documents opt in through
the newMultiSectionDocument.toPdfBytes(FixedLayoutRenderer)/
writePdf(FixedLayoutRenderer, OutputStream)overloads — the multi-section
counterpart ofDocumentSession.render(backend). - The layered template packages dropped their
.v2suffix:
com.demcha.compose.document.templates.<family>.v2.*→
com.demcha.compose.document.templates.<family>.*forcv,coverletter,
invoice, andproposal. Update imports accordingly — behaviour and rendering are
unchanged; this is a package rename only.
Packaging
- 2.0 splits the monolithic engine into modules. The engine now builds under a new
graph-compose-corecoordinate, and the originalgraph-composecoordinate
becomes a thin drop-in aggregator that depends ongraph-compose-core— so an
existinggraph-composedependency keeps compiling and rendering PDF unchanged.
Consumer-testing support (graph-compose-testing) and the semantic DOCX / PPTX
backends (graph-compose-render-docx/graph-compose-render-pptx) are already
separate artifacts; the PDF render backend now lives in
graph-compose-render-pdf, which thegraph-composewrapper aggregates so a
baregraph-composestill renders PDF, whilegraph-compose-corealone is lean
(it throwsMissingBackendExceptionif asked to render without a backend). The
built-in templates now ship ingraph-compose-templates(opt-in; the
graph-composewrapper does not bundle them). The
optionalgraph-compose-fonts/graph-compose-emojiartifacts are unchanged.
Full install guidance ships with 2.0.0. graph-compose-render-pdfis a separate artifact: the entire PDFBox backend —
document.backend.fixed.pdf.**and theengine.render.pdf.**render tree — plus
PDFBox, zxing (barcodes), and the commons-logging→SLF4J bridge leave
graph-compose-core. The core keeps theDocumentSessionAPI and the
ServiceLoaderseam (FixedLayoutBackendProvider/FontMetricsProvider); the
PDF provider ships in render-pdf and is discovered at runtime. Depend on
graph-compose(orgraph-compose-render-pdfdirectly) for PDF; a bare
graph-compose-corerenders nothing until a backend is on the classpath.graph-compose-templatesis a separate artifact: the built-in CV, cover-letter,
invoice, and proposal templates (document.templates.**) leave the engine. They
are pure authoring code over the canonical DSL, so the module depends only on
graph-compose-core. Addgraph-compose-templatesfor the ready-made presets; a
consumer that used them throughgraph-composebefore must now add this artifact
(thecom.demcha.compose.document.templates.**packages are unchanged).- The semantic office backends are separate artifacts and Apache POI leaves the
engine:DocxSemanticBackendships ingraph-compose-render-docx(which brings
POI transitively — add it to export DOCX), andPptxSemanticBackendships in its
owngraph-compose-render-pptx(a POI-free skeleton for now — add it for the
slide-safe semantic manifest). Their packages —
com.demcha.compose.document.backend.semantic.{docx,pptx}— are unchanged. The
no-poibuild profile is retired. graph-compose-testingis now a separate artifact: the consumer testing
support —LayoutSnapshotAssertions(deterministic layout snapshots) and
PdfVisualRegression(pixel-diff of rendered pages) — leaves the
graph-composejar together with its Jackson and PDFBox dependencies. The
com.demcha.compose.testing.layout/com.demcha.compose.testing.visual
packages are unchanged, so imports stay the same; addgraph-compose-testing
at test scope to keep using them.graph-compose-bundleis the batteries-included aggregate for the split layout:
one dependency pulls the default PDF stack (graph-compose= core + render-pdf),
the built-in templates (graph-compose-templates), the bundled Google fonts, and
the colour-emoji set at compatible pinned versions. The office backends
(graph-compose-render-docx/graph-compose-render-pptx) stay opt-in and are not
bundled.
Internal
- The process-wide image caches (decoded source bytes and image metadata) are now
bounded with LRU eviction instead of growing without limit. A long-lived JVM that
renders many distinct images — a rendering service, a batch job — no longer
accumulates image data indefinitely. Single documents are unaffected: the caps sit
far above any realistic distinct-image count, so a render never evicts or re-decodes.
Build
- Added report-only cross-module code coverage. A new non-published
graph-compose-coveragemodule runs JaCoCoreport-aggregateover the engine, the
PDF backend, and the built-in templates plus thegraph-compose-qacross-module
suites, so each module's coverage counts the tests that actually exercise it (a
single-module report undercounts, because much of the production code is driven from
qa at test scope). CI publishes the HTML/XML report as an artifact; no coverage
threshold is enforced yet.
Documentation
- Documented that text is laid out left-to-right only: bidirectional (RTL) reordering
and complex-script shaping (Arabic joining, Indic reordering) are not performed. Added
to the README support matrix. - The 2.0 module migration guide now lists the API changes it previously delegated to the
changelog — the.v2package rename, theBusinessThemeremoval, the retired classic
presets, andFont.adjustFontSizeToFit— each with its migration action.
Breaking Changes
- Removed classic (pre‑layered) CV, cover‑letter, invoice, and proposal template presets; all templates now use the layered stack on `BrandTheme`.
- Removed standalone `BusinessTheme` design‑token bundle from the library; it remains only in example code.
- Removed DSL name aliases `DocumentSession.builder()` and `DocumentDsl.text()`. Use `DocumentSession.dsl()` and `DocumentDsl.paragraph()`.
- Removed PDF‑typed overloads on `DocumentSession`: `metadata(PdfMetadataOptions)`, `watermark(PdfWatermarkOptions)`, `protect(PdfProtectionOptions)`, `header(PdfHeaderFooterOptions)`, `footer(PdfHeaderFooterOptions)`. Use backend‑neutral equivalents (`metadata(DocumentMetadata)`, etc.).
- Removed `linkOptions()` accessor on document nodes and inline runs. Use `linkTarget()` with `ExternalLinkTarget.options()`.
- Removed internal engine utilities: `Font.adjustFontSizeToFit(...)`, the dormant ECS internals (`EntityManager`, `SystemECS`, layout pipeline, snapshot extractor).
- Split monolithic artifact into modules; `graph-compose` now depends on `graph-compose-core` and aggregates backends/templates. Consumers must adjust dependencies (e.g., add `graph-compose-render-pdf` for PDF rendering, `graph-compose-templates` for built‑in templates).
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.
Share this release
About GraphCompose 2.0
All releases →Related context
Related tools
Beta — feedback welcome: [email protected]