Sprite Sheet Editor — Slice, Animate, Export to Engines
One workspace for the whole sprite pipeline: import any sheet, GIF or .aseprite file, turn it into tagged animations with per-frame durations, pivots and boxes, and export files that were loaded in the engines themselves.
The Sprite workspace is the step between finished art and a game engine. It imports a PNG sheet, numbered frame files, a GIF or APNG, an .aseprite file or an existing atlas with its JSON or XML, and turns it into animations (tags) with a duration in milliseconds on every frame, a pivot per frame and hit, hurt or custom boxes. Pack & Export then writes the files Godot 4, Unity 6, Phaser, PixiJS, LÖVE and other targets load. Painting pixels happens in the Pixel workspace of the same project.

- Godot 4Verified· Godot 4.7.2
- Unity 6Verified· Unity 6000.5.3f1
- Phaser 3 / 4Verified· Phaser 3.90 + 4.2
- PixiJS 8Verified· PixiJS 8.21
- Aseprite JSONVerified· Phaser load.aseprite · PixiJS 8.21
- .asepriteVerified· Aseprite 1.3.18
- Spine / libGDXVerified· spine-canvas 4.2
- Starling / Sparrow XMLVerified· Phaser 4.2
- LÖVEVerified· LÖVE 11.5
- DefoldBuilt· Defold bob.jar 1.13.1
- GameMakerUNVERIFIED
- CSS spritesVerified· Chromium
- GIF / APNGDecoded· Pillow
What a game-ready sprite needs besides pixels
An engine does not play a picture; it plays a list of frames. Each frame needs its rectangle on a texture, the canvas it belongs to (so a trimmed frame lands where it was drawn), a pivot that says which pixel sits on the object's position, and a duration. An animation is a named run of frames with a direction and a repeat count. Hit and hurt boxes are extra rectangles per frame that game code checks.
The Studio keeps exactly that document. A sheet is one shared image and its frames are regions of it, so reordering or re-tagging never touches pixels. A pivot is stored as 0–1 of the frame canvas (bottom-centre 0.5, 1.0 unless you set it), durations are milliseconds (100 by default, as in Aseprite), and a tag's repeat follows Aseprite: 0 loops, n plays n times. Every automatic guess on import is listed with its confidence and one-click alternatives, and Apply is one undo step.
Each export target writes what its engine can read and says what it cannot carry: Godot gets per-frame durations and boxes in resource metadata, Unity gets per-frame pivots and one clip per tag but no boxes, Defold plays one FPS per animation.
- Tag
- A named run of frames with a direction (forward, reverse, ping-pong) and a repeat count.
- Pivot
- The point of a frame that sits on the object's position; stored as 0–1 of the frame canvas.
- Frame canvas
- The full size a frame is drawn on, even when only its opaque part is packed.
Example: one 384 × 256 sheet to a Godot 4 bundle
A sheet of 8 columns × 4 rows of 48 × 64 frames, one move per row.
Import grid 48 × 64, margin 0, gap 0 · 32 frames · one animation per row
Timeline rows renamed idle, run, jump, attack
idle 8 × 100 ms = 800 ms, repeat 0 (loop)
attack 7 × 100 ms + frame 5 held 250 ms = 950 ms, repeat 1 (plays once)
Pivot bottom-centre (0.5, 1.0) = pixel (24, 64) on every frame
Hit box attack frames 4–6: 16 × 12 px at (34, 30), same box id on all three
Export Godot 4 → hero.tres (4 animations) + hero.png + hero.tscn + hero.png.import
attack in Godot: loop off; idle: loop onThe same project exports again for Unity or Phaser without redoing the timeline. What happens in Godot next is on Aseprite to Godot and sprite sheets in Godot.
What it does
- Imports sheets, numbered frame files, GIF and APNG (every frame and delay), .aseprite (layers, tags, durations, slices), Aseprite JSON, TexturePacker JSON and Starling XML.
- An Aseprite-style timeline: tags with direction and repeat, per-frame durations, reorder, duplicate, flip.
- Playback with loop, ping-pong and repeat, onion skin and a floating preview at 1×–8×.
- Pivots, hit / hurt / custom boxes and collision polygons per frame, tag or selection.
How to do it
- Drop your sheet, frames or .aseprite file here.
- Apply the import (or pick one of the alternatives it lists).
- Name animations on the timeline, set durations, pivots and boxes.
- Open Pack & Export, choose your engine and export.
Check the result
- Play every tag with Enter before export; each frame shows for its own milliseconds, and a play-once tag stops on its last frame.
- In Pack & Export read the line under the target: "Loaded in Godot 4.7.2" (or UNVERIFIED in amber for GameMaker) and any setting the target changes before export.
- After export read the notes: they list what the target could not carry, such as differing pivots in one Godot animation or boxes that Unity does not receive.
- Open the result in the engine and play one tag next to Nerulio's preview at the same zoom.
Troubleshooting
| Symptom | Likely cause | How to check | Fix |
|---|---|---|---|
| The proposed grid is wrong | Uneven gaps, or sprites of mixed sizes on a sheet that looks like a grid | The decision shows medium or low confidence, with reasons about split or crossed cells | Pick an alternative or Islands; see slicing that is off |
| An .aseprite file arrives flattened | Its layers do not compose exactly in the Studio (5 of 231 test files), or cels use z-index (4 of 231) | The import panel states the reason | Frames and timing are still right; keep layered editing in Aseprite and re-import |
| Boxes or pivots are missing in the engine | The target has no place for them: Unity gets pivots but no boxes, Defold and CSS get neither | The export notes under the button | Export the Godot bundle or the generic JSON for boxes, or add them in the engine |
| The character hops when the animation changes | Frames have different pivots but the Godot scene node has one offset | The Godot export notes warn about differing pivots | Use one pivot for the tag, see pivots per frame |
Other ways to do it
| Option | When it is the better choice |
|---|---|
| Aseprite, then its File › Export Sprite Sheet and an engine plugin | You draw and animate in Aseprite anyway and your engine has a maintained importer; plugins that call Aseprite need it installed on every machine that imports. |
| TexturePacker | You mainly pack many separate images into atlases for many frameworks and want its command-line automation; it does not edit tags, pivots per frame or boxes the way a sprite editor does. |
| The engine's own editors (Unity Sprite Editor, Godot SpriteFrames panel) | One or two animations with even timing that you prefer to set up inside the project. |
Engine exports and how each was checked
"Verified" means the exported files were loaded by the real engine or tool on real CC0 assets and the result was compared with the source. Anything that was not loaded is labelled as such.
| Target | Files | Check |
|---|---|---|
| Godot 4 | .tres SpriteFrames · .tscn AnimatedSprite2D · .png.import | Verified Godot 4.7.2Loaded by Godot; every animation frame drawn and compared with the source file. The scene uses Nearest filtering; rotation is never used. |
| Unity 6 | .unity.json · Editor/NerulioSpriteImporter.cs · AnimationClip | Verified Unity 6000.5.3f1Batch mode: sprite rects, pivots, pixels, clip keys and durations checked. |
| Phaser 3 / 4 | atlas JSON (multiatlas) · .anims.json | Verified Phaser 3.90 + 4.2Frames and animations drawn by both versions. |
| PixiJS 8 | spritesheet JSON · animations · anchor · meta.scale | Verified PixiJS 8.21Rotated and multi-page atlases included. |
| Aseprite JSON | hash / array · frameTags · slices | Verified Phaser load.aseprite · PixiJS 8.21Tags keep their direction and repeat count. |
| .aseprite | layers · tags · durations · slices | Verified Aseprite 1.3.18Opened and rendered by the Aseprite command line. |
| Spine / libGDX | .atlas | Verified spine-canvas 4.2Every region drawn by the Spine runtime, rotated and trimmed; libGDX itself was not run. |
| Starling / Sparrow XML | XML per page | Verified Phaser 4.2Phaser 3.90 draws trimmed XML frames wrongly (its own bug); the "Sparrow XML (Phaser 3)" preset turns trim off and passes in 3.90 and 4.2. |
| LÖVE | Lua quads · nerulio_atlas.lua · main.lua | Verified LÖVE 11.5Every frame drawn and every animation stepped through the shipped helper. |
| Defold | .atlas · .tilesource | Built Defold bob.jar 1.13.1Built by Defold's command-line builder; the built texture's UVs were read back. |
| GameMaker | spr_<name>_stripN.png · gamemaker.json | UNVERIFIEDNot loaded in GameMaker (no headless GameMaker). The strips are cut the way its strip importer cuts them. |
| CSS sprites | .css · preview .html | Verified ChromiumEvery class drawn from the shipped stylesheet. |
| GIF / APNG | one file per animation | Decoded PillowEvery frame and delay decoded again after export; APNG is exact. |
Evidence
GIF decoder: 408 of 408 frames identical to Pillow on 29 real GIFs; APNG 132 of 132 on 16 files. .aseprite: 231 corpus files imported, re-written and reopened in Aseprite 1.3.18 with the same tags, durations and pixels (231/231). Exports: 49 runs in the real engines on real CC0 assets, 47 pass — the 2 failures are Phaser 3.90's trimmed-XML bug, which the Phaser 3 preset avoids.
Limits
- Rotated frames from an imported atlas stay rotated, and exporting them is UNVERIFIED; repack without rotation.
- GameMaker strips are not verified in GameMaker itself.
- Painting tools live in the Pixel workspace, which lacks some Aseprite tools (layer groups, tilemap layers, RotSprite, text).
- A grid or island guess is a preview with a confidence; nothing is cut until you press Apply, and every choice has one-click alternatives.
- .aseprite files whose layers do not compose exactly (e.g. group opacity) are imported flattened, and the Import panel says why.
- Rotated frames in an imported atlas stay rotated; their export is UNVERIFIED.
- Images up to 32,768 px per side (268 million pixels), subject to your browser's memory.
Versions and sources
Import: frames correct on 16 of 16 real assets with the default choices; 231 of 231 .aseprite files came back from Nerulio's writer into Aseprite 1.3.18 with the same tags, durations and pixels. Export: 47 of 49 engine runs pass (Godot 4.7.2, Unity 6000.5.3f1, Phaser 3.90 and 4.2, PixiJS 8.21, LÖVE 11.5, Spine runtime 4.2, Defold bob.jar 1.13.1); the two failures are Phaser 3.90's bug with trimmed Sparrow XML, which the Sparrow XML (Phaser 3) preset avoids.
Official documentation used
Classic tool
Outline, de-fringe and a ZIP of frame PNGs are still in the classic Sprite Lab.
Open the classic tool →Questions
How is this different from Aseprite?
This workspace is the step between your art and the engine: slicing, timing, pivots, boxes, packing and engine files, and it reads and writes .aseprite. Painting is in the Pixel workspace of the same project, which has the core Aseprite tools but not all of them.
Does it keep my Aseprite tags and durations?
Yes. On the 231-file .aseprite test corpus, tags and durations came back 231/231 when the Studio's output was opened in Aseprite 1.3.18.
Is it free, and do I need an account?
Everything on these pages is free and works without an account. There is no watermark and no export that is held back.
Are my sprites uploaded?
No. The Studio decodes, packs and exports in this browser tab. Projects are autosaved in the browser (IndexedDB) and can be saved as a .nerulio file.
Does it need Aseprite or an engine plugin installed?
No. .aseprite files are read and written in the browser, and each engine bundle carries what that engine needs (for Godot, the import settings and scene; for Unity and the Godot TileSet, a small editor script).