engineering notes

How PSD layer writing actually works

We write layered PSDs in the browser, so we've been elbow-deep in the format. Here's what a real layered file contains, why one-layer fakes are so common, and what "non-destructive mask" physically means on disk.

See the writer in action

A PSD is four sections and a trap

The format is a 1990s-vintage container: a header, color/resource blocks, the LAYER AND MASK section, and a flattened composite image at the end. The trap is that last part: a valid PSD only NEEDS the flattened composite. Write your JPEG there, leave the layer section empty, and every viewer opens it happily as "Background". That is the one-layer fake, and it is why a .psd extension proves nothing.

What real layers require

Each layer is a record: bounds, blend mode, opacity, a Unicode name, and per-channel pixel data (compressed, usually RLE) — plus, optionally, a mask channel with its own bounds. Groups are bracket markers — hidden divider layers that viewers reconstruct into a tree. Getting Photoshop, Photopea, Affinity, GIMP, AND Krita to agree on your bytes means testing against all of their readers, because each tolerates different corners of Adobe's spec.

Masks: the difference between editable and baked

A cutout can be stored two ways: bake the transparency into the alpha channel (destructive: the hidden pixels are gone), or attach a MASK channel alongside untouched pixels (non-destructive — paint the mask white and the pixels come back). We write masks. It costs an extra channel per layer and is the single clearest tell of a converter that cares.

Independent read-back of our PSD showing groups and masks
Our output read back by an independent library: the masks are real channels.

Writing it in a browser

The writer (built on the open-source ag-psd) assembles the byte stream client-side: your pixels never leave the machine to become a PSD. Text layers are the deep end. They require Adobe's type-engine data structures, which is why our OCR-recovered text arrives as genuine editable type objects while most competitors settle for pixel snapshots of words.

Verify anyone's output — including ours

Open any converter's file in Photopea and count layers; then try toggling a mask. Or go full nerd: a real layered PSD's Layer section is typically the majority of the file size, while a fake is one composite image plus headers. Our companion piece (why most converters are fake) has the 30-second version of this test.

Frequently asked

Why does everyone target PSD instead of a sane modern format?

Network effects: PSD is the interchange format every tool imports. We also write OpenRaster (.ora) (a clean, documented zip of PNGs) for tools that respect it.

What library do you build on?

ag-psd, an excellent open-source TypeScript implementation, plus our own layer/group/mask assembly and cross-app compatibility testing on top.

Do you support every PSD feature?

No — nobody does. We write what layered editing needs: raster layers, groups, masks, opacity, blend modes, and text layers. Smart objects and adjustment layers are out of scope for a converter.

Related

Material separation for Live2D, with AI doing the boring halfYour product photos, as layered files you ownSplit a background into parallax planes for your 2D gameRemove the object, fill the background, and keep the objectCanva can't make layers from an image. Here's the workaround.Get image layers into PowerPoint: the clean wayMake a depth-effect wallpaper from your own imageSeparate the subject from the background, and keep bothPull the text out of an image — as text you can actually editMost "image to PSD" converters are fake. Here is the 30-second test.Color separation for screen printing, without the $500 softwareTurn a flat image into a PSD with real layersSplit any image into separate, editable layersSplit an image into layers — by object, or by colorAn AI layer separator that hands you a real fileTurn any image into a layered .ora for GIMP and KritaOne photo in. The layered file you actually need, out.