Combine multiple .excalidraw files into a single image, placed side by side or stacked vertically.
The excalirender combine command renders each input file independently and composes the results onto a single output canvas. Each file keeps its native dimensions — panels are not resized to match each other.
Output formats: PNG and PDF.
# Side by side (default horizontal layout)
excalirender combine a.excalidraw b.excalidraw
# Custom output path
excalirender combine a.excalidraw b.excalidraw -o comparison.png
# Vertical layout (stacked)
excalirender combine a.excalidraw b.excalidraw --layout vertical
# Show filename labels below each panel
excalirender combine a.excalidraw b.excalidraw --labels
# Custom gap, dark mode
excalirender combine a.excalidraw b.excalidraw --gap 60 --dark
# Three or more files
excalirender combine a.excalidraw b.excalidraw c.excalidraw --labels
# PDF output
excalirender combine a.excalidraw b.excalidraw -o output.pdf
# Scale 2x
excalirender combine a.excalidraw b.excalidraw --scale 2
# Write to stdout
excalirender combine a.excalidraw b.excalidraw -o - > output.png| Option | Description | Default |
|---|---|---|
-o, --output <path> |
Output file path (.png or .pdf) | combined.png |
-l, --layout <type> |
Layout: horizontal or vertical |
horizontal |
--gap <pixels> |
Gap between panels in pixels | 40 |
--labels |
Show filename labels below each panel | false |
-s, --scale <number> |
Export scale factor | 1 |
-d, --dark |
Enable dark mode export | false |
--transparent |
Transparent background (no fill) | false |
--format <type> |
Output format when using stdout (-o -) |
png |
Panels are placed left to right with a configurable gap between them.
- Total width = sum of all panel widths + gap × (panel count − 1)
- Total height = max panel height (including label height if enabled)
Panels are stacked top to bottom with a configurable gap between them.
- Total width = max panel width
- Total height = sum of all panel heights (including label height) + gap × (panel count − 1)
Gap and label height are scaled by the --scale factor to maintain proportions at higher resolutions.
When --labels is enabled, each panel displays its filename (without the .excalidraw extension) centered below the panel.
- Font: 14px sans-serif (scaled by
--scale) - Color:
#333333in light mode,#ccccccin dark mode - Padding: 4px above the label text (scaled)
src/combine.ts # Combine logic (exportCombined, CombineOptions)
src/cli.ts # CLI argument parsing for combine subcommand
src/index.ts # Combine routing and validation
| Function | File | Description |
|---|---|---|
exportCombined(inputPaths, options) |
combine.ts | Main entry point — renders and composes panels |
buildCombineArgs(files, opts) |
cli.ts | Builds CombineCLIArgs from CLI input |
interface CombineOptions {
outputPath: string;
layout: "horizontal" | "vertical";
gap: number;
labels: boolean;
scale: number;
darkMode: boolean;
transparent: boolean;
}- Prepare each file:
prepareExport()fromshared.tsparses the.excalidrawJSON, filters deleted elements, calculates bounds, and determines background color - Render to canvas:
renderElementsToCanvas()fromexport.tsdraws each file onto its own canvas using Rough.js and node-canvas - Calculate master dimensions: Based on layout, gap, and label height
- Compose: Create a master canvas and draw each panel at its calculated (x, y) offset using
ctx.drawImage() - Labels: If enabled, render filename text centered below each panel
- Write output: PNG via stream or PDF via Cairo PDF backend
For PDF output, each panel canvas is converted to a PNG buffer, loaded as an image, and drawn onto a PDF canvas. This avoids issues with cross-backend canvas drawing.
- PNG and PDF only: SVG output is not supported (would require complex nested SVG documents). GIF and
.excalidrawformats are also not supported. - No stdin: All input files must be file paths. Stdin (
-) is not supported since combine requires multiple inputs. - No resizing: Each panel keeps its native dimensions. Panels with very different sizes may produce uneven layouts.