npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@aborrol/resvg-js-tolty

v2.6.2-ab41

Published

Fork: resvg-js with advanced custom text layout (textLayout, letterSpacing, opacity, font buffers) by Aborrol

Readme

Reusing fonts in Node (ResvgFontManager)

Чтобы не парсить и не загружать шрифты на каждый new Resvg(...), можно создать ResvgFontManager один раз и переиспользовать базу шрифтов:

const { ResvgWithFonts, ResvgFontManager } = require('@aborrol/resvg-js-tolty')

const fontManager = new ResvgFontManager({
  loadSystemFonts: false,
  fontBuffers: [
    { fontName: 'Roboto-400', buffer: fs.readFileSync('Roboto-Regular.ttf') },
  ],
  defaultFontFamily: 'Roboto-400',
})

const resvg = ResvgWithFonts.withFontManager(svgString, {
  background: '#fff',
  // любые другие опции
}, fontManager)

const png = resvg.render().asPng()

⚡️ This is a fork of [email protected] with custom text layout features (see below).

resvg-js

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.

Playground

https://resvg-js.vercel.app

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.

Custom Features (Fork by Aborrol)

  • Поддержка кастомного layout для <text>: автоматический перенос строк, параметры width, lineHeight, maxlines, textAlign, opacity, letterSpacing и др. через опцию textLayout в JS.
  • Возможность задавать шрифты из буфера с явным именем family (fontBuffers).
  • Приоритет параметров: опции JS → SVG-атрибуты → дефолт.
  • Все параметры применяются по id <text>. Если id не найден — опции не применяются.
  • Условное логирование: контроль уровня детализации логов через опцию logLevel ('off', 'error', 'warn', 'info', 'debug', 'trace').

Пример: кастомный layout и шрифты из буфера

const { promises } = require('fs')
const { join } = require('path')
const { Resvg } = require('@resvg/resvg-js')

async function main() {
  const svg = await promises.readFile(join(__dirname, 'input.svg'), 'utf8')
  const fontFiles = [
    { name: 'Lobster', file: 'Lobster-Regular.ttf' },
    { name: 'Jost-700', file: 'Jost-700.ttf' },
  ]
  // Загружаем шрифты как буферы
  const fontBuffers = await Promise.all(
    fontFiles.map(async ({ name, file }) => {
      const buffer = await promises.readFile(join(__dirname, 'fonts', file))
      return { fontName: name, buffer: Array.from(buffer) }
    }),
  )

  const resvg = new Resvg(svg, {
    background: '#fff',
    font: {
      loadSystemFonts: false,
      fontBuffers, // <-- ваши шрифты
      defaultFontFamily: 'Lobster',
    },
    textLayout: {
      'main-title': {
        width: 300,
        lineHeight: 32,
        maxlines: 3,
        textAlign: 'center',
        opacity: 0.5,
        letterSpacing: 2.5,
        x: 50,
        y: 100,
        fontFamily: 'Lobster',
        fontSize: 48,
        fill: '#ff0000',
      },
      'subtitle': {
        width: 200,
        lineHeight: 24,
        maxlines: 2,
        textAlign: 'left',
      }
    },
    logLevel: 'debug', // Контроль уровня логирования: 'off', 'error', 'warn', 'info', 'debug', 'trace'
  })

  const pngData = resvg.render()
  const pngBuffer = pngData.asPng()
  await promises.writeFile(join(__dirname, 'output.png'), Buffer.from(pngBuffer))
  console.log('💾 output.png создан')
}

main().catch(console.error)

Этот пример показывает, как подключить свои TTF-шрифты из буфера и задать расширенный layout для текста через textLayout.

Уровни логирования (logLevel)

Опция logLevel позволяет контролировать детализацию отладочной информации:

  • 'off' - никаких логов
  • 'error' - только ошибки
  • 'warn' - предупреждения и ошибки
  • 'info' - информационные сообщения, предупреждения и ошибки
  • 'debug' - все сообщения включая отладочные (по умолчанию)
  • 'trace' - максимальная детализация

Примеры использования:

// Минимальное логирование - только ошибки и предупреждения
const resvg = new Resvg(svg, { logLevel: 'warn' })

// Полная отладочная информация
const resvg = new Resvg(svg, { logLevel: 'debug' })

// Без логов
const resvg = new Resvg(svg, { logLevel: 'off' })

TypeScript Поддержка

Проект включает полную TypeScript типизацию для всех функций, включая кастомный textLayout:

import { Resvg, ResvgRenderOptions, TextLayoutOptions } from '@aborrol/resvg-js-tolty';

const textLayout: TextLayoutOptions = {
  'main-title': {
    width: 300,
    lineHeight: 32,
    maxlines: 3,
    textAlign: 'center', // 'left' | 'center' | 'right' | 'middle'
    opacity: 0.5,
    letterSpacing: 2.5,
    x: 50,
    y: 100,
    fontFamily: 'Lobster',
    fontSize: 48,
    fill: '#ff0000',
    fontWeight: 'bold',
    fontStyle: 'normal',
  }
};

const options: ResvgRenderOptions = {
  font: {
    loadSystemFonts: false,
    fontBuffers: [
      { fontName: 'Lobster', buffer: [1, 2, 3, 4] }
    ],
  },
  textLayout,
  logLevel: 'debug',
};

const resvg = new Resvg(svg, options);

Доступные типы:

  • TextLayoutBlockOptions - опции для одного текстового блока
  • TextLayoutOptions - карта id → опции для всех текстовых блоков
  • ResvgRenderOptions - полные опции рендеринга
  • FontBuffer - структура для передачи шрифтов из буфера

Cross-Compilation

resvg-js поддерживает кросскомпиляцию для всех основных платформ.

Быстрый старт

Локальная кросскомпиляция

# Установка зависимостей и Rust целей
make install

# Кросскомпиляция для всех платформ
make build

# Проверка артефактов
make verify

Docker кросскомпиляция

# Кросскомпиляция через Docker
make build-docker

# Или через npm
npm run cross-compile:docker:rebuild

Гибридная кросскомпиляция (рекомендуется)

# macOS локально + остальные через Docker
make build-hybrid

# Или через npm
npm run cross-compile:hybrid

Документация

Поддерживаемые платформы

  • macOS: ARM64 (Apple Silicon), x64 (Intel)
  • Linux: ARM32/ARM64/x64 (glibc и musl)
  • Windows: ARM64/x86/x64
  • Android: ARM32/ARM64

CI/CD

Проект включает автоматический GitHub Actions workflow для кросскомпиляции на всех платформах.

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/[email protected]/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 [email protected] [email protected] @types/sharp [email protected]
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 | Node.js 20 | Node.js 22 | npm | | ---------------- | ---------- | ---------- | ---------- | ---------- | ---------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Windows x64 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | npm version | | Windows x32 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | npm version | | Windows arm64 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | npm version | | macOS x64 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | npm version | | macOS arm64(M Chips) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 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

  • Install latest Rust

  • Install Node.js@10+ which fully supported Node-API

  • Install wasm-pack

    curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh

    Normally wasm-pack will install wasm-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

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

MPLv2.0

Copyright (c) 2021-present, yisibl(一丝)