{"id":13520488,"url":"https://github.com/webtoon/psd","last_synced_at":"2025-05-15T01:09:23.012Z","repository":{"id":36959207,"uuid":"442669159","full_name":"webtoon/psd","owner":"webtoon","description":"Fast zero-dependency PSD parser for the web and Node.js","archived":false,"fork":false,"pushed_at":"2024-02-05T12:57:30.000Z","size":51134,"stargazers_count":1259,"open_issues_count":41,"forks_count":57,"subscribers_count":16,"default_branch":"main","last_synced_at":"2025-05-15T01:09:17.623Z","etag":null,"topics":["javascript","parser","photoshop","psb","psb-parser","psd","psd-parser","typescript","web"],"latest_commit_sha":null,"homepage":"https://webtoon.github.io/psd","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/webtoon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-12-29T05:26:25.000Z","updated_at":"2025-05-14T15:02:35.000Z","dependencies_parsed_at":"2024-09-20T19:31:22.126Z","dependency_job_id":"df4d0be3-b80f-408c-bdc2-463b1111b325","html_url":"https://github.com/webtoon/psd","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webtoon%2Fpsd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webtoon%2Fpsd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webtoon%2Fpsd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webtoon%2Fpsd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/webtoon","download_url":"https://codeload.github.com/webtoon/psd/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254254043,"owners_count":22039792,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","parser","photoshop","psb","psb-parser","psd","psd-parser","typescript","web"],"created_at":"2024-08-01T05:02:22.275Z","updated_at":"2025-05-15T01:09:18.003Z","avatar_url":"https://github.com/webtoon.png","language":"TypeScript","readme":"\u003cp align=\"center\"\u003e\u003cimg src=\"./images/webtoon-psd-logo.png\" height=\"128\" /\u003e\u003c/p\u003e\n\n# @webtoon/psd\n\n[![Package on NPM](https://img.shields.io/npm/v/@webtoon/psd)](https://www.npmjs.com/package/@webtoon/psd) [![Minified size](https://img.shields.io/bundlephobia/min/@webtoon/psd)](https://bundlephobia.com/package/@webtoon/psd)\n\n\u003e A lightweight Adobe Photoshop .psd/.psb file parser in typescript with zero-dependency for web browsers and NodeJS\n\n`@webtoon/psd` is a fast, lightweight parser for Adobe Photoshop PSD/PSB files. It uses standard (ES2015+) features and can be used both in web browsers and in Node.js. It pulls in zero dependencies, making it smaller ([~100 KiB minified](https://bundlephobia.com/package/@webtoon/psd)) than other PSD parsers ([ag-psd]: [200 KiB](https://bundlephobia.com/package/ag-psd@15.0.0), [PSD.js]: [443 KiB](https://github.com/meltingice/psd.js/blob/master/dist/psd.min.js)). It uses WebAssembly to speed up decoding image data.\n\n[ag-psd]: https://github.com/Agamnentzar/ag-psd\n[psd.js]: https://github.com/meltingice/psd.js\n\n## Browser Support\n\n| Chrome | Firefox | Safari | Edge | Node |\n| :----: | :-----: | :----: | :--: | :--: |\n|   57   |   52    |   11   |  79  |  12  |\n\n\\*Internet Explorer is not supported\n\n## Installation\n\n```bash\n$ npm install @webtoon/psd\n```\n\n## Benchmarks\n\nYou can run [benchmarks for @webtoon/psd in your browser](https://webtoon.github.io/psd/benchmark/).\n\n## Features\n\n#### ✅ Supported\n\n- Support large format (`.psb`)\n- Image / Layer information (size, offset, etc.)\n- Image / Layer pixel data\n- Unicode layer names\n- Image / Layer opacity\n- Text layers string value\n- Guides\n- Slices\n\n#### 🚧 Work in progress\n\n- Layer effects (shadow, overlays, etc.)\n\n#### ❌ Unsupported\n\n- Photoshop metadata not directly related to the image\n\n## Usage\n\n`@webtoon/psd` is provided as a pure ECMAScript module.\n\n### Web Browsers\n\nCheck out the [live demo](https://webtoon.github.io/psd) ([source code](https://github.com/webtoon/psd/tree/main/packages/example-browser)) for web browser.\n\n`@webtoon/psd` must be bundled with a bundler such as Webpack or Rollup.\n\n`@webtoon/psd` reads a PSD file as an `ArrayBuffer`. You can use `FileReader` or `File` to load a PSD file:\n\n```ts\nimport Psd from \"@webtoon/psd\";\n\nconst inputEl: HTMLInputElement = document.querySelector(\"input[type='file']\");\ninputEl.addEventListener(\"change\", async () =\u003e {\n  const file = inputEl.files[0];\n\n  const result = await file.arrayBuffer();\n  const psdFile = Psd.parse(result);\n\n  const canvasElement = document.createElement(\"canvas\");\n  const context = canvasElement.getContext(\"2d\");\n  const compositeBuffer = await psdFile.composite();\n  const imageData = new ImageData(\n    compositeBuffer,\n    psdFile.width,\n    psdFile.height\n  );\n\n  canvasElement.width = psdFile.width;\n  canvasElement.height = psdFile.height;\n\n  context.putImageData(imageData, 0, 0);\n  document.body.append(canvasElement);\n});\n```\n\nFor performance, we recommend parsing PSD files in a [Web Worker](https://developer.mozilla.org/docs/Web/API/Web_Workers_API) rather than the main thread.\n\n### NodeJS\n\nCheck out the [source code for the Node.js example](https://github.com/webtoon/psd/tree/main/packages/example-node) for web browser.\n\n`@webtoon/psd` does not support the Node.js `Buffer`. You must explicitly supply the underlying `ArrayBuffer`.\n\n```ts\nimport * as fs from \"fs\";\nimport Psd from \"@webtoon/psd\";\n\nconst psdData = fs.readFileSync(\"./my-file.psd\");\n// Pass the ArrayBuffer instance inside the Buffer\nconst psdFile = Psd.parse(psdData.buffer);\n```\n\nSince `@webtoon/psd` is provided as an ES module, you must use dynamic `import()` or a bundler to run it in CommonJS code:\n\n```ts\nconst Psd = await import(\"@webtoon/psd\");\n```\n\n## API Docs\n\nThis library provides the `Psd` class as the default export.\n\n### Opening a file\n\n`Psd.parse(ArrayBuffer)` takes an `ArrayBuffer` containing a PSD or PSB file and returns a new `Psd` object.\n\n```ts\nconst psdFile = Psd.parse(myBuffer);\n```\n\n### Traversing layers\n\nA `Psd` object contains a tree of `Layer` and `Group` (i.e. layer group) objects.\n\n- The `Psd` object provides a `children` property, which is an array of top-level `Layer`s and `Group`s.\n- Each `Group` object provides a `children` property, which is an array of `Layers` and `Group`s that belong immediately under the current layer group.\n- `Psd`, `Group`, and `Layer` objects provide a `type` field, which can be used to discriminate each type:\n\n```ts\nimport Psd, {Node} from \"@webtoon/psd\";\n\n// Recursively traverse layers and layer groups\nfunction traverseNode(node: Node) {\n  if (node.type === \"Layer\") {\n    // Do something with Layer\n  } else if (node.type === \"Group\") {\n    // Do something with Group\n  } else if (node.type === \"Psd\") {\n    // Do something with Psd\n  } else {\n    throw new Error(\"Invalid node type\");\n  }\n\n  node.children?.forEach((child) =\u003e traverseNode(child));\n}\n\ntraverseNode(psdFile);\n```\n\nThe `Psd` object also provides the `layers` property, which is an array of all `Layer`s in the image (including nested).\n\n```ts\nfor (const layer of psdFile.layers) {\n  doSomething(layer);\n}\n```\n\n### Decoding image data\n\nUse `Psd.prototype.composite()` and `Layer.prototype.composite()` to decode the pixel information for the entire image or an individual layer.\n\nNote that for `Psd.prototype.composite()` to work, PSD/PSB files need to be saved in \"Maximize Compatibility\" mode. Otherwise, it will return no data. You can enable it in `Preferences \u003e File Handling \u003e File Compatibility \u003e Maximize PSD and PSB File Compatibility`\n\n```ts\n// Decode the pixel data of the entire image\npixelData = await psd.composite();\n\n// Extract the pixel data of a layer, with all layer and layer group effects applied\n// (currently, only the opacity is supported)\nlayerPixelData = await layer.composite();\n\n// Extract the pixel data of a layer, with only the layer's own effects applied\nlayerPixelData = await layer.composite(true, false);\n\n// Extract the pixel data of a layer, without any effects\nlayerPixelData = await layer.composite(false);\n```\n\n## License\n\n`@webtoon/psd` is released under the [MIT license](https://github.com/webtoon/psd/blob/main/LICENSE).\n\n```\nCopyright 2021-present NAVER WEBTOON\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n```\n","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebtoon%2Fpsd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwebtoon%2Fpsd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebtoon%2Fpsd/lists"}