Aseprite data model
Frames, layers, and cels are different dimensions of a sprite
Understand canvas, timeline frames, layer ordering, cel coordinates, opacity, and RGBA pixels through the converter's SpriteProject model.
A sprite editor project has more than an image. It has a canvas, a timeline, a vertical layer stack, and pieces of pixel data placed where a particular frame and layer intersect. This repository calls that intersection a cel and carries it through the canonical SpriteProject model.
The model used by every importer
type SpriteProject = {
width: number;
height: number;
colorMode: "rgba";
frames: { index: number; durationMs: number }[];
layers: {
id: string;
name: string;
visible: boolean;
opacity: number;
cels: {
frameIndex: number;
x: number;
y: number;
imageData: ImageData;
}[];
}[];
}
Optional frame tags add a name, inclusive range, and forward, reverse, or ping-pong direction. The model currently uses RGBA pixels and whole-millisecond frame durations from 1 through 65,535.
Canvas: the shared coordinate space
width and height define the document canvas. A cel can be smaller than that canvas and use signed x and y coordinates, which is useful for a PSD or OpenRaster layer whose pixels occupy only part of the document. Full-frame inputs such as PNG sequences normally create canvas-sized cels at (0, 0).
Frames: time without pixels
A frame record identifies one timeline position and how long it displays. It does not own an image directly. Frame indexes must be contiguous and match their array positions. This separation lets many layers contribute different cels to the same moment.
A three-frame project might use 80 ms, 120 ms, and 200 ms. GIF, APNG, atlas JSON, Pixilart, Piskel, and Pixelorama derive those values differently, but the Aseprite exporter consumes the normalized result in exactly one form.
Layers: stack-wide properties
A layer has stable identity, a display name, visibility, opacity from 0 to 255, and an ordered list of cels. Array order becomes Aseprite layer order. Opacity remains a layer property; the exporter does not bake it into every pixel.
The current writer emits normal raster layers. That is why importers reject source blends and editor objects whose behavior cannot be represented as a normal layer without changing meaning.
Cels: where layer and frame meet
Each cel points to one frame index and carries its own RGBA ImageData plus an x/y position. One layer may have no cel for a frame; another may have one. Validation forbids two cels from the same layer claiming the same frame because that would be ambiguous.
A synthetic two-layer example
Consider a 16×16 two-frame character. “Color” is the lower layer and “Ink” is above it. Each layer has a cel on each frame, for four cels total. Both frames last 100 ms. Aseprite can now hide Ink, rename Color, or edit one frame's ink without changing the other three cels.
If the same animation is exported to two flattened PNG files, each PNG contains only the final composited pixels. The converter can still create two frames, but it has no evidence that Ink and Color ever existed. The accurate output is one generated layer with two cels.
How the binary writer uses the model
The exporter validates canvas size, frame count, duration, layer properties, cel bounds, unique frame references, RGBA byte length, and optional tags. It writes a 32-bit RGBA Aseprite header, layer chunks in the first frame, compressed-image cel chunks in their referenced frames, and a frame-tags chunk when present.
Cel opacity is written as fully opaque because SpriteProject has no per-cel opacity; layer opacity remains separate. Cel coordinates must fit Aseprite's signed 16-bit fields. Pixel bytes are stored in a zlib stream using deterministic uncompressed DEFLATE blocks.
Use the distinctions when judging compatibility
- “Converts frames” means timeline positions and displayed pixels can be rebuilt.
- “Preserves layers” means the source contains layer records and the specific importer maps their supported properties.
- “Preserves cels” means layer-specific pixels and frame references survive the mapping.
- “Looks the same” is not proof that masks, effects, blend modes, or editor metadata remain editable.
Continue with the browser-local pipeline to see how source-specific parsers converge on this model.