drawio2tikz
drawio2tikz converts draw.io diagrams to TikZ code for embedding in LaTeX documents.
Features
- Converts either a single draw.io page or all pages
- Converts multiple draw.io files from the web UI
- Preserves label colors, bold text, font sizes, and simple line breaks
- Ignores draw.io font family names, allowing output to use the host LaTeX document font
- Removes draw.io SVG CSS that cannot be represented in TikZ, including
light-dark(...)from draw.io's dark mode color scheme - Restores draw.io labels emitted as SVG
foreignObjectelements, which draw.io exports as HTML fragments
Requirements
- Python 3.14 or newer
drawioCLI available onPATH(install from diagrams.net or via Homebrew:brew install --cask drawio)
Installation
pip / uv
Install from PyPI:
uv tool install drawio2tikz
Or with pip:
pip install drawio2tikz
Development Setup
Clone the repository and install in development mode:
git clone https://github.com/okayama-daiki/drawio2tikz.git
cd drawio2tikz
uv sync
uv run drawio2tikz --help
Usage
Basic Usage
Convert a single page from a draw.io file to TikZ:
drawio2tikz path/to/figure.drawio -o output_dir
This generates figure.tex in the output directory.
Convert All Pages
To convert all pages in a multi-page .drawio file:
drawio2tikz path/to/multipage.drawio --all-pages -o output_dir
Each page is saved as multipage-01.tex, multipage-02.tex, and so on.
Keep Intermediate SVG
To debug or inspect the intermediate SVG (after sanitization):
drawio2tikz path/to/figure.drawio -o output_dir --keep-svg --svg-dir output_dir/svg
View Help
drawio2tikz --help
Web App
Run the FastAPI web UI locally:
uv sync
uv run drawio2tikz-web
Then open http://localhost:8000.
The conversion API is available at POST /api/convert with multipart form data:
file: one or more.drawio,.drawio.png, or.xmlfilespage_index: 1-based page index, default1all_pages: convert every page, defaultfalsekeep_svg: include the sanitized intermediate SVG, defaultfalse
Docker
Build and run the web app:
docker build -t drawio2tikz .
docker run --rm -p 8000:8000 drawio2tikz
On Apple Silicon, build the amd64 image because the Dockerfile installs the draw.io Desktop .deb package:
docker build --platform linux/amd64 -t drawio2tikz .
docker run --rm --platform linux/amd64 -p 8000:8000 drawio2tikz
Cloud Run deployment
Pushes to main run the full CI suite and then deploy the amd64 container to the
drawio2tikz Cloud Run service in asia-northeast1. GitHub Actions authenticates with
Workload Identity Federation, so the repository does not store a Google Cloud service-account
key.
The deployment keeps Cloud Run at zero minimum instances, one maximum instance, and one concurrent request per instance. After Cloud Run imports the image, CI deletes the temporary Artifact Registry copy; a one-day cleanup policy handles interrupted runs as a fallback.
Cloud Run uses the dedicated drawio2tikz-runtime service account. It has no project-level role
and can access only the drawio2tikz-origin-auth Secret Manager secret. The GitHub deployer is
restricted to updating the existing Cloud Run service, pushing/deleting transient images in the
single Artifact Registry repository, and acting as that runtime service account. Its Workload
Identity Federation trust is limited to this repository's immutable GitHub ID and the main
branch.
The workflow expects these GitHub Actions repository variables:
GCP_WORKLOAD_IDENTITY_PROVIDERGCP_DEPLOY_SERVICE_ACCOUNT
Custom domain
The public custom domain is https://drawio2tikz.daiki.dev. A small Cloudflare Worker in
cloudflare/ streams requests to Cloud Run. Cloudflare manages the DNS record and TLS certificate
through a Worker Custom Domain configured once in the Cloudflare dashboard. The domain is
intentionally not declared in cloudflare/wrangler.jsonc, so CI cannot modify zone routes.
Cloudflare deployment expects these GitHub Actions repository secrets:
CLOUDFLARE_ACCOUNT_IDCLOUDFLARE_API_TOKENORIGIN_AUTH_TOKEN
The Cloudflare token needs only Account / Workers Scripts / Edit for the selected account; it
needs no zone permission. The origin token is installed as a Cloudflare Worker secret and a Cloud
Run Secret Manager reference. Direct requests to the public run.app URL are rejected without
that header.
Security
The web service limits each upload to 10 MiB, combined uploads to 20 MiB, requests to 10 files, draw.io documents to 50 pages, decompressed diagram XML to 20 MiB, and draw.io export processes to 120 seconds. XML parsing disables DTD and entity expansion. Browser responses carry a restrictive content security policy and related security headers.
The generated TikZ intentionally preserves raw TeX entered in draw.io labels. Treat output from untrusted diagrams as untrusted source code: inspect it before compiling and do not enable TeX shell escape for untrusted output.
LaTeX Setup
Add these packages to your LaTeX document preamble:
\usepackage{xcolor}
\usepackage{tikz}
\usepackage{amsmath}
Include the generated TikZ file:
\input{path/to/figure.tex}
For support of arbitrary large font sizes, use a scalable font:
\usepackage{mlmodern}
Example LaTeX Document
\documentclass{article}
\usepackage{xcolor}
\usepackage{tikz}
\usepackage{amsmath}
\usepackage{mlmodern}
\begin{document}
\section{My Diagram}
\begin{figure}
\centering
\input{figures/diagram.tex}
\caption{A diagram created in draw.io}
\end{figure}
\end{document}
Contributing
Contributions are welcome! Please feel free to open issues or submit pull requests on GitHub.
License
MIT
Metadata
Release files for drawio2tikz 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| drawio2tikz-0.6.0.tar.gz | 33.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| drawio2tikz-0.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 69.5 kB
Release files / drawio2tikz-0.6.0.tar.gz
| Download URL | drawio2tikz-0.6.0.tar.gz |
|---|---|
| Size | 33.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
37e142069479c150fc7f6ed39992bfb720e40e589a992a078ebdcceb03c7e25f
|
|
BLAKE2b-256 checksum How to use checksums |
cf265ee9ced62a1cf479bbafad6fb90afe150a8a999141dc25165011671477f2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 27, 2026.
Transparency logRelease files / drawio2tikz-0.6.0-py3-none-any.whl
| Download URL | drawio2tikz-0.6.0-py3-none-any.whl |
|---|---|
| Size | 36.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
32ff18eb1f15207d091bd8393952d010140ab044fa7fbc29e18f6622b09dd942
|
|
BLAKE2b-256 checksum How to use checksums |
32521f96700219509539d8e60f0d74c3980e0ae23a85902ff4da542658edbc7b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 27, 2026.
Transparency log