Developer reference
Every function and option, what it returns, and how to show the pages in a web page. Examples are written to run as shown.
Which one should I use?
Everything runs on your own machine, in your own process. The Node.js package converts on a background thread so the event loop keeps running, and the Python package releases the GIL while it works. No server, account or network access is involved.
| You want to… | Use |
|---|---|
| Convert files in a terminal, a script or CI | docsvg |
| Show uploaded documents in a web or Electron app | Node.js preview() + document-svg/preview-ui |
| Convert from Python: scripts, notebooks, web APIs | Python preview() / convert() |
| Build it into a Rust program | convert_path() / convert_bytes() |
| Convert inside the browser only (PDF, Word, Excel, PowerPoint) | <docsvg-viewer> (WebAssembly) |
Command line: docsvg
The format is chosen from the file extension, with a look at the file's first bytes when the extension is missing or generic. The command exits with 0 on success, and with 1 and a message on standard error when conversion fails.
docsvg <INPUT> --output <FOLDER> [options]
docsvg reverse <SVG or FOLDER> --output <FILE>
docsvg transform <SVG or -> --output <SVG or -> [options]Convert: docsvg <INPUT> --output <FOLDER>
| Option | Default | What it does |
|---|---|---|
-o, --output DIR | required | New or empty folder that receives the pages and conversion.json. |
--jobs N | 1 | How many PDF pages to convert at once. Other formats are converted page by page. |
--max-input-mib N | 512 MiB | Largest input file accepted. |
--max-entry-mib N | 128 MiB | Largest expanded part inside a PDF or a ZIP-based file (Office, EPUB, 3MF, CBZ). |
--max-pages N | 10,000 | Most pages, slides or sheets written. |
--max-xml-events N | 5,000,000 | Most XML parser steps per part; stops oversized or hostile XML. |
--no-metadata | metadata on | Leave the provenance metadata out of each SVG. |
--precision N | 5 | Decimal places kept in coordinates. Smaller numbers give smaller files. |
--outline-embedded-pdf-text | off | Draw embedded PDF fonts as shapes: looks exactly like the original, but the text can no longer be selected. Check that the font's license allows this. |
--embed-drawio-source | off | Keep the draw.io source inside each SVG so it can be turned back into an editable diagram. Roughly doubles the size. |
--stencils PATH | none | draw.io shape library files or folders to draw library shapes with. Without them, such shapes become labelled placeholders. |
Write back: docsvg reverse
| Option | Default | What it does |
|---|---|---|
-o, --output FILE | required | The file to create. Its extension picks the format: .pptx, .docx, .xlsx, .pdf, .drawio, .dxf, .gcode, .stl, .html, .webp and more. |
--max-input-mib N | 512 MiB | Largest total SVG input. |
--max-pages N | 10,000 | Most SVG pages read. |
Tidy up: docsvg transform
| Option | Default | What it does |
|---|---|---|
--minify | off | Remove comments and extra spaces. |
--monochrome COLOR | off | Paint every fill and stroke in one colour, e.g. "#1e293b". |
--responsive | off | Drop the fixed size so the SVG scales to its container. |
--precision N | none | Round coordinates to N decimal places. |
--remove-metadata | off | Remove <metadata>, <desc> and data-* attributes. |
--clean-paths | off | Tidy path data (drop zero-length segments and duplicate closes). |
--strip-empty-groups | off | Remove groups that draw nothing. |
What a conversion writes
The folder must be new or empty; existing files are never overwritten. conversion.json is the report of the whole job. The same fields come back from convert() and preview() (camelCase in Node.js).
out/
├── page-0001.svg
├── page-0002.svg
└── conversion.json| Field | What it does |
|---|---|
page_count | Number of pages written. |
warnings | Document-wide notes on anything approximated or left out. Empty does not guarantee a pixel-perfect match. |
pages[].svg | File name of the page (convert) or the complete SVG markup (preview). |
pages[].width_points, height_points | Page size in points (1 pt = 1/72 inch). |
pages[].warnings | Notes for that page only. |
source_format | The format that was detected, such as pptx or pdf. |
needs_review | preview() only: true when the document or any page has a warning. |
elapsed_ms, input_bytes, version | How long it took, how big the input was, and which version made it. |
Node.js
Errors reject the promise with an Error whose message starts with the kind of problem: "invalid input", "unsupported input", "safety limit exceeded" or "I/O error".
const { convert, preview, reverse, transform } = require('document-svg')
async function main() {
const result = await preview('slides.pptx', { maxPages: 50 })
console.log(result.pageCount, result.needsReview)
const firstPageSvg = result.pages[0].svg
const report = await convert('slides.pptx', 'out/slides', { jobs: 2 })
await reverse('out/slides', 'slides-copy.pptx')
const small = transform(firstPageSvg, { minify: true })
}
main().catch(console.error)| Function | Returns | What it does |
|---|---|---|
preview(file, options?) | Promise<PreviewReport> | Every page as SVG text, in memory. Nothing is left on disk. |
convert(file, folder, options?) | Promise<ConversionReport> | Write pages and conversion.json to a folder. |
reverse(svgOrFolder, file, options?) | Promise<ReverseReport> | Package SVG pages as another file type. Options: maxInputBytes, maxPages. |
transform(svg, options?) | string | Tidy an SVG string; runs synchronously. |
Options for preview() and convert()
| Option | Default | What it does |
|---|---|---|
jobs | 1 | How many PDF pages to convert at once. Other formats are converted page by page. |
maxInputBytes | 512 MiB | Largest input file accepted. |
maxZipEntryBytes | 128 MiB | Largest expanded part inside a PDF or a ZIP-based file (Office, EPUB, 3MF, CBZ). |
maxPages | 10,000 | Most pages, slides or sheets written. |
maxXmlEvents | 5,000,000 | Most XML parser steps per part; stops oversized or hostile XML. |
includeMetadata: false | metadata on | Leave the provenance metadata out of each SVG. |
precision | 5 | Decimal places kept in coordinates. Smaller numbers give smaller files. |
outlineEmbeddedPdfText | off | Draw embedded PDF fonts as shapes: looks exactly like the original, but the text can no longer be selected. Check that the font's license allows this. |
embedDrawioSource | off | Keep the draw.io source inside each SVG so it can be turned back into an editable diagram. Roughly doubles the size. |
stencilPaths | none | draw.io shape library files or folders to draw library shapes with. Without them, such shapes become labelled placeholders. |
maxSvgBytes | 64 MiB | preview() only: largest SVG for one page. |
maxTotalSvgBytes | 256 MiB | preview() only: largest total for all pages. |
Options for transform()
| Option | Default | What it does |
|---|---|---|
minify | off | Remove comments and extra spaces. |
monochrome | off | Paint every fill and stroke in one colour, e.g. "#1e293b". |
responsive | off | Drop the fixed size so the SVG scales to its container. |
precision | none | Round coordinates to N decimal places. |
removeMetadata | off | Remove <metadata>, <desc> and data-* attributes. |
cleanPaths | off | Tidy path data (drop zero-length segments and duplicate closes). |
stripEmptyGroups | off | Remove groups that draw nothing. |
document-svg/preview-ui (runs in the browser; no native code)
| Function | Returns | What it does |
|---|---|---|
createSvgPreviewUrl(svg) | string | A Blob URL for an <img>. Checks the SVG first. |
revokeSvgPreviewUrl(url) | void | Release a Blob URL when the image goes away. |
createSvgPreviewDataUrl(svg) | string | A data: URL, for passing to another window or process. |
copySvgToClipboard(svg) | Promise<'image/svg+xml' | 'text/plain'> | Copy the image, or its source where images can't be copied. Call from a click. |
copySvgSourceToClipboard(svg) | Promise<void> | Always copy the SVG source as text. |
Python
Install document-svg, import document_svg. Results are plain dictionaries with the same fields as conversion.json.
from document_svg import convert, preview, reverse, transform
result = preview("report.docx", max_pages=50)
print(result["page_count"], result["needs_review"])
first_page_svg = result["pages"][0]["svg"]
report = convert("report.docx", "out/report", jobs=2)
reverse("out/report", "report-copy.docx")
small = transform(first_page_svg, minify=True)| Function | Returns | What it does |
|---|---|---|
preview(path, **options) | dict | Every page as SVG text, in memory. Accepts max_svg_bytes and max_total_svg_bytes as well. |
convert(path, folder, **options) | dict | Write pages and conversion.json to a folder. |
reverse(svg_or_folder, path, *, max_input_bytes=None, max_pages=None) | dict | Package SVG pages as another file type. |
transform(svg, **options) | str | bytes | Tidy an SVG. Returns str for str input and bytes for bytes input. |
Options for preview() and convert() (keyword-only)
| Option | Default | What it does |
|---|---|---|
jobs | 1 | How many PDF pages to convert at once. Other formats are converted page by page. |
max_input_bytes | 512 MiB | Largest input file accepted. |
max_zip_entry_bytes | 128 MiB | Largest expanded part inside a PDF or a ZIP-based file (Office, EPUB, 3MF, CBZ). |
max_pages | 10,000 | Most pages, slides or sheets written. |
max_xml_events | 5,000,000 | Most XML parser steps per part; stops oversized or hostile XML. |
include_metadata=False | metadata on | Leave the provenance metadata out of each SVG. |
precision | 5 | Decimal places kept in coordinates. Smaller numbers give smaller files. |
outline_embedded_pdf_text | off | Draw embedded PDF fonts as shapes: looks exactly like the original, but the text can no longer be selected. Check that the font's license allows this. |
embed_drawio_source | off | Keep the draw.io source inside each SVG so it can be turned back into an editable diagram. Roughly doubles the size. |
stencil_paths | none | draw.io shape library files or folders to draw library shapes with. Without them, such shapes become labelled placeholders. |
Exceptions
| Error | When |
|---|---|
ValueError | The input is invalid or unsupported, or a safety limit was reached. |
OSError | A file could not be read or written, e.g. the output folder is not empty. |
RuntimeError | Anything else, such as a damaged PDF, ZIP or XML structure. |
Rust
Only the crate root (the functions above, their option and report types, Error) and the ir and svg modules are public API; internal readers can change between releases.
use document_svg::{convert_path, ConvertOptions};
fn main() -> Result<(), document_svg::Error> {
let options = ConvertOptions { jobs: 2, ..ConvertOptions::default() };
let report = convert_path("report.pdf", "out/report", &options)?;
println!("{} pages, {} warnings", report.page_count, report.warnings.len());
Ok(())
}| Function | Returns | What it does |
|---|---|---|
convert_path(input, folder, &ConvertOptions) | Result<ConversionReport> | Convert a file and write pages and conversion.json. |
convert_bytes(name, &bytes, &ConvertOptions, ByteConvertLimits, on_page) | Result<ByteConversionReport> | Convert from memory without temporary files; on_page receives each SvgPage as soon as it is ready. Also works on wasm32. |
svg_to_document(input, output, &ReverseOptions) | Result<ReverseReport> | Package SVG pages as another file type (the CLI's reverse). |
transform_svg(&bytes, &TransformOptions) | Result<Vec<u8>> | Tidy an SVG (the CLI's transform). |
ConvertOptions fields
| Option | Default | What it does |
|---|---|---|
jobs | 1 | How many PDF pages to convert at once. Other formats are converted page by page. |
max_input_bytes | 512 MiB | Largest input file accepted. |
max_zip_entry_bytes | 128 MiB | Largest expanded part inside a PDF or a ZIP-based file (Office, EPUB, 3MF, CBZ). |
max_pages | 10,000 | Most pages, slides or sheets written. |
max_xml_events | 5,000,000 | Most XML parser steps per part; stops oversized or hostile XML. |
include_metadata: false | metadata on | Leave the provenance metadata out of each SVG. |
precision | 5 | Decimal places kept in coordinates. Smaller numbers give smaller files. |
outline_embedded_pdf_text | off | Draw embedded PDF fonts as shapes: looks exactly like the original, but the text can no longer be selected. Check that the font's license allows this. |
embed_drawio_source | off | Keep the draw.io source inside each SVG so it can be turned back into an editable diagram. Roughly doubles the size. |
stencil_paths | none | draw.io shape library files or folders to draw library shapes with. Without them, such shapes become labelled placeholders. |
Error variants
| Error | When |
|---|---|
InvalidInput | The input or an argument is invalid, e.g. the output folder is not empty. |
Unsupported | The format can't be recognised, or a feature isn't supported. |
LimitExceeded | A safety limit was reached. |
Io, Pdf, Xml, Zip, Json | Reading or parsing failed at that layer. |
Showing pages in a web page
Yes — the pages are ordinary SVG images, so any browser shows them. There are two ways to get them onto the screen.
1. Convert on your server or in Electron's main process with Node.js, send the SVG to the page, and show it with preview-ui (see the Node.js section and the preview guide). Works for every supported format.
2. Convert inside the browser with the WebAssembly build and its ready-made <docsvg-viewer> element. Nothing is uploaded and no server is needed. It covers PDF, Word, Excel and PowerPoint, and offers page thumbnails, zoom, fit to width or page, rotation, full screen, text search and download of the current page.
<script type="module" src="/bindings/wasm/web/docsvg-viewer.js"></script>
<docsvg-viewer thumbnails></docsvg-viewer>
<script type="module">
const viewer = document.querySelector('docsvg-viewer')
viewer.options = { maxPages: 200 } // optional limits
fileInput.addEventListener('change', () => viewer.openFile(fileInput.files[0]))
</script><docsvg-viewer> at a glance
| Function | What it does |
|---|---|
thumbnails | Attribute: show a column of page thumbnails. |
openFile(file) | Method: convert and show a File (from an input or drag and drop, which the element also handles itself). |
options | Property: limits such as maxInputBytes (default 64 MiB), maxPages (default 1,000) and precision. |
Keyboard | Arrow keys and Page Up/Down move between pages, + and − zoom, f fits the width, r rotates. |
- The WebAssembly build is not published as a package. Build it from bindings/wasm (Rust and wasm-bindgen are needed), then serve bindings/wasm/web from your site.
- Serve it over HTTP; opening the files with file:// does not work. A Content-Security-Policy needs 'wasm-unsafe-eval' for scripts and 'self' for workers.
- Pages are shown through Blob URLs in <img> elements; the viewer never inserts document SVG into your page.
Try the viewer in your browser →How to build and host the viewer →
Limits at a glance
Every limit protects the machine from oversized or broken files. Lower them for your use case if you like; don't raise them just to push a difficult file through.
| Limit | CLI, Node.js, Python, Rust | Browser (WebAssembly) |
|---|---|---|
| Input file | 512 MiB | 64 MiB (at most 256 MiB) |
| One expanded part (PDF stream, ZIP entry) | 128 MiB | 32 MiB |
| Pages | 10,000 | 1,000 |
| XML parser steps per part | 5,000,000 | 2,000,000 |
| SVG for one page (in-memory preview) | 64 MiB | 16 MiB |
| SVG for all pages (in-memory preview) | 256 MiB | 128 MiB |
| Coordinate decimal places | 5 | 4 |