I translated 150 PSD files with Photopea, ag-psd and Claude Code
I had a project over the weekend: some designers sent me 150 PSD files representing playing cards that I needed to translate to french and export in various formats. The text layers in the PSD were all manually edited, sometimes with proper shape constraints and auto-layouting, but also lots of hacks as designers aren't tidy. Translating to french would make 20% of text layers overflow, english is more terse than french.
The designers' own export script, based of Photoshop, took 3h to export those 600DPI cards, to finally downsample to 300DPI.
I didn't want to spend 2 weeks on that job. I could feel I would need to revise the render several times, seeing some typos in the cards.
I discovered Photopea's Live Messaging API was the answer.
The Contenders
I was planning on automatically extracting the text, machine translating it, manually proofreading it, and then reinjecting the text with exact template driven text layers. Going from 2 weeks down to a weekend. I evaluated different approaches to do so:
- ag-psd: Parses and edits PSD data fast, but its text rasterization is inaccurate and doesn't handle effects, text within a shape etc. Not faithful to Photoshop.
- Skia: A bit more mature than ag-psd on text rasterization, but still not very accurate and no understanding of the PSD document structure.
- Headless Photoshop: Expensive. Licensing headaches. Slow. Not an option.
I needed actual Photoshop rendering, headless, scriptable, fast.
How Photopea's Live API Works
I used 10 playwright-cli to openphotopea.com/#<config>. Then:
- Send it a PSD as ArrayBuffer
- Send JavaScript snippets (real Photoshop scripting engine) to perform a variety of tasks
- Receive rendered PNGs/PSDs back as ArrayBuffers
You get Photoshop rendering without Adobe. Everything stays client-side.
The Reality Check
✅ Client-side (no data leaves)
✅ Full Photoshop scripting API
✅ Headless-friendly (Playwright integration)
✅ Fast (~2-3s per card to open 3MB files, transfer the text, fit it within the box and reexport)
❌ Can't copy/paste layers between documents (forked ag-psd to do this)
❌ Scripting API undocumented (reverse-engineered it)
❌ Font caching doesn't survive reboots—massive time sink
❌ No API to detect text overflow in shapes
❌ No easy way to push styled textRuns from an API
❌ Injected text rasters don't refresh (had to hack: resize layer 100→100 to force re-render)
What I Actually Did
- Resample all documents to 300DPI with a headless Photopea
- Extracted text via ag-psd
- Applied translations on extracted text
- Deleted all translated text layers to replace with accurate template driven contrained to shape layers via a forked custom version of ag-psd.
- With injected scripts in Photopea, measured actual rendered text and reduced the text size until it fitted within the template shape without overflows. For this, I checked text bounds against the path to check if it overflows.
- Exported faithful PNGs for print
Worth It?
For 150 cards: absolutely. Because 150 cards turned out to be 200 with the different revisions. There could be 1,000 for all I care, it's fast now. The pipeline can be adapted to any other project of mass PSD localization.
If you're doing PSD batch automation (localization, design tooling), the API is serviceable—just budget time for workarounds and font management.
Anyone else automating Photoshop? What did you wish you'd known?