resvg-js
resvg-js copied to clipboard
A high-performance SVG renderer and toolkit, powered by Rust based resvg and napi-rs.
resvg-js
resvg-js is a high-performance SVG renderer and toolkit, powered by Rust based resvg, with Node.js backend using napi-rs, also a pure WebAssmebly backend.
Features
- Fast, safe and zero dependencies, with correct output.
- Convert SVG to PNG, includes cropping, scaling and setting the background color.
- Support system fonts and custom fonts in SVG text.
-
v2
: Gets the width and height of the SVG and the generated PNG. -
v2
: Support for outputting simplified SVG strings, such as converting shapes(rect, circle, etc) to<path>
. -
v2
: Support WebAssembly. -
v2
: Support to get SVG bounding box and crop according to bounding box. -
v2
: Support for loading images of external links in<image>
. - No need for node-gyp and postinstall, the
.node
file has been compiled for you. - Cross-platform support, including Apple M Chips.
Installation
Node.js
npm i @resvg/resvg-js
Browser(Wasm)
<script src="https://unpkg.com/@resvg/resvg-wasm"></script>
Example
This example will load Source Han Serif, and then render the SVG to PNG.
node example/index.js
Loaded 1 font faces in 0ms.
Font './example/SourceHanSerifCN-Light-subset.ttf':0 found in 0.006ms.
✨ Done in 55.65491008758545 ms
SVG | PNG |
---|---|
CC BY 3.0: Niabot |
![]() CC BY 3.0: Niabot |
![]() |
Usage
Node.js
const { promises } = require('fs')
const { join } = require('path')
const { Resvg } = require('@resvg/resvg-js')
async function main() {
const svg = await promises.readFile(join(__dirname, './text.svg'))
const opts = {
background: 'rgba(238, 235, 230, .9)',
fitTo: {
mode: 'width',
value: 1200,
},
font: {
fontFiles: ['./example/SourceHanSerifCN-Light-subset.ttf'], // Load custom fonts.
loadSystemFonts: false, // It will be faster to disable loading system fonts.
defaultFontFamily: 'Source Han Serif CN Light',
},
}
const resvg = new Resvg(svg, opts)
const pngData = resvg.render()
const pngBuffer = pngData.asPng()
console.info('Original SVG Size:', `${resvg.width} x ${resvg.height}`)
console.info('Output PNG Size :', `${pngData.width} x ${pngData.height}`)
await promises.writeFile(join(__dirname, './text-out.png'), pngBuffer)
}
main()
WebAssembly
This package also ships a pure WebAssembly artifact built with wasm-bindgen
to run in browsers.
Browser
<script src="https://unpkg.com/@resvg/resvg-wasm"></script>
<script>
(async function () {
// The Wasm must be initialized first
await resvg.initWasm(fetch('https://unpkg.com/@resvg/resvg-wasm/index_bg.wasm'))
const opts = {
fitTo: {
mode: 'width', // If you need to change the size
value: 800,
},
}
const svg = '<svg> ... </svg>' // Input SVG, String or Uint8Array
const resvgJS = new resvg.Resvg(svg, opts)
const pngData = resvgJS.render(svg, opts) // Output PNG data, Uint8Array
const pngBuffer = pngData.asPng()
const svgURL = URL.createObjectURL(new Blob([pngData], { type: 'image/png' }))
document.getElementById('output').src = svgURL
})()
</script>
See playground, it is also possible to call Wasm in Node.js, but it is slower.
Sample Benchmark
Running "resize width" suite...
resvg-js(Rust):
12 ops/s
sharp:
9 ops/s
skr-canvas(Rust):
7 ops/s
svg2img(canvg and node-canvas):
6 ops/s
Support matrix
Test or Contributing
-
Install latest
Rust
-
Install
Node.js@10+
which fully supportedNode-API
-
Install
wasm-pack
curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
Normally
wasm-pack
will installwasm-bindgen
automatically, but if the installation fails due to network reasons, please try to install it manually.cargo install wasm-bindgen-cli
On computers with Apple M chips, the following error message may appear:
Error: failed to download from https://github.com/WebAssembly/binaryen/releases/download/version_90/binaryen-version_90-x86_64-apple-darwin.tar.gz
Please install binaryen manually:
brew install binaryen
Build Node.js bindings
npm i
npm run build
npm test
Build WebAssembly bindings
npm i
npm run build:wasm
npm run test:wasm
Roadmap
I will consider implementing the following features, if you happen to be interested, please feel free to discuss with me or submit a PR.
- [x] Support async API
- [x] Upgrade to napi-rs v2
- [x] Support WebAssembly
- [x] Output usvg-simplified SVG string
- [x] Support for getting SVG Bounding box
- [ ] Support for generating more lossless bitmap formats, e.g. avif, webp, JPEG XL
Release package
We use GitHub actions to automatically publish npm packages.
# 1.0.0 => 1.0.1
npm version patch
# or 1.0.0 => 1.1.0
npm version minor
License
Copyright (c) 2021-present, yisibl(一丝)