Excalidraw CLI

Render to PNG or SVG

Render local files and workspace scenes to PNG or SVG with the browser you already have.

render turns a local file into a PNG or SVG, no API key needed. scenes render does the same for a scene in your workspace.

excalidraw render drawing.excalidraw --out drawing.png
excalidraw render drawing.excalidraw --out drawing.svg --theme dark
cat drawing.excalidraw | excalidraw render - --out drawing.png
excalidraw scenes render <sceneId> --frame-id <frameId> --out frame.png

The format follows the --out extension, .png or .svg, or --format. SVGs embed the fonts their text uses, cut down to the characters it needs, so they look the same wherever they're opened.

--all-frames renders each frame to its own file, for example a deck's slides. Files are numbered in presentation order and named after their frames, and the command prints them as JSON:

excalidraw scenes render <sceneId> --all-frames --out slides/
# slides/01-title.png, slides/02-agenda.png, ...

With a file path, the command prints the image's path and dimensions as JSON. Pass --out - to write the image to stdout instead, for example to pipe it into another program. stdout then carries only the PNG bytes or SVG markup, even with --raw or --output table, and errors and retry notices go to stderr:

node generate-scene.js | excalidraw render - --out - > drawing.png
excalidraw scenes render <sceneId> --out - | magick png:- -resize 50% preview.png

Rendering uses a browser that's already installed: Chrome, Edge or Chromium, or Firefox if none of those is. Firefox is slower: a render takes about 5 s instead of under 1 s. The CLI doesn't download a browser. If it can't find yours, pass --browser-path or set EXCALIDRAW_BROWSER_PATH; a binary named firefox is driven as Firefox. The browser runs with a temporary profile, and scenes render never passes your API key to it.

OptionDefaultNotes
--out <file>requiredFile path, or - for stdout. A directory with --all-frames.
--format <png|svg>--out extension, else png
--frame-id <id>Render just this frame.
--all-framesoffRender each frame to its own file in the --out directory.
--scale <n>1Resolution multiplier, up to 16.
--max-width, --max-height16384Shrink the PNG to fit these sizes in pixels.
--padding <px>20Ignored for frames.
--theme <light|dark>scene setting
--transparentoffTransparent background.
--timeout <ms>30000How long a render may take, per frame with --all-frames.
  • Images must be embedded in the file. Image URLs and website embeds aren't loaded.
  • PNGs keep the scene's aspect ratio and stay under 64 megapixels. When a limit makes a PNG smaller than --scale asks for, the command prints a warning. SVGs have no size limit.
  • Chinese, Japanese and Korean text in the hand-drawn font, Excalifont, is drawn in Xiaolai, which is downloaded the first time a scene uses it, then cached. Without network access, that text uses a system font. As in Excalidraw itself, CJK text in the other fonts, such as Virgil or Comic Shanns, always uses a system font. See CJK fonts for proxies, mirrors and offline use.
  • Emoji come from your system's fonts.

CJK fonts

The CLI downloads Xiaolai's files from Excalidraw's CDN and checks each against its SHA-256. When the CDN fails or doesn't answer in time, it tries npmmirror, then jsDelivr. If every download fails, the command still renders and prints a warning naming the reason.

  • Behind a proxy, set HTTPS_PROXY (or HTTP_PROXY) as you would for curl; a value without a scheme, such as proxy.corp:8080, is an HTTP proxy. NO_PROXY lists hosts to reach directly. This applies to API requests and the update check too. socks5:// URLs work as well, though Node prints a warning that its SOCKS support is experimental. Other proxies, such as socks4://, are skipped with a warning.
  • --fonts-url (or EXCALIDRAW_FONTS_URL) replaces the download locations with your own: comma-separated URLs that mirror @excalidraw/excalidraw@0.18.1's dist/prod/ folder, or none to turn downloads off.
  • For offline use, point --fonts-url at a local copy of that folder. Files are read from it directly, not copied to the cache:
mkdir -p ~/excalidraw-fonts && cd ~/excalidraw-fonts
npm pack @excalidraw/excalidraw@0.18.1 --registry https://registry.npmmirror.com
tar -xzf excalidraw-excalidraw-0.18.1.tgz
export EXCALIDRAW_FONTS_URL=~/excalidraw-fonts/package/dist/prod

Last updated on