MCPcopy Index your code
hub / github.com/Automattic/node-canvas

github.com/Automattic/node-canvas @v3.2.3

Chat with this repo
repository ↗ · DeepWiki ↗ · release v3.2.3 ↗ · + Follow
309 symbols 590 edges 63 files 12 documented · 4% updated todayv3.2.3 · 2026-03-31★ 10,681427 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

node-canvas

Test NPM version

node-canvas is a Cairo-backed Canvas implementation for Node.js.

Installation

$ npm install canvas

By default, pre-built binaries will be downloaded if you're on one of the following platforms: - macOS x86/64 - macOS aarch64 (aka Apple silicon) - Linux x86/64 (glibc only) - Windows x86/64

If you want to build from source, use npm install --build-from-source and see the Compiling section below.

The minimum version of Node.js required is 18.12.0.

Compiling

If you don't have a supported OS or processor architecture, or you use --build-from-source, the module will be compiled on your system. This requires several dependencies, including Cairo and Pango.

For detailed installation information, see the wiki. One-line installation instructions for common OSes are below. Note that libgif/giflib, librsvg and libjpeg are optional and only required if you need GIF, SVG and JPEG support, respectively. Cairo v1.10.0 or later is required.

OS Command
macOS Using Homebrew:

brew install pkg-config cairo pango libpng jpeg giflib librsvg pixman python-setuptools Ubuntu | sudo apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev Fedora | sudo yum install gcc-c++ cairo-devel pango-devel libjpeg-turbo-devel giflib-devel Solaris | pkgin install cairo pango pkg-config xproto renderproto kbproto xextproto OpenBSD | doas pkg_add cairo pango png jpeg giflib Windows | See the wiki Others | See the wiki

Mac OS X v10.11+: If you have recently updated to Mac OS X v10.11+ and are experiencing trouble when compiling, run the following command: xcode-select --install. Read more about the problem on Stack Overflow. If you have xcode 10.0 or higher installed, in order to build from source you need NPM 6.4.1 or higher.

Quick Example

const { createCanvas, loadImage } = require('canvas')
const canvas = createCanvas(200, 200)
const ctx = canvas.getContext('2d')

// Write "Awesome!"
ctx.font = '30px Impact'
ctx.rotate(0.1)
ctx.fillText('Awesome!', 50, 100)

// Draw line under text
var text = ctx.measureText('Awesome!')
ctx.strokeStyle = 'rgba(0,0,0,0.5)'
ctx.beginPath()
ctx.lineTo(50, 102)
ctx.lineTo(50 + text.width, 102)
ctx.stroke()

// Draw cat with lime helmet
loadImage('examples/images/lime-cat.jpg').then((image) => {
  ctx.drawImage(image, 50, 0, 70, 70)

  console.log('<img src="https://github.com/Automattic/node-canvas/raw/v3.2.3/' + canvas.toDataURL() + '" />')
})

Upgrading from 1.x to 2.x

See the changelog for a guide to upgrading from 1.x to 2.x.

For version 1.x documentation, see the v1.x branch.

Documentation

This project is an implementation of the Web Canvas API and implements that API as closely as possible. For API documentation, please visit Mozilla Web Canvas API. (See Compatibility Status for the current API compliance.) All utility methods and non-standard APIs are documented below.

Utility methods

Non-standard APIs

createCanvas()

ts createCanvas(width: number, height: number, type?: 'PDF'|'SVG') => Canvas

Creates a Canvas instance. This method works in both Node.js and Web browsers, where there is no Canvas constructor. (See browser.js for the implementation that runs in browsers.)

const { createCanvas } = require('canvas')
const mycanvas = createCanvas(200, 200)
const myPDFcanvas = createCanvas(600, 800, 'pdf') // see "PDF Support" section

createImageData()

ts createImageData(width: number, height: number) => ImageData createImageData(data: Uint8ClampedArray, width: number, height?: number) => ImageData // for alternative pixel formats: createImageData(data: Uint16Array, width: number, height?: number) => ImageData

Creates an ImageData instance. This method works in both Node.js and Web browsers.

const { createImageData } = require('canvas')
const width = 20, height = 20
const arraySize = width * height * 4
const mydata = createImageData(new Uint8ClampedArray(arraySize), width)

loadImage()

ts loadImage() => Promise<Image>

Convenience method for loading images. This method works in both Node.js and Web browsers.

const { loadImage } = require('canvas')
const myimg = loadImage('http://server.com/image.png')

myimg.then(() => {
  // do something with image
}).catch(err => {
  console.log('oh no!', err)
})

// or with async/await:
const myimg = await loadImage('http://server.com/image.png')
// do something with image

registerFont()

ts registerFont(path: string, { family: string, weight?: string, style?: string }) => void

To use a font file that is not installed as a system font, use registerFont() to register the font with Canvas.

const { registerFont, createCanvas } = require('canvas')
registerFont('comicsans.ttf', { family: 'Comic Sans' })

const canvas = createCanvas(500, 500)
const ctx = canvas.getContext('2d')

ctx.font = '12px "Comic Sans"'
ctx.fillText('Everyone hates this font :(', 250, 10)

The second argument is an object with properties that resemble the CSS properties that are specified in @font-face rules. You must specify at least family. weight, and style are optional and default to 'normal'.

deregisterAllFonts()

ts deregisterAllFonts() => void

Use deregisterAllFonts to unregister all fonts that have been previously registered. This method is useful when you want to remove all registered fonts, such as when using the canvas in tests

const { registerFont, createCanvas, deregisterAllFonts } = require('canvas')

describe('text rendering', () => {
    afterEach(() => {
        deregisterAllFonts();
    })
    it('should render text with Comic Sans', () => {
        registerFont('comicsans.ttf', { family: 'Comic Sans' })

        const canvas = createCanvas(500, 500)
        const ctx = canvas.getContext('2d')

        ctx.font = '12px "Comic Sans"'
        ctx.fillText('Everyone loves this font :)', 250, 10)

        // assertScreenshot()
    })
})

Image#src

ts img.src: string|Buffer

As in browsers, img.src can be set to a data: URI or a remote URL. In addition, node-canvas allows setting src to a local file path or Buffer instance.

const { Image } = require('canvas')

// From a buffer:
fs.readFile('images/squid.png', (err, squid) => {
  if (err) throw err
  const img = new Image()
  img.onload = () => ctx.drawImage(img, 0, 0)
  img.onerror = err => { throw err }
  img.src = squid
})

// From a local file path:
const img = new Image()
img.onload = () => ctx.drawImage(img, 0, 0)
img.onerror = err => { throw err }
img.src = 'images/squid.png'

// From a remote URL:
img.src = 'http://picsum.photos/200/300'
// ... as above

// From a `data:` URI:
img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='
// ... as above

Note: In some cases, img.src= is currently synchronous. However, you should always use img.onload and img.onerror, as we intend to make img.src= always asynchronous as it is in browsers. See https://github.com/Automattic/node-canvas/issues/1007.

Image#dataMode

ts img.dataMode: number

Applies to JPEG images drawn to PDF canvases only.

Setting img.dataMode = Image.MODE_MIME or Image.MODE_MIME|Image.MODE_IMAGE enables MIME data tracking of images. When MIME data is tracked, PDF canvases can embed JPEGs directly into the output, rather than re-encoding into PNG. This can drastically reduce filesize and speed up rendering.

const { Image, createCanvas } = require('canvas')
const canvas = createCanvas(w, h, 'pdf')
const img = new Image()
img.dataMode = Image.MODE_IMAGE // Only image data tracked
img.dataMode = Image.MODE_MIME // Only mime data tracked
img.dataMode = Image.MODE_MIME | Image.MODE_IMAGE // Both are tracked

If working with a non-PDF canvas, image data must be tracked; otherwise the output will be junk.

Enabling mime data tracking has no benefits (only a slow down) unless you are generating a PDF.

Canvas#toBuffer()

ts canvas.toBuffer((err: Error|null, result: Buffer) => void, mimeType?: string, config?: any) => void canvas.toBuffer(mimeType?: string, config?: any) => Buffer

Creates a Buffer object representing the image contained in the canvas.

  • callback If provided, the buffer will be provided in the callback instead of being returned by the function. Invoked with an error as the first argument if encoding failed, or the resulting buffer as the second argument if it succeeded. Not supported for mimeType raw or for PDF or SVG canvases.
  • mimeType A string indicating the image format. Valid options are image/png, image/jpeg (if node-canvas was built with JPEG support), raw (unencoded data in BGRA order on little-endian (most) systems, ARGB on big-endian systems; top-to-bottom), application/pdf (for PDF canvases) and image/svg+xml (for SVG canvases). Defaults to image/png for image canvases, or the corresponding type for PDF or SVG canvas.
  • config
  • For image/jpeg, an object specifying the quality (0 to 1), if progressive compression should be used and/or if chroma subsampling should be used: {quality: 0.75, progressive: false, chromaSubsampling: true}. All properties are optional.

  • For image/png, an object specifying the ZLIB compression level (between 0 and 9), the compression filter(s), the palette (indexed PNGs only), the the background palette index (indexed PNGs only) and/or the resolution (ppi): {compressionLevel: 6, filters: canvas.PNG_ALL_FILTERS, palette: undefined, backgroundIndex: 0, resolution: undefined}. All properties are optional.

    Note that the PNG format encodes the resolution in pixels per meter, so if you specify 96, the file will encode 3780 ppm (~96.01 ppi). The resolution is undefined by default to match common browser behavior.

  • For application/pdf, an object specifying optional document metadata: {title: string, author: string, subject: string, keywords: string, creator: string, creationDate: Date, modDate: Date}. All properties are optional and default to undefined, except for creationDate, which defaults to the current date. Adding metadata requires Cairo 1.16.0 or later.

    For a description of these properties, see page 550 of PDF 32000-1:2008.

    Note that there is no standard separator for keywords. A space is recommended because it is in common use by other applications, and Cairo will enclose the list of keywords in quotes if a comma or semicolon is used.

Return value

If no callback is provided, a Buffer. If a callback is provided, none.

Examples

// Default: buf contains a PNG-encoded image
const buf = canvas.toBuffer()

// PNG-encoded, zlib compression level 3 for faster compression but bigger files, no filtering
const buf2 = canvas.toBuffer('image/png', { compressionLevel: 3, filters: canvas.PNG_FILTER_NONE })

// JPEG-encoded, 50% quality
const buf3 = canvas.toBuffer('image/jpeg', { quality: 0.5 })

// Asynchronous PNG
canvas.toBuffer((err, buf) => {
  if (err) throw err // encoding failed
  // buf is PNG-encoded image
})

canvas.toBuffer((err, buf) => {
  if (err) throw err // encoding failed
  // buf is JPEG-encoded image at 95% quality
}, 'image/jpeg', { quality: 0.95 })

// BGRA pixel values, native-endian
const buf4 = canvas.toBuffer('raw')
const { stride, width } = canvas
// In memory, this is `canvas.height * canvas.stride` bytes long.
// The top row of pixels, in BGRA order on little-endian hardware,
// left-to-right, is:
const topPixelsBGRALeftToRight = buf4.slice(0, width * 4)
// And the third row is:
const row3 = buf4.slice(2 * stride, 2 * stride + width * 4)

// SVG and PDF canvases
const myCanvas = createCanvas(w, h, 'pdf')
myCanvas.toBuffer() // returns a buffer containing a PDF-encoded canvas
// With optional metadata:
myCanvas.toBuffer('application/pdf', {
  title: 'my picture',
  keywords: 'node.js demo cairo',
  creationDate: new Date()
})

Canvas#createPNGStream()

```

Extension points exported contracts — how you extend this code

PngConfig (Interface)
(no doc)
index.d.ts
JpegConfig (Interface)
(no doc)
index.d.ts
PdfConfig (Interface)
(no doc)
index.d.ts
NodeCanvasRenderingContext2DSettings (Interface)
(no doc)
index.d.ts
TextMetrics (Interface)
(no doc)
index.d.ts

Core symbols most depended-on inside this repo

createCanvas
called by 592
index.js
done
called by 93
benchmarks/run.js
scale
called by 83
lib/DOMMatrix.js
translate
called by 78
lib/DOMMatrix.js
rotate
called by 44
lib/DOMMatrix.js
toFloat64Array
called by 33
lib/DOMMatrix.js
line
called by 27
test/public/tests.js
loadImage
called by 23
index.js

Shape

Function 175
Method 74
Class 54
Interface 6

Languages

TypeScript100%

Modules by API surface

lib/DOMMatrix.js52 symbols
index.d.ts28 symbols
test/wpt/generated/pixel-manipulation.js17 symbols
test/wpt/generated/drawing-text-to-the-canvas.js15 symbols
test/wpt/generated/transformations.js13 symbols
test/wpt/generated/the-canvas-state.js13 symbols
test/wpt/generated/the-canvas-element.js13 symbols
test/wpt/generated/text-styles.js13 symbols
test/wpt/generated/shadows.js13 symbols
test/wpt/generated/path-objects.js13 symbols
test/wpt/generated/meta.js13 symbols
test/wpt/generated/line-styles.js13 symbols

Dependencies from manifests, versioned

@types/node10.12.18 · 1×
assert-rejects1.0.0 · 1×
express4.16.3 · 1×
js-yaml4.1.0 · 1×
mocha5.2.0 · 1×
node-addon-api7.0.0 · 1×
pixelmatch4.0.2 · 1×
prebuild-install7.1.3 · 1×
standard12.0.1 · 1×
tsd0.29.0 · 1×
typescript4.2.2 · 1×

For agents

$ claude mcp add node-canvas \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact