Releases: d2lang/d2
Releases · d2lang/d2
Release list
v0.9.0
Immutable
release. Only release title and notes can be modified.
Features 🚀
- TALA is now open source and bundled with D2, including the JavaScript/WASM package. Select it with
d2 --layout=tala,D2_LAYOUT=tala, orvars.d2-config.layout-engine: tala. No separate plugin installation or license key is required. - tala: configure layout attempts with
--tala-seeds,D2_TALA_SEEDS, orvars.d2-config.data.tala-seeds. - exports: render PNG, GIF, PDF, and PPTX with the built-in renderer
Improvements 🧹
- performance: reduce repeated work in Dagre ranking, text measurement, SVG preparation, and PNG encoding
- performance: reduce repeated work in selective imports, dynamic grid layout, and PNG connection rendering
- exports: reduce PNG memory usage and support images above the previous 67-megapixel limit
- performance: SVG rendering is approximately 10× faster across the E2E corpus. Real-world diagrams compile, lay out, and render approximately 3× faster at the median.
- renders: SVG exports are approximately 24% smaller across the E2E corpus and 18% smaller across real-world fixtures, with unchanged appearance.
- renders: render Markdown labels as native SVG instead of HTML
foreignObjectcontent
Bugfixes ⛑️
- install: reject the obsolete
--talainstaller flag with migration guidance before installing, instead of incorrectly claiming that older D2 releases bundle TALA - sequence diagrams: keep synthetic lifeline endpoint IDs stable across architectures
- exports: honor
D2_TIMEOUTduring PNG and GIF rendering - compiler: keep recursive globs out of class and variable definitions and report class reference cycles instead of overflowing the stack
- renders: decode gzip, Brotli, and deflate remote images before embedding them
For the latest d2.js changes, see separate changelog.
v0.8.2
Features 🚀
- exports: gif exports work with
animate: truekeyword #2663
Improvements 🧹
- releases: strip native binaries, build and smoke-test all six archives in CI, produce reproducible archives with checksums, signed provenance, and SBOM attestations, and verify standalone downloads when GitHub provides a digest
- plugins: make render post-processing optional and deprecate it for removal after one protocol compatibility cycle; legacy external
postprocesscommands remain supported during the transition - api: deprecate legacy layout-feature constants, raw-WASM ELK/object-order bridges, unused public wrappers, and test-only comparison, validation, and logging helpers; compatibility entry points remain callable for one release while in-repository callers use supported or internal replacements
- maintenance: update the Go toolchain to 1.27.0 and refresh Go, d2.js, CI, release dependencies, and compression-sensitive snapshots
- renders: update syntax highlighting and migrate archived font and PDF dependencies to maintained replacements
- d2dagre: replace the embedded JavaScript runtime with native Go Dagro and update its D2-used layout surface from Dagre 0.8.5 to Dagre 3.1.1 behavior. This intentionally changes node ordering and coordinates, edge routes, self-loops, and compound sizing in some diagrams; regenerate and review stored SVG or board-JSON snapshots
- d2sketch: update the native rough-go renderer from Rough.js 4.0.4 to 4.6.6 behavior. Seeded sketch strokes, fills, arrowheads, and SVG paths may change; regenerate and review stored sketch SVG snapshots
- d2elk: replace the embedded ELK.js 0.8.2 runtime with native Go elk-go and update D2's ELK layout profile to ELK.js 0.12.0 behavior. This is a layout-behavior update, not an output-compatible runtime swap:
- existing ELK diagrams may receive different node coordinates and ordering, edge and label routes, and component packing; regenerate and review stored SVG or board-JSON snapshots
- children of nested compound graphs may be reordered because ELK 0.12 cannot safely apply D2's previous nested model-order profile
- non-default
--elk-algorithmmodes may also produce different geometry; the optional DisCo algorithm is removed because upstream no longer bundles it
- d2latex: replace the embedded MathJax JavaScript runtime with the native Go mathjax-go port without changing rendered formulas
- performance: native Go engine migrations substantially reduce median end-to-end D2-to-SVG conversion time in Apple M4 benchmarks:
- Dagre is 7–9× faster
- ELK is 40–53× faster
- LaTeX is 21.6× faster on a four-formula diagram
- performance: remove superlinear compiler and layout bottlenecks in large globs, repeated imports, nested diagrams, compound Dagre graphs, bend-heavy ELK layouts, and style-only scenario/step boards #2827. Median Apple M4 single-CPU synthetic stress benchmarks for these targeted cliffs, rather than corpus-wide conversion averages, improve by:
- leading glob applied to 1,000 fields: 1.59s to 12ms (~133× faster)
- 100 references into the same 100-field import file: 54ms to 12ms (~4.6× faster)
- 4,000 flat fields: 67ms to 7ms (~9.6× faster)
- 3,200 distinct edges: 200ms to 19ms (~10.6× faster)
- 32-node base with 8 style-only scenarios and 8 steps (17 boards total): 40ms to 7.3ms (~5.5× faster)
- 340-object nested D2 Dagre layout: 1.30s to 0.88s (~32% faster)
- Dagro depth-100 compound layout: 3.60s to 0.90s (~4× faster)
- 250-node, 1,000-edge ELK layout: 337ms to 238ms (~30% faster)
- d2ascii:
- exports:
- renders:
- remote images are fetched more reliably #2659
Bugfixes ⛑️
- d2dagre: keep same-direction parallel edges and self-loop routes finite when using Dagre 3.1.1 behavior
- d2svg: reject padding that would produce invalid negative SVG dimensions
- d2elk: route ancestor-to-descendant connections around intermediate containers
- d2elk: prevent labels on multiple self-loops from overlapping in right-directed layouts, including the
ent2d2_rightregression case - d2svg: render one-stop gradients with finite SVG offsets
- compiler: make suffix globs match only names with the requested suffix
- compiler: reject non-finite opacity values with a source diagnostic
- d2svg: preserve connection links on LaTeX, Markdown, and code labels
- d2lib: preserve caller-supplied light and dark theme overrides over source configuration
- compiler: index equivalent connections consistently when endpoint notation is reversed
- exports: pptx follows standards more closely, addressing warnings from some Powerpoint software #2645
- d2sequence: fix edge case of invalid sequence diagrams #2660
- d2svg: Text may overflow legend bounds when monospace font is used #2674
For the latest d2.js changes, see separate changelog.
v0.7.1
Features 🚀
- ASCII renders. Output
txtfor d2 to render diagrams as ASCII art #2572 crossarrowhead shape is available #2190style.underlinesupport for class fields and methods #2544- markdown, latex, and code can be used as edge labels #2545
- border-x label positioning functionality #2549
- tooltips with
nearset always show even without hover #2564 - CLI supports customizing monospace fonts with
--font-mono,--font-mono-bold,--font-mono-italic, and--font-mono-semiboldflags #2590
Improvements 🧹
- labels on scenario/step boards can be set with primary value (like layers) #2579
- autoformatter preserves order of boards #2580
- rename "Legend" with a title/label of your choosing (especially useful for non-English diagrams) #2582
- sketch mode fonts will use custom fonts if provided #2582
Bugfixes ⛑️
- actors in sequence diagrams with labels and icons together no longer overlap, position keywords now work too #2548
- fix double glob behavior in scenarios (wasn't propagating correctly) #2557
- fix diagram bounding box not accounting for legend in some cases #2584
Breaking Changes
- If you are using D2 as a library/API, passing in a FontFamily with
sketchrenders will now use the font, instead of previously ignoring it.
For the latest d2.js changes, see separate changelog.
v0.7.0
Features 🚀
- Icons:
- connections can include icons #12
- Syntax:
suspend/unsuspendto define models and instantiate them #2394
- Globs:
- Render:
- Icons:
- border-radius should work on icon #2409
- Misc:
- Diagram legends are implemented #2416
Improvements 🧹
- CLI:
- Compiler:
- Parser:
- impose max key length. It's almost certainly a mistake if an ID gets too long, e.g. missing quotes #2465
- Render:
- horizontal padding added for connection labels #2461
Bugfixes ⛑️
- Compiler:
- fixes panic when
sql_shapeshape value had mixed casing #2349 - fixes panic when importing from a file with spread substitutions in
vars#2427 - fixes support for
centerind2-config#2360 - fixes panic when comment lines appear in arrays #2378
- fixes inconsistencies when objects were double quoted #2390
- fixes globs not applying to spread substitutions #2426
- fixes panic when classes were mixed with layers incorrectly #2448
- fixes panic when gradient colors are used in sketch mode #2481
- fixes panic using glob ampersand filters with composite values #2489
- fixes leaf ampersand filter when used with imports #2494
- fixes panic when
- Formatter:
- fixes substitutions in quotes surrounded by text #2462
- CLI:
- fetch and render remote images of mimetype octet-stream correctly #2370
- Composition:
- Markdown:
- fixes nested var substitutions not working #2456
For the latest d2.js changes, see separate changelog.
v0.6.9
Features 🚀
- Animations:
style.animated: trueis supported on shapes #2250 - Connections now support
link#1955 - Vars: vars in markdown blocks are substituted #2218
- Markdown: Github-flavored tables work in
mdblocks #2221 - Render: adds box arrowheads #2227
d2 fmtnow supports a--checkflag #2253- CLI: PNG output to stdout is supported using
--stdout-format png -#2291 - Globs:
&connectedand&leaffilters are implemented #2299 - CLI: add --no-xml-tag for direct HTML embedding #2302
- CLI:
playcmd added for opening d2 input in online playground #2242
Improvements 🧹
- Composition: links pointing to own board are purged #2203
- Syntax: reserved keywords must be unquoted #2231
- Latex: Backslashes in Latex blocks do not escape #2232
- This is a breaking change. Previously Latex blocks required escaping the backslash. So
for older D2 versions, you should remove the excess backslashes.
- This is a breaking change. Previously Latex blocks required escaping the backslash. So
- Links: non-http url scheme links are supported (e.g.
x.link: vscode://file/) #2237 - Compiler: reserved keywords with missing values error instead of silently doing nothing #2251
- Render: SVG outputs conform to stricter HTML standards, e.g. no duplicate ids #2273
- Themes: theme names are consistently cased #2322
- Nears: constant nears avoid collision with edge routes #2327
Bugfixes ⛑️
- Imports: fixes using substitutions in
iconvalues #2207 - Markdown: fixes ampersands in URLs in markdown #2219
- Globs: fixes edge case where globs with imported boards would create empty boards #2247
- Sequence diagrams: fixes alignment of notes when self messages are above it #2264
- Null: fixes
nulling a connection with absolute syntax #2318 - Gradients: works with connection fills #2326
- Latex: fixes backslashes doubling on successive parses #2328
v0.6.8
Features 🚀
- Render: SVG files render in non-browser contexts (e.g. Inkscape, LaTeX) #2147
Improvements 🧹
- Lib: removes a dependency on external slog that was causing troubles with installation #2137
- CLI: attempts writing to path atomically, falling back to non-atomic if failed #2141
- Export: pptx has "created at" metadata removed, so successive runs yield the same result #2169
- Formatter: empty board keywords (e.g.
layers) are removed #2178 - Render: a tooltip or link by itself will not expand width of shape #2183
Bugfixes ⛑️
v0.6.7
Features 🚀
- Vars: Variable definitions can refer to other variables in the current scope #2052
- Composition: Imported boards can use underscores to reference boards beyond its own scope (e.g. to a sibling board at the scope its imported to) #2075
- Autoformat: Reserved keywords are formatted to be lowercase #2098
- Misc: support for characters in the Latin-1 and geometric shapes unicode range #2100
- Imports: can now import from absolute file paths #2113
- Render: linear and radial gradients are now available for
fill,strokeandfont-color#2120
Improvements 🧹
- Sequence diagram: edge groups account for edge label heights #2038
- Sequence diagram: self-referential edges account for edge label heights #2040
- Sequence diagram: The spacing between self-referential edges and regular edges is uniform #2043
- Compiler: Error on multi-line labels in
sql_tableshapes #2057 - Sequence diagram: Image shape actors can use spans and notes #2056
- Globs: Filters work with default values (e.g.
&opacity: 1will capture everything without opacity explicitly set) #2090 - Render: connection label fills have a bit of padding and border-radius for better aesthetics #2094
- Sequence diagram: the padding between message labels and message endpoints are slightly increased #2096
- Render: code syntax highlighter dependency upgrade caused some slight subtle color changes in code snippets #2119
Bugfixes ⛑️
- Sequence diagram: multi-line edge labels no longer can collide with other elements #2049
- Sequence diagram: long self-referential edge labels no longer can collide neighboring actors (or its own) lifeline edges #2050
- Sequence diagram: fixes layout when sequence diagrams are in children boards (e.g. a layer) #1692
- Globs: An edge case was fixed where globs used in edges were creating nodes when it shouldn't have #2051
- Render: Multi-line class labels/headers are rendered correctly #2057
- CLI: Watch mode uses correct backlinks (
_usages) #2058 - Vars: Spread variables are inserted in place instead of appending to end of scope #2062
- Imports: fix local icon imports from files that are imported #2066
- CLI: fixes edge case of watch mode links to nested board that had more nested boards not working #2070
- CLI: fixes theme flag not being passed to GIF outputs #2071
- CLI: fixes scale flag not being passed to animated SVG outputs #2071
- CLI: pptx exports use theme flags correctly #2099
- Imports: importing files with url links is fixed #2105
- Composition: linking to invalid boards no longer produces an invalid link #2118
v0.6.6
Features 🚀
- Glob inverse filters are implemented (e.g.
*: {!&shape: circle; style.fill: red}to turn all non-circles red) #2008 - Globs can be used in glob filter values, including checking for existence (e.g.
*: {&link: *; style.fill: red}to turn all objects with a link red) #2009
Improvements 🧹
- Opacity 0 shapes no longer have a label mask which made any segment of connections going through them lower opacity #1940
- Bidirectional connections are now animated in opposite directions rather than one direction #1939
Bugfixes ⛑️
- Local relative icons are relative to the d2 file instead of CLI invoke path #1924
- Custom label positions weren't being read when the width was smaller than the label #1928
- Using
shape: circlefor arrowheads no longer removes all arrowheads along path in sketch mode #1942 - Globs to null connections work #1965
- Edge globs setting styles inherit correctly in child boards #1967
- Board links imported with spread imports work #1972
- Fix importing a file with nested boards #1998
- Fix importing a file with underscores in links #1999
- Replace a panic with an error message resulting from invalid
linkusage #2011 - Fix globs not applying to scenarios on keys that were applied in earlier scenarios #2021
- Fix edge case of invalid SVG from code blocks #2031
v0.6.5
D2 0.6.5 has a hotfix for 0.6.4 breaking plugin compatibility. Also includes 2 compiler fixes regarding substitutions/vars.
Bugfixes ⛑️
v0.6.4
Features 🚀
style.underlineworks on connections #1836noneis added as an accepted value forfill-pattern. Previously there was no way to cancel thefill-patternon select objects set by a theme that applies it (Origami) #1882
Improvements 🧹
- Dimensions can be set less than label dimensions #1901
- Boards no longer inherit
labelfields from parents #1838 - Prevents
neartargeting a child of a special object like grid cells, which wasn't doing anything #1851
Bugfixes ⛑️
- Theme flags on CLI apply to PDFs #1894
- Fixes styles in connections not overriding styles set by globs #1857
- Fixes
nullbeing set on a nested shape not working in certain cases when connections also pointed to that shape #1830 - Fixes edge case of bad import syntax crashing using d2 as a library #1829
- Fixes
style.fillnot applying to markdown #1872 - Fixes compiler erroring on certain styles when the shape's
shapevalue is not all lowercase (e.g.Circle) #1887