@polotno/psd-import
v0.3.2
Published
Convert Photoshop PSD files into editable Polotno JSON designs while preserving text, vector, and raster layers
Readme
@polotno/psd-import — PSD to editable Polotno JSON
Parse a Photoshop .psd file and convert it into a JSON document that matches the Polotno schema. Works in the browser and in Node.
Works without the editor. The converter returns plain Polotno design JSON.
Runtime: Browser and Node.js. Conversion runs locally.
Documentation · Try PSD to JSON in your browser
License: Non-production use is free, with no time limit. Production use requires a valid Polotno subscription. Read the license.
Install
npm install @polotno/psd-importUsage
psdToJson accepts an ArrayBuffer or Uint8Array of PSD bytes and returns a Polotno-schema JSON document.
Browser — read bytes from a file input:
import { psdToJson } from '@polotno/psd-import';
const file = input.files[0];
const buffer = await file.arrayBuffer();
const json = await psdToJson({ psd: buffer });
// Optional: load into a Polotno store
store.loadJSON(json);Node.js — read bytes from disk:
import { readFile } from 'node:fs/promises';
import { psdToJson } from '@polotno/psd-import';
const buffer = await readFile('./design.psd');
const json = await psdToJson({ psd: buffer });The returned object matches the Polotno JSON schema: { width, height, fonts, pages, unit, dpi }.
Parse errors
If the parser cannot read the file, psdToJson throws an Error with code: 'IMPORT_FAILED' and details.format: 'psd'.
The original parser error remains available as cause.
If a recognized PSD or PSB header or a declared section exceeds the available bytes, the error also includes details.reason: 'truncated'.
Applications can use this reason to ask the user for a complete copy of the file.
The reason identifies missing bytes but does not establish how the file lost them.
The detection runs only after the parser fails, so recoverable files still convert.
The detection covers the header, color data, image resources, and layer and mask data.
It does not detect missing bytes inside the final composite image section, which has no section length.
If the file is complete but its compressed image data does not decompress (for example, a zlib checksum mismatch), the error includes details.reason: 'corrupt'.
If the file is valid but uses something the parser (ag-psd) cannot read, the error includes details.reason: 'unsupported'.
This covers the Lab, Duotone and Multichannel color modes, and more than 16 channels: the PSD format allows up to 56 (color plus alpha and spot channels).
Converting the document to RGB or CMYK, or deleting extra alpha or spot channels, in Photoshop avoids it. A complete copy of the same file fails the same way, so this reason takes precedence over truncated.
If the decoded layer pixels would exceed the parser's memory budget (ag-psd's default of 2 GiB), the error includes details.reason: 'too-large'.
Applications can use this reason to tell the user the file is too large to import; flattening or cropping the document, or reducing its size or bit depth, in Photoshop avoids it. This reason also takes precedence over truncated.
Other parser errors have no details.reason. Applications must not treat every IMPORT_FAILED error as truncation, corruption, an unsupported file or an oversized file.
How it works
The goal is to keep as many of the PSD's layers as separate, editable elements as possible, instead of flattening the file into a single image. Each PSD layer is mapped to the closest equivalent in the Polotno schema:
- Text layers stay as editable text — font family, weight, style, size, color, alignment, line height, and letter spacing carry over. A layer that mixes styles becomes one rich-text element with styled spans. Color and linear gradient overlays and strokes become the text's fill and stroke.
- Shape and vector layers become SVG elements with their fills, gradients, and strokes preserved.
- Raster layers become images. When a layer uses effects the schema can't represent natively (gradient/color overlays, gradient maps, hue/saturation, brightness/contrast, …), the effect is baked into that layer's pixels so it still looks right while every other element remains separate.
- Groups become Polotno groups with their opacity and blend mode, so the layer hierarchy survives. A pass-through group stays pass-through, unless it is faded and nothing inside it blends, when it is faded as one unit; any other mode isolates the group, as in Photoshop.
- Masks and group effects are applied to the layers underneath them, so masked content and folder-level overlays render correctly without collapsing the document. A masked group that holds only raster layers is composited into one image.
- Blend modes pass through where the schema supports them; unsupported modes are flattened only with the layers they depend on.
- Adjustment layers (levels, curves, exposure, invert, posterize, threshold, hue/saturation with its color ranges and colorize, brightness/contrast, black & white, gradient map) are baked into the layers they reach. In a CMYK document, tone adjustments run on the ink plates, as in Photoshop.
- Transparent documents (no Background layer) import with a transparent page, so layers blend over transparency as in Photoshop and PNG export keeps it.
The PSD's pre-rendered composite image is intentionally not used — every element stays selectable and editable.
License
See LICENSE.md.
