Skip to content

yisibl/resvg-js

main
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
October 8, 2021 16:25
npm
October 20, 2023 22:43
src
October 16, 2023 21:45
October 20, 2023 22:43
November 17, 2022 12:02
November 11, 2021 01:46
December 24, 2021 22:36
October 8, 2021 16:25
October 20, 2023 22:43
February 15, 2022 19:10
February 22, 2022 12:32
October 20, 2023 22:43
October 8, 2021 16:25
September 25, 2023 14:44

resvg-js

GitHub CI Status @resvg/resvg-js npm version @resvg/resvg-js downloads Rust 1.65+

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 WebAssembly backend.

Please use all lowercase resvg-js when referencing project names.

๐Ÿ’– ๐Ÿ™Sponsoring me

Your sponsorship means a lot to me. It will help me sustain my projects actively and make more of my ideas come true. Much appreciated!

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.
  • Support for running as native addons in Deno.

Sponsor

Alipay(ๆ”ฏไป˜ๅฎ)

Installation

Node.js

npm i @resvg/resvg-js

Browser(Wasm)

<script src="https://unpkg.com/@resvg/resvg-wasm"></script>

Docs

Example

Node.js 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

Deno Example

deno run --unstable --allow-read --allow-write --allow-ffi example/index-deno.js

[2022-11-16T15:03:29Z DEBUG resvg_js::fonts] Loaded 1 font faces in 0.067ms.
[2022-11-16T15:03:29Z DEBUG resvg_js::fonts] Font './example/SourceHanSerifCN-Light-subset.ttf':0 found in 0.001ms.
Original SVG Size: 1324 x 687
Output PNG Size  : 1200 x 623
โœจ Done in 66 ms
SVG PNG

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', // You can omit this.
    },
  }
  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()

Bun

Starting with Bun 0.8.1, resvg-js can be run directly in Bun without any modification to the JS files, and is fully compatible with the syntax in Node.js.

bun example/index.js

Deno

Starting with Deno 1.26.1, there is support for running Native Addons directly from Node.js. This allows for performance that is close to that found in Node.js.

deno run --unstable --allow-read --allow-write --allow-ffi example/index-deno.js
import * as path from 'https://deno.land/std@0.159.0/path/mod.ts'
import { Resvg } from 'npm:@resvg/resvg-js'
const __dirname = path.dirname(path.fromFileUrl(import.meta.url))

const svg = await Deno.readFile(path.join(__dirname, './text.svg'))
const opts = {
  fitTo: {
    mode: 'width',
    value: 1200,
  },
}

const t = performance.now()
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}`)
console.info('โœจ Done in', performance.now() - t, 'ms')

await Deno.writeFile(path.join(__dirname, './text-out-deno.png'), pngBuffer)

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 font = await fetch('./fonts/Pacifico-Regular.woff2')
    if (!font.ok) return

    const fontData = await font.arrayBuffer()
    const buffer = new Uint8Array(fontData)

    const opts = {
      fitTo: {
        mode: 'width', // If you need to change the size
        value: 800,
      },
      font: {
        fontBuffers: [buffer], // New in 2.5.0, loading custom fonts
      },
    }

    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

npm i benny@3.x sharp@0.x @types/sharp svg2img@0.x
npm run bench
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

Node.js 12 Node.js 14 Node.js 16 Node.js 18 npm
Windows x64 โœ“ โœ“ โœ“ โœ“ npm version
Windows x32 โœ“ โœ“ โœ“ โœ“ npm version
Windows arm64 โœ“ โœ“ โœ“ โœ“ npm version
macOS x64 โœ“ โœ“ โœ“ โœ“ npm version
macOS arm64(M1) โœ“ โœ“ โœ“ โœ“ npm version
Linux x64 gnu โœ“ โœ“ โœ“ โœ“ npm version
Linux x64 musl โœ“ โœ“ โœ“ โœ“ npm version
Linux arm gnu โœ“ โœ“ โœ“ โœ“ npm version
Linux arm64 gnu โœ“ โœ“ โœ“ โœ“ npm version
Linux arm64 musl โœ“ โœ“ โœ“ โœ“ npm version
Android arm64 โœ“ โœ“ โœ“ โœ“ npm version
Android armv7 โœ“ โœ“ โœ“ โœ“ npm version

Test or Contributing

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.

  • Support async API
  • Upgrade to napi-rs v2
  • Support WebAssembly
  • Output usvg-simplified SVG string
  • 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

Please use all lowercase resvg-js when referencing project names.

MPLv2.0

Copyright (c) 2021-present, yisibl(ไธ€ไธ)