百科.dev
全部条目AI 编程趋势榜开源项目技术资讯提交条目
登录
< 返回工具列表
S

skia-canvas

> 编程语言
开源

一个多线程、基于 GPU 的 2D 向量图形环境,适用于 Node.js

2.6K stars0 点赞0 次浏览
访问官网GitHub

工具介绍

一个多线程、基于 GPU 的 2D 向量图形环境,适用于 Node.js



Skia Canvas is a Node.js implementation of the HTML Canvas drawing API for both on- and off-screen rendering. Since it uses Google’s Skia graphics engine, its output is very similar to Chrome’s <canvas> element — though it's also capable of things the browser’s Canvas still can't achieve.

In particular, Skia Canvas:

  • generates images in vector (PDF & SVG) as well as bitmap (JPEG, PNG, & WEBP) formats
  • can draw to interactive GUI [windows][window] and provides a browser-like [event][win_bind] framework
  • can save images to [files][toFile], encode to [dataURL][toURL] strings, and return [Buffers][toBuffer] or [Sharp][sharp] objects
  • uses native threads in a [user-configurable][multithreading] worker pool for asynchronous rendering and file I/O
  • can create [multiple ‘pages’][newPage] on a given canvas and then [output][toFile] them as a single, multi-page PDF or an image-sequence saved to multiple files
  • can [simplify][p2d_simplify], [blunt][p2d_round], [combine][bool-ops], [excerpt][p2d_trim], and [atomize][p2d_points] Bézier paths using efficient boolean operations or point-by-point [interpolation][p2d_interpolate]
  • provides [3D perspective][createProjection()] transformations in addition to [scaling][scale()], [rotation][rotate()], and [translation][translate()]
  • can fill shapes with vector-based [Textures][createTexture()] in addition to bitmap-based [Patterns][createPattern()] and supports line-drawing with custom [markers][lineDashMarker]
  • supports the full set of [CSS filter][filter] image processing operators
  • offers rich typographic control including:
    • multi-line, [word-wrapped][textwrap] text
    • line-by-line [text metrics][c2d_measuretext]
    • small-caps, ligatures, and other opentype features accessible using standard [font-variant][fontvariant] syntax
    • proportional [letter-spacing][letterSpacing], [word-spacing][wordSpacing], and [leading][c2d_font]
    • support for [variable fonts][VariableFonts] and transparent mapping of weight values
    • use of non-system fonts [loaded][fontlibrary-use] from local files
  • can be used for server-side image rendering on standard Linux hosts and ‘serverless’ platforms like Vercel and AWS Lambda

Installation

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

bash
npm install skia-canvas

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

pnpm

If you use the pnpm package manager, it will not download skia-canvas's platform-native binary unless you explicitly allow it. You can do this interactively via the ‘approve builds’ command (note that you need to press <space> to toggle the selection and then <enter> to proceed):

bash
pnpm install skia-canvas
pnpm approve-builds

In non-interactive scenarios (like building via CI), you can approve the build step when you add skia-canvas to your project:

bash
pnpm install skia-canvas --allow-build=skia-canvas

Alternatively, you can add a pnpm.onlyBuiltDependencies entry to your package.json file to mark the build-step as allowed:

json
{
  "pnpm": {
    "onlyBuiltDependencies": ["skia-canvas"]
  }
}

Platform Support

Skia Canvas runs on Linux, macOS, or Windows as well as serverless platforms like Vercel and AWS Lambda. Precompiled versions of the library’s native code will be automatically downloaded in the appropriate architecture (arm64 or x64) when you install it via npm.

The underlying Rust library uses [N-API][node_napi] v8 which allows it to run on all currently supported Node.js releases, and it is backward compatible with versions going back to v12.22+, v14.17+, v15.12+, and v16+.

Linux

The library is compatible with Linux systems using glibc 2.28 or later as well as Alpine Linux and the musl C library it favors. It will make use of the system’s fontconfig settings in /etc/fonts if they exist but will otherwise fall back to using a placeholder configuration, looking for installed fonts at commonly used Linux paths.

Docker

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:22, node:24-bookworm, or simply:

dockerfile
FROM node

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

dockerfile
FROM node:alpine

AWS Lambda

Skia Canvas depends on libraries that aren't present in the standard Lambda runtime. You can add these to your function by uploading a ‘layer’ (a zip file containing the required libraries and node_modules directory) and configuring your function to use it.

Detailed AWS instructions

Adding the Skia Canvas layer to your AWS account

  1. Look in the Assets section of Skia Canvas’s current release and download the aws-lambda-x64.zip or aws-lambda-arm64.zip file (depending on your architecture) but don’t decompress it
  2. Go to the AWS Lambda Layers console and click the Create Layer button, then fill in the fields:
  • Name: skia-canvas (or whatever you want)
  • Description: you might want to note the Skia Canvas version here
  • Compatible architectures: select x86_64 or arm64 depending on which zip you chose
  • Compatible runtimes: select Node.js 22.x (and/or 20.x)
  1. Click the Choose file button and select the zip file you downloaded in Step 1, then click Create

Alternatively, you can use the aws command line tool to create the layer. This bash script will fetch the skia-canvas version of your choice and make it available to your Lambda functions.

bash
#!/usr/bin/env bash
VERSION=3.0.8 # the skia-canvas version to include
PLATFORM=arm64 # arm64 or x64

curl -sLO https://github.com/samizdatco/skia-canvas/releases/download/v${VERSION}/aws-lambda-${PLATFORM}.zip
aws lambda publish-layer-version \
    --layer-name "skia-canvas" \
    --description "Skia Canvas ${VERSION} layer" \
    --zip-file "fileb://aws-lambda-${PLATFORM}.zip" \
    --compatible-runtimes "nodejs20.x" "nodejs22.x" \
    --compatible-architectures "${X/#x/x86_}"

Using the layer in a Lambda function

You can now use this layer in any function you create in the Functions console. After creating a new function, click the Add a Layer button and you can select your newly created Skia Canvas layer from the Custom Layers layer source.

Note that the layer only includes Skia Canvas and its dependencies—any other npm modules you want to use will need to be bundled into your function. To prevent the skia-canvas module from being doubly-included, make sure you add it to the devDependencies section (not the regular dependencies section) of your package.json file.

Next.js / Webpack

If you are using a framework like Next.js that bundles your server-side code with Webpack, you'll need to mark skia-canvas as an ‘external’, otherwise its platform-native binary file will be excluded from the final build. Try adding these options to your next.config.ts file:

javascript
const nextConfig: NextConfig = {
  serverExternalPackages: ['skia-canvas'],
  webpack: (config, options) => {
    if (options.isServer){
      config.externals = [
        ...config.externals,
        {'skia-canvas': 'commonjs skia-canvas'},
      ]
    }
    return config
  }
};

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:

  1. A recent version of git (older versions have difficulties with Skia's submodules)
  2. The Rust compiler and cargo package manager using rustup
  3. A C compiler toolchain (either LLVM/Clang or MSVC)
  4. Python 3 (used by Skia's build process)
  5. The Ninja build system
  6. 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. The Dockerfiles in the containers directory may also be useful for identifying needed dependencies. 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).

Global Settings

There are a handful of settings that can only be configured at launch and will apply to all the canvases you create in your script. The sections below describe the different [environment variables][node_env] you can set to make global changes. You can either set them as part of your command line invocation, or place them in a .env file in your project directory and use Node 20's [--env-file argument][node_env_arg] to load them all at once.

Multithreading

When rendering canvases in the background (e.g., by using the asynchronous [toFile][toFile] or [toBuffer][toBuffer] methods), tasks are spawned in a thread pool managed by the [rayon][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][canvas] object's [engine.threads][engine] 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:

bash
SKIA_CANVAS_THREADS=2 node my-canvas-script.js

Argument Validation

There are a number of situations where the browser API will react to invalid arguments by silently ignoring the method call rather than throwing an error. For example, these lines will simply have no effect:

javascript
ctx.fillRect(0, 0, 100, "october")
ctx.lineTo(NaN, 0)

Skia Canvas does its best to emulate these quirks, but allows you to opt into a stricter mode in which it will throw TypeErrors in these situations (which can be useful for debugging).

Set the SKIA_CANVAS_STRICT environment variable to 1 or true to enable this mode.

Example Usage

Generating image files

…

Multi-page sequences

…

Rendering to a window

javascript
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()
})
`

Issues· 0 开放

查看全部 Issues在 GitHub 打开

暂无开放 Issues,或尚未同步最近议题。

> 标签

Rustcanvasnode

暂无评论,来聊聊你的看法吧

> 工具信息

发布日期2026年8月1日
最后更新2026年9月17日
分类编程语言
定价开源

> 相关工具

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言