@napi-rs/canvas
A native Node.js binding to Google's Skia graphics engine that implements the HTML5 Canvas API with zero system dependencies.
Repository Health
Technical Analysis
@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
LottieAnimationrenderer built on Skia’s Skottie module, with frame/time seeking and support for embedded fonts, embedded base64 images, external asset directories, and.lottiearchives GlobalFontsfor 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-canvasin 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
Bubble Lab
Automation · AI Development
Open-core workflow engine for building AI-powered automations in TypeScript that run natively inside Slack — no context switching required.
Bun
Developer Tools
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.
Cherry Studio
AI Assistants
All-in-one AI desktop client with 300+ assistants and multi-model support
Documenso
Digital Signiture
Self-hosted, open-source DocuSign alternative with legally binding PDF signatures, multi-party workflows, and a full REST and tRPC API.
LobeHub
AI Assistants · Productivity · Automation
Your Chief Agent Operator — build, schedule, and collaborate with an entire AI team in one self-hostable workspace.
NocoDB
No Code Platforms · Databases · Low Code Platforms
Turn any SQL database into a collaborative no-code spreadsheet with automatic REST APIs and real-time views.
Notesnook
Note Taking · File Storage · Security
End-to-end encrypted, open-source note-taking where your data stays yours — even from the server.
Papra
Bookmarks Archiving
Self-hosted document archiving with email ingestion, OCR full-text search, and pluggable storage — store once, find anything.