Installation
image-stitch ships ready for every runtime: native ESM, CommonJS, a tree-shakeable ESM bundle, and a browser-friendly global build. Install it with npm, pnpm, or yarn.
npm install image-stitch
Node.js 18+ is recommended. In browsers, load the prebuilt script tag bundle from https://cdn.jsdelivr.net/npm/image-stitch/dist/browser/image-stitch.min.js or import the module build from https://cdn.jsdelivr.net/npm/image-stitch/dist/bundles/image-stitch.esm.js.
Quick start (Node.js)
import { concatPngs } from "image-stitch";
import { readFileSync, writeFileSync } from "node:fs";
const stitched = await concatPngs({
inputs: [
readFileSync("./pngsuite/png/basi0g08.png"),
readFileSync("./pngsuite/png/basi2c08.png")
],
layout: { columns: 2 }
});
writeFileSync("spritesheet.png", stitched);
The returned value is a Uint8Array containing the PNG file. Persist it to disk, push it across the network, or convert it into a Blob for browser usage.
Browser usage
Use dynamic imports to fetch the ESM bundle from a CDN when prototyping. The following snippet wires the result into an <img>.
const { concatPngs } = await import("https://cdn.jsdelivr.net/npm/image-stitch/dist/bundles/image-stitch.esm.js");
const buffers = await Promise.all([
fetch("./images/basi0g08.png").then(r => r.arrayBuffer()),
fetch("./images/basi2c08.png").then(r => r.arrayBuffer())
]);
const stitched = await concatPngs({ inputs: buffers, layout: { columns: 2 } });
const blob = new Blob([stitched], { type: "image/png" });
document.querySelector("img.preview").src = URL.createObjectURL(blob);
When building a production bundle, import directly from image-stitch and let your bundler handle tree-shaking.
API reference
concatPngs(options)
Concatenate input images and return a Promise<Uint8Array>. All options are required unless marked optional.
interface ConcatOptions {
inputs: Array<Uint8Array | ArrayBuffer | string>;
layout: {
columns?: number;
rows?: number;
width?: number;
height?: number;
wrapBehavior?: "wrap" | "truncate";
};
}
- inputs — Buffers, typed arrays, or Node.js file paths.
- layout.columns — Fixed number of images per row.
- layout.rows — Fixed number of images per column.
- layout.width — Maximum pixel width; wraps when exceeded.
- layout.height — Maximum pixel height; truncates or wraps based on
wrapBehavior.
concatPngsStream(options)
Returns an async generator of Uint8Array chunks. Perfect for HTTP responses.
import { concatPngsStream } from "image-stitch";
const stream = concatPngsStream({ inputs, layout: { width: 2048 } });
for await (const chunk of stream) {
response.write(chunk);
}
Best practices
- Use inputs with matching bit depth and color type to avoid implicit conversions.
- Combine sprites that share transparency for consistent padding.
- Prefer
concatPngsStreamfor large or user-submitted assets. - Defer heavy work to a worker thread when running inside a browser UI.