npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

chessboard-image

v1.3.0

Published

Generate beautiful chess board images from FEN notation. Pure JS port of chessboard-image (Python).

Downloads

168

Readme

Chessboard Image (JS)

License: MIT Node 18+

A JavaScript/Node.js port of the Python chessboard-image library. Generate beautiful chess board PNGs from FEN notation with customizable themes.

Rendering is powered by @napi-rs/canvas by default (prebuilt native binaries, no system libraries required), with an opt-in pure-JavaScript renderer for sandboxed runtimes that can't load native modules.

Features

  • Pure Node.js — no browser or headless-Chromium dependency
  • Multiple built-in themes (Wikipedia, Alpha, USCF, Wisteria, Sakura, Maestro, Symbol)
  • Any valid FEN notation
  • Output to file, Buffer, or data: URL
  • White or Black perspective
  • Optional file/rank coordinate labels

Installation

npm install chessboard-image

Quick Start

import { generateImage } from 'chessboard-image';

const startFen = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1';
await generateImage(startFen, 'board.png', { size: 400 });

Starting Position

Basic Usage

import { generateImage, generateBuffer, generateDataURL } from 'chessboard-image';

// Basic generation
await generateImage(fen, 'board.png', { size: 400 });

// With coordinates
await generateImage(fen, 'board.png', { showCoordinates: true });

// Black's perspective
await generateImage(fen, 'board.png', { playerPov: 'black' });

// Different theme
await generateImage(fen, 'board.png', { themeName: 'alpha' });

// Get PNG bytes or a data URL
const bytes = await generateBuffer(fen, { size: 500 });
const dataUrl = await generateDataURL(fen);

| White Perspective | Black Perspective | |:---:|:---:| | White POV | Black POV |

| Without Coordinates | With Coordinates | |:---:|:---:| | No Coordinates | With Coordinates |

Themes

Built-in themes: alpha, wikipedia, uscf, wisteria, sakura, maestro, symbol

| Wikipedia | Alpha | USCF | |:---:|:---:|:---:| | Wikipedia | Alpha | USCF |

| Wisteria | Sakura | Maestro | |:---:|:---:|:---:| | Wisteria | Sakura | Maestro |

| Symbol | |:---:| | Symbol |

import { listThemes, generateImage } from 'chessboard-image';

// List available themes
const themes = listThemes();

// Use a different theme
await generateImage(fen, 'board.png', { themeName: 'alpha' });

Sandboxed runtimes (Devvit, Cloudflare Workers, Edge)

The default @napi-rs/canvas backend requires a native N-API module, which can't load in sandboxed JS runtimes. For those, pass renderer: 'pure-js' to use a pure-JavaScript backend built on pngjs:

import { generateDataURL } from 'chessboard-image';

const dataUrl = await generateDataURL(fen, {
  renderer: 'pure-js',
  themeName: 'wikipedia',
});

Supported targets include:

  • Reddit Devvit
  • Cloudflare Workers
  • Vercel / Netlify Edge Functions
  • Deno Deploy

@napi-rs/canvas is declared as an optionalDependency, so installs won't fail on platforms without prebuilt binaries. If you only ever use the pure-JS renderer, you can install with --no-optional.

Differences from the canvas renderer

  • Same public API, same output shape (data:image/png;base64,… or Buffer).
  • Same board palettes and piece sprites (both backends read theme.json).
  • Coordinate labels are drawn with a built-in 5×7 bitmap font instead of a system font, so they look blockier but remain legible.
  • Piece sprites are scaled with nearest-neighbor rather than the antialiased scaler in Skia. For pixel-perfect output, pick size = 640 (cell size 80 = native sprite resolution).

CLI Usage

# Basic generation
chessboard-image generate "fen_string" -o board.png

# With options
chessboard-image generate "fen_string" -o board.png -s 600 -t alpha -p black -c

# Options:
# -s, --size: Board size in pixels
# -t, --theme: Theme name
# -p, --player-pov: white or black perspective
# -c, --coordinates: Show coordinates
# -r, --renderer: canvas (default) or pure-js

Examples

Famous Positions

import { generateImage } from 'chessboard-image';

// Scholar's Mate
const scholars = 'r1bqkb1r/pppp1Qpp/2n2n2/4p3/2B1P3/8/PPPP1PPP/RNB1K1NR b KQkq - 0 1';
await generateImage(scholars, 'scholars_mate.png', { size: 500 });

// Endgame
const endgame = '8/1p1b4/p7/3ppk2/6p1/2P4p/PP3B1K/5B2 b - - 0 1';
await generateImage(endgame, 'endgame.png', { playerPov: 'black', showCoordinates: true });

// Sicilian Defense
const sicilian = 'rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 2';
await generateImage(sicilian, 'sicilian.png', { themeName: 'alpha' });

| Scholar's Mate | Endgame (Black POV) | Sicilian Defense | |:---:|:---:|:---:| | Scholar's Mate | Endgame | Sicilian |

Batch Processing

import { generateImage } from 'chessboard-image';

const positions = [
  ['start', 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'],
  ['endgame', '8/1B6/8/8/8/8/1K3Qqr/7k w KQkq - 0 1'],
];

for (const [name, fen] of positions) {
  await generateImage(fen, `${name}.png`, { size: 400, showCoordinates: true });
}

API Reference

All image-producing functions are async.

generateImage(fen, outputPath?, {
  size = 400,
  themeName = 'wikipedia',
  themeFile,
  playerPov = 'white',
  showCoordinates = false,
  renderer = 'canvas',           // or 'pure-js' for sandboxed runtimes
}): Promise<string>

generateBuffer(fen, options): Promise<Buffer>   // PNG bytes
generateBytes (fen, options): Promise<Buffer>   // alias of generateBuffer
generateDataURL(fen, options): Promise<string>  // data:image/png;base64,...

listThemes(themeFile?): string[]
getThemeInfo(themeName?, themeFile?): { name, boardColors, pieces, pieceCount }
loadTheme({ themeFile, themeName }): object
parseFEN(fen): string[][]

Parameters

  • fen (string): FEN notation string
  • size (number): Board size in pixels (default: 400)
  • themeName (string): Theme name (default: 'wikipedia')
  • themeFile (string): Path to custom theme JSON (optional)
  • playerPov ('white' | 'black'): Perspective (default: 'white')
  • showCoordinates (boolean): Show file/rank labels (default: false)
  • renderer ('canvas' | 'pure-js'): Rendering backend (default: 'canvas'). Use 'pure-js' in sandboxed runtimes that can't load native modules.

Errors

InvalidFENError, ThemeNotFoundError, ChessImageGeneratorError — all exported from the package.

Custom Themes

Create a JSON file with base64-encoded pieces:

{
  "my_theme": {
    "pieces": {
      "wK": ["data:image/png;base64,..."], "wQ": ["data:image/png;base64,..."],
      "wR": ["data:image/png;base64,..."], "wB": ["data:image/png;base64,..."],
      "wN": ["data:image/png;base64,..."], "wP": ["data:image/png;base64,..."],
      "bK": ["data:image/png;base64,..."], "bQ": ["data:image/png;base64,..."],
      "bR": ["data:image/png;base64,..."], "bB": ["data:image/png;base64,..."],
      "bN": ["data:image/png;base64,..."], "bP": ["data:image/png;base64,..."]
    },
    "board": ["#F0D9B5", "#B58863"]
  }
}

Use with:

await generateImage(fen, 'board.png', {
  themeFile: 'my_themes.json',
  themeName: 'my_theme',
});

Differences from the Python version

  • API is async (Promise-returning) instead of synchronous PIL.
  • No generate_pil equivalent — use generateBuffer for PNG bytes, or import @napi-rs/canvas directly if you need a Canvas object.
  • New generateDataURL helper for embedding boards in HTML.
  • Option names are camelCase (playerPov, showCoordinates, themeName, themeFile).
  • Convenience aliases: fenToImage, fenToBytes, fenToBuffer, fenToDataURL.

Development

git clone https://github.com/anandjoshi91/chessboard-image-js.git
cd chessboard-image-js
npm install
npm test
node examples/generate_example_images.js

Requirements

  • Node.js 18+
  • @napi-rs/canvas — optional, installed automatically where prebuilt binaries are available; required only for the default canvas renderer
  • pngjs — always installed; powers the pure-js renderer

License

MIT — see LICENSE.