You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

skia-canvas

Package Overview
Dependencies
Maintainers
1
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

skia-canvas

A GPU-accelerated Canvas Graphics API for Node

2.0.2
latest
Source
npmnpm
Version published
Weekly downloads
22K
-15.09%
Maintainers
1
Weekly downloads
 
Created
Source
Skia Canvas
Getting Started   ·   Documentation   ·   Release Notes   ·   Discussion Forum

Skia Canvas is a browser-less implementation of the HTML Canvas drawing API for Node.js. It is based on Google’s Skia graphics engine and, accordingly, produces very similar results to Chrome’s <canvas> element. The library is well suited for use on desktop machines where you can render hardware-accelerated graphics to a window and on the server where it can output a variety of image formats.

While the primary goal of this project is to provide a reliable emulation of the standard API according to the spec, it also extends it in a number of areas to take greater advantage of Skia's advanced graphical features and provide a more expressive coding environment.

In particular, Skia Canvas:

  • is fast and compact since rendering takes place on the GPU and all the heavy lifting is done by native code written in Rust and C++
  • can render to windows using an OS-native graphics pipeline and provides a browser-like UI event framework
  • generates images in both raster (JPEG, PNG, & WEBP) and vector (PDF & SVG) formats
  • can save images to files, return them as Buffers, or encode dataURL strings
  • uses native threads in a user-configurable worker pool for asynchronous rendering and file I/O
  • can create multiple ‘pages’ on a given canvas and then output them as a single, multi-page PDF or an image-sequence saved to multiple files
  • can simplify, blunt, combine, excerpt, and atomize bézier paths using efficient boolean operations or point-by-point interpolation
  • provides 3D perspective transformations in addition to scaling, rotation, and translation
  • can fill shapes with vector-based Textures in addition to bitmap-based Patterns and supports line-drawing with custom markers
  • supports the full set of CSS filter image processing operators
  • offers rich typographic control including:

Installation

If you’re running on a supported platform, installation should be as simple as:

npm install skia-canvas

This will download a pre-compiled library from the project’s most recent release.

Platform Support

The underlying Rust library uses N-API v8 which allows it to run on Node.js versions:

  • v12.22+
  • v14.17+
  • v15.12+
  • v16.0.0 and later

Pre-compiled binaries are available for:

  • Linux (x64 & arm64)
  • macOS (x64 & Apple silicon)
  • Windows (x64)

Nearly everything you need is statically linked into the library. A notable exception is the Fontconfig library which must be installed separately if you’re running on Linux.

Running in Docker

The library is compatible with Linux systems using glibc 2.28 or later as well as Alpine Linux (x64 & arm64) and the musl C library it favors. In both cases, Fontconfig must be installed on the system for skia-canvas to operate correctly.

If you are setting up a Dockerfile that uses node as its basis, the simplest approach is to set your FROM image to one of the (Debian-derived) defaults like node:lts, node:18, node:16, node:14-buster, node:12-buster, node:bullseye, node:buster, or simply:

FROM node

You can also use the ‘slim’ image if you manually install fontconfig:

FROM node:slim
RUN apt-get update && apt-get install -y -q --no-install-recommends libfontconfig1

If you wish to use Alpine as the underlying distribution, you can start with something along the lines of:

FROM node:alpine
RUN apk update && apk add fontconfig

Compiling from Source

If prebuilt binaries aren’t available for your system you’ll need to compile the portions of this library that directly interface with Skia.

Start by installing:

  • The Rust compiler and cargo package manager using rustup
  • A C compiler toolchain (either LLVM/Clang or MSVC)
  • Python 3 (used by Skia's build process)
  • The Ninja build system
  • On Linux: Fontconfig and OpenSSL

Detailed instructions for setting up these dependencies on different operating systems can be found in the ‘Building’ section of the Rust Skia documentation. Once all the necessary compilers and libraries are present, running npm run build will give you a usable library (after a fairly lengthy compilation process).

Multithreading

When rendering canvases in the background (e.g., by using the asynchronous saveAs or toBuffer methods), tasks are spawned in a thread pool managed by the rayon library. By default it will create up to as many threads as your CPU has cores. You can see this default value by inspecting any Canvas object's engine.threads property. If you wish to override this default, you can set the SKIA_CANVAS_THREADS environment variable to your preferred value.

For example, you can limit your asynchronous processing to two simultaneous tasks by running your script with:

SKIA_CANVAS_THREADS=2 node my-canvas-script.js

Example Usage

Generating image files

import {Canvas} from 'skia-canvas'

let canvas = new Canvas(400, 400),
    ctx = canvas.getContext("2d"),
    {width, height} = canvas;

let sweep = ctx.createConicGradient(Math.PI * 1.2, width/2, height/2)
sweep.addColorStop(0, "red")
sweep.addColorStop(0.25, "orange")
sweep.addColorStop(0.5, "yellow")
sweep.addColorStop(0.75, "green")
sweep.addColorStop(1, "red")
ctx.strokeStyle = sweep
ctx.lineWidth = 100
ctx.strokeRect(100,100, 200,200)

// render to multiple destinations using a background thread
async function render(){
  // save a ‘retina’ image...
  await canvas.saveAs("rainbox.png", {density:2})
  // ...or use a shorthand for canvas.toBuffer("png")
  let pngData = await canvas.png
  // ...or embed it in a string
  let pngEmbed = `<img src="${await canvas.toDataURL("png")}">`
}
render()

// ...or save the file synchronously from the main thread
canvas.saveAsSync("rainbox.pdf")

Multi-page sequences

import {Canvas} from 'skia-canvas'

let canvas = new Canvas(400, 400),
    ctx = canvas.getContext("2d"),
    {width, height} = canvas

for (const color of ['orange', 'yellow', 'green', 'skyblue', 'purple']){
  ctx = canvas.newPage()
  ctx.fillStyle = color
  ctx.fillRect(0,0, width, height)
  ctx.fillStyle = 'white'
  ctx.arc(width/2, height/2, 40, 0, 2 * Math.PI)
  ctx.fill()
}

async function render(){
  // save to a multi-page PDF file
  await canvas.saveAs("all-pages.pdf")

  // save to files named `page-01.png`, `page-02.png`, etc.
  await canvas.saveAs("page-{2}.png")
}
render()

Rendering to a window

import {Window} from 'skia-canvas'

let win = new Window(300, 300)
win.title = "Canvas Window"
win.on("draw", e => {
  let ctx = e.target.canvas.getContext("2d")
  ctx.lineWidth = 25 + 25 * Math.cos(e.frame / 10)
  ctx.beginPath()
  ctx.arc(150, 150, 50, 0, 2 * Math.PI)
  ctx.stroke()

  ctx.beginPath()
  ctx.arc(150, 150, 10, 0, 2 * Math.PI)
  ctx.stroke()
  ctx.fill()
})

Acknowledgements

This project is deeply indebted to the work of the Rust Skia project whose Skia bindings provide a safe and idiomatic interface to the mess of C++ that lies underneath. Many thanks to the developers of node-canvas for their terrific set of unit tests. In the absence of an Acid Test for canvas, these routines were invaluable.

Notable contributors

  • @mpaparno contributed support for SVG rendering, raw image-buffer handling, WEBP import/export and numerous bugfixes
  • @Salmondx developed the initial Raw image loading & rendering routines
  • @lucasmerlin helped get GPU rendering working on Vulkan
  • @cprecioso & @saantonandre corrected and expanded upon the TypeScript type definitions
  • @meihuanyu contributed filter & path rendering fixes

© 2020–2025 Samizdat Drafting Co.

Keywords

canvas

FAQs

Package last updated on 28 Jan 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.