asset-builder-packer
v0.0.2
Published
Texture atlas packer for Pixi and Spine: sharp/libvips compositing, maxrects placement, typed Pixi spritesheet JSON and Spine .atlas emitters, first-class trim/rotation, deterministic output.
Readme
asset-builder-packer
A texture-atlas packer for Pixi and Spine, built on sharp/libvips and
maxrects-packer. It takes decoded RGBA sprites and produces composited atlas pages plus typed
Pixi spritesheet JSON and Spine .atlas output.
Why another packer:
- sharp/libvips compositing — raw-RGBA pages end-to-end; encode once per output format (PNG/WebP/AVIF/JPG) downstream, no intermediate re-encoding.
- Typed emitters, not templates/regex — Pixi JSON and Spine
.atlasare built from data; format variants come from a second emitter call, never string replacement. - First-class trim + rotation for Spine — correct
offset/origmath with Y-up offsets (many pipelines hardcodeoffset: 0,0and can't trim Spine attachments). - Deterministic — identical input + options ⇒ byte-identical pages and emitter output, so it composes cleanly with content-hash build caches.
- Fill-rate metrics — per-page efficiency for VRAM budgeting.
Originally built to replace free-tex-packer-core in an internal asset pipeline; published as a standalone library.
import { pack, emitPixiJson, emitSpineAtlasPage } from 'asset-builder-packer';
const result = await pack(images, { maxWidth: 4096, maxHeight: 4096, allowTrim: true });
for (const page of result.pages) {
const json = emitPixiJson(page, { imageName: `${name}-${page.pageIndex}.png`, scale: 1 });
// page.data is raw RGBA — encode with sharp to png/webp/avif, once per format
}Status: phase 0 (contract + emitters + tests). Roadmap: docs/PLAN.md. Working agreements and invariants: CLAUDE.md.
npm test— vitestnpm run typecheck— tsc noEmitnpm run build— compile todist/
