# Sprite sheet tool with a Phaser-ready atlas export (browser-only, nothing uploaded)

**URL:** <https://phaser.discourse.group/t/sprite-sheet-tool-with-a-phaser-ready-atlas-export-browser-only-nothing-uploaded/15669>\
**Category:** Showcase\
**Created:** [September 27, 2026, 3:34pm UTC](https://phaser.discourse.group/t/sprite-sheet-tool-with-a-phaser-ready-atlas-export-browser-only-nothing-uploaded/15669 "2026-09-27T15:34:58Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![spritesheetbuilder](https://avatars.discourse-cdn.com/v4/letter/s/fbc32d/32.png) [@spritesheetbuilder](https://phaser.discourse.group/u/spritesheetbuilder)\
**Post date:** [September 27, 2026, 3:34pm UTC](https://phaser.discourse.group/t/sprite-sheet-tool-with-a-phaser-ready-atlas-export-browser-only-nothing-uploaded/15669/1 "2026-09-27T15:34:58Z")

</div>

I maintain a free browser sprite sheet tool set and Phaser is the engine I tested the metadata export  
against, so here is the shortest useful path from a folder of frames to `load.atlas`, in case it saves  
someone an afternoon.

Pack the frames at [https://spritesheetbuilder.com/](https://spritesheetbuilder.com/) (grid or auto-pack, padding and spacing, live preview  
at 1–30 FPS), then export the atlas bundle. The JSON is TexturePacker-shaped, so the stock loader takes  
it:

```js
function preload() {
  this.load.atlas("hero", "assets/hero.png", "assets/hero.json");
}

function create() {
  const frames = this.textures.get("hero").getFrameNames(); // ["idle0001", ...]
  const idle = frames.filter((n) => n.startsWith("idle")).sort();

  this.anims.create({
    key: "idle",
    frames: idle.map((frame) => ({ key: "hero", frame })),
    frameRate: 12,
    repeat: -1
  });

  this.add.sprite(160, 120, "hero").play("idle");
}

```

Two things I would flag from building this, both of which cost me real time:

1. **Sort the frame names.** The loader returns them in atlas order, which for an auto-packed sheet is  
whatever order the packer placed them in. The animation runs, the poses are correct, and the sequence  
is shuffled — with no error to point at the cause.
2. **Frame records use `w`/`h`, not `width`/`height`.** Inside `frames.<name>.frame` the rect keys are  
`x/y/w/h`, with `spriteSourceSize` and `sourceSize` alongside. A loader copied from a Unity-shaped  
atlas silently produces zero-sized frames instead of failing.

Engine notes for the other exports (Unity editor importer, Godot `.tres` SpriteFrames) are collected at  
[Sprite Sheets for Unity, Godot & Phaser](https://spritesheetbuilder.com/engines).

Everything runs client-side — the files are never uploaded, which is the reason the tool exists in this  
shape rather than as a service. If you hit a Phaser case the export does not cover (rotated/trimmed  
frames in particular, which I deliberately do not emit), post it here and I will look at it.
