Stop exporting SVGs by hand: script Inkscape CLI for reproducible PNGs
Use Inkscape's 1.x headless CLI with explicit export flags to replace manual SVG to PNG/PDF exports with a reproducible, scriptable asset pipeline.
17 Oct 2025, 04:41 UTC

Designers finish an icon set in Inkscape, then someone exports PNGs by hand for web, docs, and the release notes. A week later the PNGs drift from the SVGs because a different DPI, page margin, or background was used. The useful takeaway is to treat SVG export as code: run Inkscape headless with explicit flags so the same command produces the same raster assets on a laptop and in CI.
The reproducibility problem with GUI exports
Manual export hides parameters. DPI, canvas vs drawing bounds, and transparent background are choices made in a dialog and rarely recorded. When the source SVG changes, the old PNGs stay around, or a new export uses different defaults. For teams that want deterministic assets, the export step needs to be declarative and versioned.
Inkscape 1.x ships a non-interactive CLI that loads an SVG, renders it with Inkscape's own engine, writes the output, and exits without opening the GUI. That makes it usable from Makefiles, npm scripts, and CI jobs.
1.x CLI flags that cover real export cases
The 1.x command line replaced the 0.9x verbs. Old flags like --export-png and --without-gui no longer apply. The current pattern is --export-filename, --export-type, and sizing controls.
- --export-type png or pdf selects the raster or vector target. --export-filename sets the output path.
- --export-dpi sets raster resolution. --export-width and --export-height set exact pixel dimensions, which is useful for 1x/2x sets.
- --export-area-drawing crops to the artwork bounds instead of the full page. --export-background and --export-background-opacity control transparency.
Run inkscape --version and inkscape --help on the build machine first. The flags above exist only on Inkscape 1.x. Legacy 0.9x installs will reject them.
A minimal reproducible export rule
The following Make rule is intended to be placed in a project root where icons/*.svg exists and a build/ directory is writable. It requires inkscape in PATH and read access to the SVGs and write access to build/.
# Makefile
INKSCAPE ?= inkscape
SRC := icons
DST := build/icons
PNG1 := $(DST)/1x
PNG2 := $(DST)/2x
$(shell mkdir -p $(PNG1) $(PNG2))
$(PNG1)/%.png $(PNG2)/%.png: $(SRC)/%.svg
$(INKSCAPE) $< \
--export-type png \
--export-filename $@ \
--export-area-drawing \
--export-background none
For a 2x variant you would add a width multiplier, for example --export-width 256 for a 128px source, keeping the aspect ratio. A shell loop with the same flags can be used when Make is not desired.
Expected checks after a run: the output files exist under build/icons/1x and 2x, and their names match the source SVGs. A practical verification is to export one file via the GUI with the same DPI and area settings, then compare pixel dimensions of the two PNGs. Differences usually point to font substitution or a version mismatch.
Limits you should plan for
Headless export preserves Inkscape's renderer, which is good for fidelity to what a designer sees, but Inkscape startup is heavier than dedicated rasterizers. Do not assume speed parity.
Text rendering depends on locally installed fonts. If an SVG contains live text, a CI container without the designer's fonts will substitute, changing metrics and appearance. Pin fonts in the build image or convert text to paths for fully deterministic output.
Version sensitivity matters. The 1.x flags will fail on 0.9x. Test the script in a clean container without design-machine fonts to surface substitution before relying on it in CI.
Batching helps. Passing multiple files to one inkscape invocation reduces startup overhead compared with launching once per file. The exact batch syntax is version dependent, so confirm with --help on the target release.
Close the loop
Commit the export rule and the flag set alongside the SVGs. Treat the generated PNGs as build artifacts rather than checked-in binaries unless you need them for a release package. Document the required Inkscape version and font packages in the README so a new contributor can reproduce the assets without opening the GUI.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.