@napi-rs/canvas

A native Node.js binding to Google's Skia graphics engine that implements the HTML5 Canvas API with zero system dependencies.

Library
npm
v1.0.9
2,325 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
87 /100 Excellent
Development Activity 96
Maintenance 100
Community 52
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
80 /100 Excellent
Architecture 85
Code Quality 82
Innovation 78
Learning Curve 75

@napi-rs/canvas is a Node.js addon, built on Node-API (napi-rs) and Rust, that exposes Google’s Skia rendering engine through the same CanvasRenderingContext2D surface web developers already know. Unlike node-canvas, which links against Cairo and Pango and therefore needs system libraries installed on the host, this package ships prebuilt native binaries for every major platform (Linux glibc/musl, macOS, Windows, Android, ARM variants) so npm install alone is enough to start drawing.

Beyond core 2D drawing, it bundles Path2D with PathKit-style boolean path operations (union, intersect, simplify, winding conversion), server-side SVG rendering, GIF/AVIF/WebP/JPEG/PDF encoding, and a Skottie-based Lottie animation renderer that can play and seek .json/.lottie animation files onto a canvas. Custom font loading via GlobalFonts, multi-threaded non-blocking image encoding through libuv’s thread pool, and OffscreenCanvas-style APIs round out the surface area.

The project benchmarks itself directly against node-canvas and skia-canvas in its README and consistently reports lower latency and higher throughput for common operations like shape drawing and gradient rendering, largely a product of using Skia (the engine behind Chrome and Android) rather than Cairo.

What You Get

  • A CanvasRenderingContext2D-compatible drawing surface (createCanvas, getContext('2d')) that mirrors the browser Canvas API
  • Prebuilt native binaries for Linux (glibc/musl), macOS, Windows, Android, and ARM/RISC-V targets via @napi-rs/cli, so no C++ toolchain or system graphics libraries are required at install time
  • Path2D with PathKit-derived boolean path operations (op, simplify, asWinding, trim, round) beyond what the standard Canvas spec defines
  • Multi-format image encoding (PNG, JPEG, AVIF, WebP, GIF, SVG, PDF) that runs off the main thread in libuv’s thread pool so encoding doesn’t block Node’s event loop
  • A LottieAnimation renderer built on Skia’s Skottie module, with frame/time seeking and support for embedded fonts, embedded base64 images, external asset directories, and .lottie archives
  • GlobalFonts for registering custom TTF/OTF fonts (including color/emoji fonts) so text renders identically regardless of the host system’s installed fonts

Common Use Cases

  • Generating chart, thumbnail, or social-preview images on a server without spinning up headless Chrome
  • Rendering SVGs or Lottie animations to static PNG/JPEG frames or exporting them as video via a companion encoder
  • Producing PDF or multi-page raster output from programmatic drawing instructions
  • Running as a drop-in, dependency-free replacement for node-canvas in Docker images and serverless/Lambda functions where installing Cairo/Pango is impractical
  • Manipulating and combining vector paths (boolean ops, simplification, fill-rule conversion) for icon or font tooling pipelines

Under The Hood

Architecture The package is a thin JS/TypeScript surface (index.js, js-binding.js, index.d.ts) over a Rust native addon compiled with napi-rs/N-API, with the Rust side in src/ split by concern: ctx.rs for the 2D rendering context, path.rs/pattern.rs/gradient.rs for path and paint state, image.rs/gif.rs/avif.rs/svg.rs for format-specific codecs, font.rs/global_fonts.rs for text shaping and font registration, and lottie.rs/page_recorder.rs/picture_recorder.rs for the Skottie-based animation and multi-page recording paths. A separate node-canvas.js/node-canvas.d.ts module provides an explicit compatibility shim mapping onto the older node-canvas API shape, and build.rs plus a vendored Skia checkout under skia//skia-c/ drive the native build across the eleven napi.targets platform triples declared in package.json; changing the core rendering abstraction in ctx.rs would ripple through every codec and the Lottie renderer since they all draw through the same context.

Tech Stack The native layer is Rust (edition 2024) built against napi/napi-derive 3.1 with web_stream and serde-json features, cssparser/cssparser-color for CSS color/gradient parsing, libavif/libavif-sys for AVIF codec support, gif for GIF encoding, imagesize/infer for format detection, and mimalloc-safe as the allocator on non-Linux and non-aarch64-Linux targets; the JS side is plain TypeScript-typed CommonJS with no runtime framework dependency, distributed through @napi-rs/cli’s prebuilt-binary packaging so consumers never compile Rust themselves.

Code Quality Tests live under __test__/ as ava-driven .spec.ts files (around 28 spec files covering Path2D, GIF, global fonts, image loading, node-canvas compatibility, and several numbered regression cases tied to specific GitHub issues), run via yarn test/test:ci. Linting is handled by oxlint (plus oxlint-tsgolint for type-aware rules) wired into a Husky pre-commit hook via lint-staged, and CI runs across dedicated GitHub Actions workflows (CI.yaml, docker.yml, skia.yaml, libcxxabi.yml) covering the native build matrix, not just the JS layer.

API Design The primary API deliberately shadows the standard browser CanvasRenderingContext2D/Path2D interfaces so existing browser-side drawing code ports over with minimal changes, while extending it with clearly separated namespaces (GlobalFonts, LottieAnimation, PathKit-style path operations) rather than overloading the base drawing API; a dedicated node-canvas.js compatibility module isolates the shape differences needed to drop this in as a node-canvas replacement, keeping the primary API surface uncluttered.

Used by 8 apps in this directory

TypeScript
99%
Apache 2.0

Bubble Lab

AI Development · Automation

1,094

Open-core workflow engine for building AI-powered automations in TypeScript that run natively inside Slack — no context switching required.

View details
35
Repo Health
78
Technical
71
Dependency
Built with
TypeScript 99%
Updated 5 months ago
Rust
67%
MIT

Bun

Developer Tools

96,068

An all-in-one JavaScript and TypeScript toolkit — one Rust-and-JavaScriptCore binary that replaces Node.js, npm, a bundler, and a test runner with faster equivalents.

View details
92
Repo Health
91
Technical
64
Dependency
Built with
Rust 67%
C++ 19%
TypeScript 10%
Updated 5 days ago
TypeScript
99%
AGPL 3.0

Cherry Studio

AI Assistants

52,202

All-in-one AI desktop client with 300+ assistants and multi-model support

View details
89
Repo Health
84
Technical
70
Dependency
Built with
TypeScript 99%
Updated 4 days ago
TypeScript
92%
AGPL 3.0

Documenso

Digital Signiture

15,224

Self-hosted, open-source DocuSign alternative with legally binding PDF signatures, multi-party workflows, and a full REST and tRPC API.

View details
93
Repo Health
79
Technical
68
Dependency
Built with
TypeScript 92%
Updated 4 days ago
TypeScript
99%
Other

LobeHub

AI Assistants · Automation · Productivity

82,864

Your Chief Agent Operator — build, schedule, and collaborate with an entire AI team in one self-hostable workspace.

View details
92
Repo Health
81
Technical
66
Dependency
Built with
TypeScript 99%
Updated 4 days ago
TypeScript
65%
Other

NocoDB

Databases · Low Code Platforms · No Code Platforms

65,098

Turn any SQL database into a collaborative no-code spreadsheet with automatic REST APIs and real-time views.

View details
90
Repo Health
77
Technical
62
Dependency
Built with
TypeScript 65%
Vue 30%
Updated 6 days ago
TypeScript
85%
GPL 3.0

Notesnook

File Storage · Note Taking · Security

14,660

End-to-end encrypted, open-source note-taking where your data stays yours — even from the server.

View details
90
Repo Health
84
Technical
60
Dependency
Built with
TypeScript 85%
JavaScript 12%
Updated 5 days ago
TypeScript
93%
AGPL 3.0

Papra

Bookmarks Archiving

5,519

Self-hosted document archiving with email ingestion, OCR full-text search, and pluggable storage — store once, find anything.

View details
86
Repo Health
82
Technical
69
Dependency
Built with
TypeScript 93%
Updated 5 days ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers