kei-lisp-plugin-graphics
v4.0.0
Published
Canvas2D graphics plugin for the kei-lisp interpreter
Maintainers
Readme
kei-lisp-plugin-graphics
A Canvas2D drawing plugin for the kei-lisp
interpreter. Register it on a LispInterpreter and call drawing primitives
(gopen, gline-to, gfill-rect, ...) directly from Lisp source.
[!WARNING] This is a toy / hobby project built for learning and experimentation. Use in production (or any other serious product) is not recommended. APIs may change without notice, and maintenance and support are provided on a best-effort basis only.
It is also a personal project: issue reports (bugs, questions, ideas) are welcome, but external pull requests are generally not accepted — see CONTRIBUTING.md.

The canvas above is painted entirely from Lisp source. You can see this program rendered in the example page. To write and run kei-lisp yourself, use kei-lisp-web.
Features
- 75 Canvas2D drawing primitives (
g…symbols) callable directly from Lisp source - Works with
HTMLCanvasElementandOffscreenCanvas - ESM and CommonJS dual output with TypeScript types
- Zero runtime dependencies
Installation
# npm
npm install kei-lisp-plugin-graphics kei-lisp
# yarn
yarn add kei-lisp-plugin-graphics kei-lisp
# pnpm
pnpm add kei-lisp-plugin-graphics kei-lispkei-lisp is a peer dependency; install both into your project. Requires
kei-lisp >= 3.0.1 (for kei-lisp 2.x use kei-lisp-plugin-graphics 3.x) and
Node.js >= 24 for the build toolchain (the plugin itself targets any
environment that exposes a CanvasRenderingContext2D).
Quick start
import { LispInterpreter } from 'kei-lisp';
import { createGraphicsPlugin } from 'kei-lisp-plugin-graphics';
const canvas = document.querySelector<HTMLCanvasElement>('#stage')!;
const interpreter = new LispInterpreter();
interpreter.use(createGraphicsPlugin({ canvas }));
interpreter.evalString(`
(gopen)
(gfill-color "tomato")
(gfill-rect 10 10 120 80)
(gstroke-color "black")
(gline-width 2)
(gstroke-rect 10 10 120 80)
(gclose) ; note: gclose clears the canvas — omit it to keep the drawing visible
`);HTMLCanvasElement and OffscreenCanvas are both accepted.
API
export function createGraphicsPlugin(options: {
canvas: HTMLCanvasElement | OffscreenCanvas;
}): GraphicsPlugin;The returned plugin implements the KeiLispPlugin
interface and registers a fixed set of g… symbols that proxy to the
canvas's 2D rendering context.
Provided Lisp functions
| Category | Symbols |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Lifecycle | gopen, gclose, gclear, greset, gwidth, gheight, gsleep |
| Path | gstart-path, gfinish-path, gmove-to, gline-to, gquadcurve-to, gbezcurve-to, garc, garc-to, grect, ground-rect, gellipse, gclip, gis-point-in-path, gis-point-in-stroke |
| Fill / stroke | gfill, gstroke, gfill-rect, gstroke-rect, gfill-tri, gstroke-tri, gfill-text, gstroke-text |
| Style | gcolor, gfill-color, gstroke-color, gline-width, gline-cap, gline-join, gline-dash, gline-dash-offset, gmiter-limit, galpha, gpattern, gcomposite, gfilter, gimage-smoothing, glinear-gradient, gradial-gradient, gconic-gradient |
| Shadow | gshadow-color, gshadow-blur, gshadow-offsetx, gshadow-offsety |
| Text | gtext-font, gtext-align, gtext-baseline, gtext-direction, gmeasure-text, gletter-spacing, gword-spacing, gfont-kerning, gfont-stretch, gfont-variant, gtext-rendering |
| Transform | gtranslate, gscale, grotate, gtransform, gset-transform, greset-transform |
| State | gsave, grestore |
| Image / export | gimage, gsave-png, gsave-jpeg, gclear-rect, gpixel, gset-pixel |
Each function returns t on success; failures signal an evaluation error
that Lisp code can intercept with (handler-case … (eval-error (e) …)).
See docs/graphics.md for argument signatures and
side effects.
Bundled Lisp patterns
The package ships loadable .lisp pattern files under lisp/ — a grid
helper (ggrid), color-palette helpers (gpalette / gpalette-color),
and a frame-loop helper (ganimate):
(load "node_modules/kei-lisp-plugin-graphics/lisp/grid.lisp")
(gopen)
(ggrid 40)load reads from the filesystem (Node.js); browser hosts can fetch the
file's text and evaluate it instead. See
docs/patterns.md for the full list.
Environment support
| Capability | Browser (HTMLCanvasElement) | OffscreenCanvas (worker) | Node.js (e.g. @napi-rs/canvas) |
| ------------------------------------- | -------------------------------------------------------- | ------------------------------------------------- | -------------------------------- |
| Drawing primitives (g…) | ✅ | ✅ | ✅ |
| gimage / gpattern (image loading) | ✅ | ⚠️ needs a global Image | ❌ signals an error |
| gsave-png / gsave-jpeg (download) | ✅ | ❌ signals an error | ❌ signals an error |
| gsave-png / gsave-jpeg (path) | ❌ signals an error | ⚠️ needs Node's process (async convertToBlob) | ✅ |
| Diagnostics | console.error (or host-provided process.stderr shim) | same | process.stderr |
Reference
In-depth documentation of each area:
- Example page — the examples rendered on GitHub Pages
- kei-lisp-web — interactive kei-lisp playground
- API docs (TypeDoc) — generated API documentation
- API Reference — TypeScript / JavaScript API
- Graphics Reference — every
g…Lisp function - Bundled Lisp Patterns — the loadable
.lisphelpers shipped underlisp/ - Non-goals — what this project deliberately does not do
- kei-lisp Plugin Guide — how plugins integrate with the interpreter
Development
git clone https://github.com/ike-keichan/kei-lisp-plugin-graphics.git
cd kei-lisp-plugin-graphics
pnpm installRequires pnpm and Node.js 24+
(see .node-version for the exact version).
| Command | Description |
| -------------------- | ----------------------------------------- |
| pnpm build | Build for distribution |
| pnpm test | Run tests |
| pnpm test:coverage | Run tests with coverage thresholds |
| pnpm test:watch | Run tests in watch mode |
| pnpm e2e | Browser E2E (Playwright + Chromium) |
| pnpm screenshot | Regenerate the README screenshot |
| pnpm check | Run all checks (format, lint, spell, ...) |
| pnpm fix | Auto-fix format and lint issues |
See CONTRIBUTING.md for the branch policy and PR flow.
