Version 2.3 (2026-10-03)
Full Version
Includes all features: graphics, input handling (keyboard, mouse, touch, gamepad), and audio plugins.
- pi.js (482 KB)
- pi.js.map (1,094 KB)
- pi.min.js (209 KB)
- pi.min.js.map (1,098 KB)
- pi.esm.js (452 KB)
- pi.esm.js.map (1,091 KB)
- pi.esm.min.js (209 KB)
- pi.esm.min.js.map (1,098 KB)
- pi.d.ts (170 KB)
Lite Version
Graphics-only build. Smaller file size, perfect for visual-only projects.
- pi.lite.js (294 KB)
- pi.lite.js.map (640 KB)
- pi.lite.min.js (129 KB)
- pi.lite.min.js.map (642 KB)
- pi.lite.esm.js (276 KB)
- pi.lite.esm.js.map (637 KB)
- pi.lite.esm.min.js (129 KB)
- pi.lite.esm.min.js.map (642 KB)
- pi.lite.d.ts (91 KB)
Changelog
**Added**
- `playAudio()` returns an instance ID that `pauseAudio()`, `resumeAudio()`, `setAudio()`, and `stopAudio()` accept. `loadAudio()` can stream a file instead of decoding it.
- Sound is mixed on `sfx`, `music`, `audio`, and `master` buses with `setBusVolume()`, through an output limiter controlled by `setSoundLimiter()`.
- Mouse-wheel input with `onWheel()` and `offWheel()`, gamepad button and axis names, `vibrateGamepad()`, and a `cancelled` field on key, mouse, touch, press, and click data.
- `provideService()` and `getService()` let one plugin offer an API to another.
**Changed**
- The `sound`, `keyboard`, `pointer`, and `gamepad` plugins are now 2.0.0. Input commands are camelCase with no aliases: `inkey` is now `inKey`, `onmouse` is `onMouse`, `ontouch` is `onTouch`, `onclick` is `onClick`, and `ingamepad` is `inGamepad`. See the [v2.3 update guide](https://github.com/AndyStubbs/pijs/blob/main/docs/UPGRADE-V2.3.md) for every rename and required adjustment.
- `sound()` and PLAY use ADSR envelopes. `sound()` replaces `attack` and `decay` with `attackTime`, `decayTime`, `sustainLevel`, and `releaseTime`, which changes the meaning of its seventh positional argument.
- `loadAudio()` no longer takes `poolSize`. Samples, synthesized sounds, and PLAY notes share one voice budget.
- Touch handler modes are `"down"`, `"move"`, and `"up"` instead of `"start"`, `"move"`, and `"end"`.
- Input handlers are identified by mode and function, so registering the same handler twice runs it once. Validation throws `TypeError` or `RangeError` with a code per parameter.
- `set()` throws `INVALID_OPTION` for an option it does not recognize, and `$.clearEvents()` clears pointer handlers on every screen.
**Fixed**
- A letter pressed with Shift no longer stays held. `input()` works after `stopKeyboard()`, and Space no longer scrolls the page or Tab moves focus during a prompt.
- Removing a pointer handler no longer disables the other handlers of its mode, and a gamepad button press that happens between reads is no longer lost.
- `setChar()` works on every font, `getImage()` returns the pixels of an offscreen screen, and offscreen screens draw again after a WebGL context loss.
- Builds are identical on every platform.
Version 2.2 (2026-09-19)
Full Version
Includes all features: graphics, input handling (keyboard, mouse, touch, gamepad), and audio plugins.
- pi.js (396 KB)
- pi.js.map (831 KB)
- pi.min.js (176 KB)
- pi.min.js.map (840 KB)
- pi.esm.js (372 KB)
- pi.esm.js.map (829 KB)
- pi.esm.min.js (176 KB)
- pi.esm.min.js.map (840 KB)
- pi.d.ts (121 KB)
Lite Version
Graphics-only build. Smaller file size, perfect for visual-only projects.
- pi.lite.js (297 KB)
- pi.lite.js.map (628 KB)
- pi.lite.min.js (133 KB)
- pi.lite.min.js.map (639 KB)
- pi.lite.esm.js (280 KB)
- pi.lite.esm.js.map (627 KB)
- pi.lite.esm.min.js (133 KB)
- pi.lite.esm.min.js.map (639 KB)
- pi.lite.d.ts (90 KB)
Changelog
**Added**
- Host-controlled canvas layout via `screen()` `noCss` option. With `noCss: true`, Pi.js appends and sizes the canvas but leaves layout CSS to the host.
- WebGL context recovery: screens sharing a lost context suspend together; on restoration they rebuild GPU resources and resume with transparent framebuffers. Applications must redraw after restoration.
- Polygons plugin included with the full version.
**Changed**
- `loadImage()` and `loadSpritesheet()` no longer accept `usePalette` or `paletteKeys`. Images retain source colors when screen palettes change. No compatibility shim is provided.
- Custom `sampler2D` inputs now align with `u_texture`. Remove any `1.0 - uv.y` workaround previously applied only to custom image maps.
- Transparent composition is consistent across drawing, layers, and contexts. `ready()` callbacks run asynchronously; input cancellation resolves with `null`.
**Fixed**
- Screen removal and selection keep global commands bound to the active surviving screen. Failed screen creation rolls back cleanly.
- Mouse and touch coordinates account for CSS scaling, borders, padding, and scrolling. Large draws use bounded batches; full-turn arcs match circles.
- Image, font, audio, and plugin lifecycle edge cases around removal, late events, and failed initialization.
**Performance**
- Cached static images and sprites avoid unnecessary WebGL state queries. Triangle and line geometry use bounded reserves and copies.
Version 2.1 (2026-08-25)
Full Version
Includes all features: graphics, input handling (keyboard, mouse, touch, gamepad), and audio plugins.
- pi.js (353 KB)
- pi.js.map (763 KB)
- pi.min.js (159 KB)
- pi.min.js.map (772 KB)
- pi.esm.js (332 KB)
- pi.esm.js.map (760 KB)
- pi.esm.min.js (159 KB)
- pi.esm.min.js.map (772 KB)
- pi.d.ts (107 KB)
Lite Version
Graphics-only build. Smaller file size, perfect for visual-only projects.
- pi.lite.js (268 KB)
- pi.lite.js.map (590 KB)
- pi.lite.min.js (122 KB)
- pi.lite.min.js.map (601 KB)
- pi.lite.esm.js (253 KB)
- pi.lite.esm.js.map (588 KB)
- pi.lite.esm.min.js (122 KB)
- pi.lite.esm.min.js.map (601 KB)
Changelog
**Added**
- Custom GLSL ES 3.00 fragment shaders can be created with `createShader()` and applied in draw order with `applyShader()`.
- Display shaders can be set with `setDisplayShader()` for effects such as custom upscaling, color grading, and CRT simulation. Persistent uniforms can be updated with `setDisplayShaderUniforms()`.
- Custom shaders support reflected float, integer, unsigned integer, boolean, vector, matrix, uniform-array, and `sampler2D` image inputs. Samplers accept registered images, direct browser image sources, and Pi screens.
- `getShaderInfo()` reports global and per-screen shader lifecycle and reflection diagnostics. `removeShader()` completes queued passes, clears active display uses, and releases cached WebGL programs.
- Nested drawing views can be managed with `pushView()`, `popView()`, and `resetView()`. Drawing, images, pixels, paint operations, clearing, and text output honor the active view's origin and clipping rectangle.
- `viewToScreen()` and `screenToView()` convert coordinates between the active view and the logical screen.
- Added a parent parameter to the screen command that enables fast `drawImage()` calls directly from the offscreen framebuffer.
**Fixed**
- Drawing an offscreen screen as an image no longer reverses its Y axis when the source and destination share a WebGL context.
- Removing images now releases their WebGL textures, and temporary framebuffers used for texture copies are reused and cleaned up with their screen.
Version 2.0 (2025-12-14)
Full Version
Includes all features: graphics, input handling (keyboard, mouse, touch, gamepad), and audio plugins.
- pi.js (308 KB)
- pi.js.map (649 KB)
- pi.min.js (140 KB)
- pi.min.js.map (658 KB)
- pi.esm.js (290 KB)
- pi.esm.js.map (647 KB)
- pi.esm.min.js (140 KB)
- pi.esm.min.js.map (658 KB)
- pi.d.ts (87 KB)
Lite Version
Graphics-only build. Smaller file size, perfect for visual-only projects.
- pi.lite.js (224 KB)
- pi.lite.js.map (483 KB)
- pi.lite.min.js (103 KB)
- pi.lite.min.js.map (493 KB)
- pi.lite.esm.js (211 KB)
- pi.lite.esm.js.map (481 KB)
- pi.lite.esm.min.js (103 KB)
- pi.lite.esm.min.js.map (493 KB)
Changelog
- Added WebGL context for all graphics.
- Added esm source file.
- Split into full and lite versions.
Version 1.2 (2025-12-12)
Full Version
Includes all features: graphics, input handling (keyboard, mouse, touch, gamepad), and audio plugins.
- pi.js (254 KB)
- pi.min.js (120 KB)
- pi.min.js.map (150 KB)
- pi.d.ts (68 KB)
Changelog
- Added getImage method
- Added removeImage method
- Removed duplicate method point
- Added cache to getImageData.
- Added parameter: isAddToPalette for get method.
- Updated internal font size calculations.
- Changed the blend mode name from blended to blend.