@nitishbhosale7/psd
v1.0.1
Published
A friendly fork of @webtoon/psd: a zero-dependency Adobe Photoshop .psd/.psb parser with a normalized, well-named API for blend modes, layer effects, text styling, visibility, and group bounds.
Maintainers
Readme
@nitishbhosale7/psd
A friendly fork of
@webtoon/psd— a fast, zero-dependency Adobe Photoshop.psd/.psbparser for browsers and Node.js — with a normalized, well-named API layered on top.
@webtoon/psd parses PSDs correctly and completely, but a lot of the useful data comes out in Adobe's raw form: blend modes as 4-char codes ("norm", "mul "), layer effects and fills as nested descriptor Maps keyed by codes like "SoFi" / "Md " / "Clr ", text styling buried in EngineData, and layer groups that expose no bounds. This fork keeps the original parser intact and adds clean getters so you don't have to decode any of that yourself.
Install
npm install @nitishbhosale7/psdWhat this fork adds
All additions are plain getters on the existing Layer and Group nodes — the rest of the @webtoon/psd API is unchanged.
| Member | On | Description |
| ----------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| blendModeName | Layer, Group | Friendly blend-mode name, e.g. "normal", "multiply" (vs. the raw blendMode code). |
| visible | Layer, Group | Convenience inverse of isHidden (works for groups too). |
| isClipped | Layer, Group | true when clipped to the layer below. |
| effects | Layer, Group | Normalized { colorOverlay?, dropShadow?, stroke? } with named fields (color {r,g,b} 0–1, opacity, angle, distance, blur, spread, blend mode, stroke position) — parsed from the lfx2 effects descriptor. |
| textStyle | Layer | Normalized text styling: { fontName, fontStyle, fontSize, color {r,g,b,a}, tracking, leading, autoLeading, alignment, isParagraph } — parsed from EngineData. |
| left / top / width / height | Group | Bounding box computed from a group's descendants (upstream groups expose none). |
Example
import Psd from "@nitishbhosale7/psd";
const psd = Psd.parse(arrayBuffer);
function walk(node) {
if (node.type === "Layer") {
console.log(node.name, {
visible: node.visible,
blend: node.blendModeName,
effects: node.effects, // e.g. { colorOverlay: { color: {r:1,g:1,b:1}, opacity: 100, blendMode: "normal" } }
text: node.textStyle, // e.g. { fontName: "SamsungSSHead-Bold", fontSize: 75, alignment: "center", ... }
});
}
if (node.type === "Group") {
console.log(
node.name,
"bounds:",
node.left,
node.top,
node.width,
node.height,
"visible:",
node.visible
);
}
for (const child of node.children ?? []) walk(child);
}
walk(psd);Everything else (parsing, composite(), masks, image resources, EngineData, raw descriptors) behaves exactly like @webtoon/psd. See the upstream docs for the base API.
Credits
This is a fork of @webtoon/psd by NAVER WEBTOON. All of the heavy lifting — the binary parser and the Rust/WASM decoder — is their work. This fork only adds a convenience layer and keeps the original tests passing.
License
Released under the MIT License.
Copyright 2021-present NAVER WEBTOON
Copyright 2026-present Nitish Bhosale (modifications)