chessboard-image
v1.3.0
Published
Generate beautiful chess board images from FEN notation. Pure JS port of chessboard-image (Python).
Downloads
168
Maintainers
Readme
Chessboard Image (JS)
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, ordata:URL - White or Black perspective
- Optional file/rank coordinate labels
Installation
npm install chessboard-imageQuick 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 });
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 |
|:---:|:---:|
|
|
|
| Without Coordinates | With Coordinates |
|:---:|:---:|
|
|
|
Themes
Built-in themes: alpha, wikipedia, uscf, wisteria, sakura, maestro, symbol
| Wikipedia | Alpha | USCF |
|:---:|:---:|:---:|
|
|
|
|
| Wisteria | Sakura | Maestro |
|:---:|:---:|:---:|
|
|
|
|
| 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,…orBuffer). - 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-jsExamples
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 |
|:---:|:---:|:---:|
|
|
|
|
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_pilequivalent — usegenerateBufferfor PNG bytes, or import@napi-rs/canvasdirectly if you need a Canvas object. - New
generateDataURLhelper 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.jsRequirements
- Node.js 18+
@napi-rs/canvas— optional, installed automatically where prebuilt binaries are available; required only for the defaultcanvasrendererpngjs— always installed; powers thepure-jsrenderer
License
MIT — see LICENSE.
