PhotoCraft: a Photoshop reimplementation in Rust, and what its PSD claim actually measures
An open-source, clean-room reimplementation of Adobe Photoshop in pure Rust
At a glance
- What is it?
- A clean-room image editor built as a Cargo workspace of two dozen Rust crates, with a wgpu compositor, sixteen adjustment layers and a PSD codec. Early alpha, two license declarations, and a fidelity number worth reading closely.
- Who is it for?
- PhotoCraft is worth a look if you want a layered editor you can compile, inspect and script, and you are willing to accept early alpha behaviour while a single large file changes often. The engine is genuinely native Rust on wgpu, the crate boundaries are sensible, and the automation channel means the same operations run from the UI or from a JSON command.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 6, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A clean-room Photoshop is a bold claim to put on a badge
The positioning line is blunt: image editing, an open-source, clean-room reimplementation of Adobe Photoshop, rebuilt in pure Rust, with layers, masks, adjustment layers, layer styles, type, vectors, brushes and real PSD files in a native app. A badge marks the project as 100 percent Rust, and a second badge lists macOS, Windows, Linux, FreeBSD and Web as targets. A third marks the status as early alpha.
Clean-room is doing real work in that sentence. It means the implementation was written from documentation and observation of file formats rather than derived from Adobe's code, which is the only way to ship something under an open licence that sits this close to a commercial product. The tree backs up the scale of the claim: alongside `Cargo.toml` and `Cargo.lock` there are `crates/`, `apps/`, `xtask/`, `docs/`, a `book/`, `perf/`, `packaging/`, `scripts/`, `scorecard/`, `examples/plugins/`, an `AGENTS.md`, an `ATTRIBUTION.md`, a `SECURITY.md`, plus `clippy.toml` and `rustfmt.toml`. That is the shape of a project with release engineering, not a prototype.
The repository is not archived, the last push was on 2026-10-06, and the release cadence is a matter of days: v0.1.1-rc.5 on 2026-10-02, v0.1.1 on 2026-10-03, and v0.2.0 on 2026-10-05.
The Cargo workspace is the architecture
The single most useful file for judging the project is the workspace manifest, because it names every subsystem and its exact path:
[workspace]
resolver = "3"
members = ["crates/*", "apps/*", "xtask"]
default-members = ["crates/*", "apps/photocraft-cli", "xtask"]The workspace pulls in every directory under `crates/` and `apps/`, but the default member set is narrower: the crates, the CLI app, and the build task. That is a deliberate choice about what a bare checkout builds.
The package metadata sits right below it:
[workspace.package]
version = "0.2.0"
edition = "2024"
license = "MIT OR Apache-2.0"
rust-version = "1.90"Two facts fall out of that immediately. Building anything here needs a recent toolchain, edition 2024 with a stated minimum of Rust 1.90, which rules out a lot of older CI images. And the version in the manifest, 0.2.0, matches the newest published tag, so the branch and the release line agree at least on this.
The crate list reads like a layer stack. `photocraft-geom` and `photocraft-color` sit at the bottom, then `photocraft-cms` for colour management, `photocraft-raster` for pixel buffers, `photocraft-doc` for the document model, `photocraft-ops` for operations, `photocraft-psd` for the file format, `photocraft-codecs` and `photocraft-raw` for image decoding, `photocraft-compose` for the compositor, `photocraft-gpu` for the wgpu backend, `photocraft-paint` and `photocraft-algo` for painting and algorithms, `photocraft-text` and `photocraft-vector` for type and paths, and `photocraft-automation`, `photocraft-plugins` and `photocraft-engine` on top, with `photocraft-io`, `photocraft-format`, `photocraft-ui-egui`, `photocraft-testkit` and `photocraft-tablet` around them. Geometry has no dependency on the compositor, and the format crate does not need the UI, which is the kind of separation that makes an engine usable from outside the app.
Sixteen adjustment layers and the full layer style set
The feature grid describes a conventional layered editor rather than a toy. Adjustment layers are the centre of it: stack Levels, Curves, Vibrance and Hue/Saturation, mask them to an area, reorder or disable them, and the README states that the original pixels never change. Sixteen adjustment layers are listed, and they also apply directly to pixels. Named ones include Curves with per-channel editing, Levels with a live histogram, Black and White, Channel Mixer, Gradient Map, Photo Filter, Selective Color, and Color Lookup reading .cube, .3dl and .look files. Shadows/Highlights, Replace Color, Match Color, HDR Toning, Desaturate and Equalize fill out the rest.
Layer styles cover Drop Shadow, Inner Shadow, Outer Glow, Inner Glow, Bevel and Emboss, Satin, Stroke, and the colour, gradient and pattern overlays, all live on any layer including type. Patterns come from a library of built-ins, can be defined from the current selection through Edit then Define Pattern, import and export as .pat, and can also be read from the `Patt` block of a PSD. Styles copy between layers, all effects can be hidden at once, and styles opened from a PSD are described as rendered to match Photoshop.
Selections are the third pillar. Marquee, lasso and Magic Wand for manual precision; Quick Selection, Object Selection and Select Subject when the machine traces for you; Select and Mask to refine hair-fine edges. Feather, expand, contract, smooth, grow and reselect refine the result, and any selection can become a layer mask, a vector path or a shape. The README is specific that smart selection runs locally, with no cloud and no account.
The rendering claim is a GPU compositor on wgpu across Metal, Vulkan, DX12 and WebGPU, with copy-on-write tiles and multithreaded filters, and the README states plainly that there is no Electron and no web view in the loop.
Every action is a command, so the UI is not the only front end
The design decision that makes this project more than a desktop app is that every action is a command. That means the same engine can be driven from four places: the graphical interface, the command line through `apps/photocraft-cli`, a JSON control channel, and an MCP server. The `photocraft-automation` and `photocraft-plugins` crates exist to make that possible, and the README notes that every screenshot in its feature grid was produced by rendering offscreen through the control channel rather than by hand-capturing the app.
That has an obvious consequence for security, and v0.2.0 handles it in a way worth knowing about before you script anything. As of that release, published on 2026-10-05, file access from automation clients is limited to folders you grant with `--automation-read-root <dir>` and `--automation-write-root <dir>`, or the matching `PHOTOCRAFT_AUTOMATION_READ_ROOT` and `PHOTOCRAFT_AUTOMATION_WRITE_ROOT` environment variables, and paths must be relative to those roots. Without roots, automation file operations fail closed rather than falling back to somewhere else. The desktop control channel also requires the per-launch token printed at startup. Interactive file dialogs and one-shot CLI commands are unaffected.
So the upgrade note for v0.2.0 is a breaking change for anyone who had a working automation setup on v0.1.1. If you are evaluating this project, the specific thing to check is whether the roots requirement has been threaded through whatever you intended to drive. The release notes also cover camera RAW work in the same entry: DNG, Canon CR2, Sony ARW in both lossless and compressed forms, Panasonic RW2 and uncompressed Olympus ORF now decode, while Nikon's compressed NEF and other formats still open only their embedded full-size preview.
Reading the 307 of 309 psd-tools figure
The fidelity claim is one sentence: re-saving keeps the render of 307 of the 309 psd-tools test files. That is a more meaningful number than most claims in this category because it names the corpus, and `psd-tools` is a third-party Python library with a published set of PSD files, so the comparison is against files PhotoCraft did not author.
It is also a number that needs reading carefully, and here is the honest version. Two of 309 files do not keep their render on re-save. That is roughly 0.6 percent, which is a good result, but the README does not say which two, whether they fail on read or on write, or whether the failure is a missing feature or a diff in a layer effect. For a workflow that round-trips real client files, that is the gap you need closed before you trust it, and the practical way to find out is to run your own files through `apps/photocraft-cli` and compare, because the corpus result says nothing about the specific PSD constructs your agency receives.
There is also an implicit scope limit in the same sentence. The claim is about the render being preserved on re-save. It is not a claim that every Photoshop feature round-trips, that the layer panel is identical, or that a file opens in Adobe products with the same editability afterwards. Photoshop is roughly three decades of accumulated behaviour; a clean-room reimplementation reaching visual parity on a test corpus is a different claim from reaching feature parity with the application.
The rest of the README points at documentation rather than spelling it out. The navigation links at the top of the page point to sections including Everything in the box, PSD without compromise, Built for agents, Under the hood and Get started, and the page itself is largely HTML tables, badge images and screenshots, with project pages hosted on getartcraft.com alongside a parent ArtCraft project and a list of other apps. Where the README stops, the hosted documentation and the repository itself take over, which is why the crate list and the release notes carry more of the reviewable detail than the front page does.
Two license declarations that do not agree, and a badge that lags the release
License is the one place where the project's own pages contradict each other, so a reader has to hold both facts.
The repository page records the license as Apache-2.0. The README badge says MIT OR Apache-2.0. The workspace manifest says the same as the badge, and the root of the tree carries both licence texts:
LICENSE-APACHE
LICENSE-MIT
NOTICETwo independent signals inside the repository, the manifest string and the presence of both licence files, agree with the badge. That is what a genuine dual-licence project looks like on disk. The single Apache-2.0 entry on the repository page is the outlier, and it is the kind of field that can reflect a classifier default rather than a legal decision. If licence terms matter to you, read the two files at the root and note that Apache-2.0 carries an explicit patent grant and NOTICE obligations that MIT does not, so the choice between them is a real choice rather than a formality.
The second gap is between identity and status. The repository is `storytold/photocraft`, but the README is branded ArtCraft: the logo image is an ArtCraft logo, the headline links go to a PhotoCraft page on getartcraft.com next to ArtCraft and a list of all Crafting Apps, and the community note invites people to a Discord under the ArtCraft name. Meanwhile a status badge still reads early alpha three days after v0.2.0 shipped, and the topic list includes `adobe-photoshop-2026` and `adobe-photoshop-2026-ai` alongside sensible ones like `image-editor`, `psd` and `rust`, which looks like machine tagging of a future product name rather than hand-picked keywords.
Neither gap is a defect. Both mean the same thing for a reader: decide on the licence from the files at the root rather than from the repository sidebar, and treat the ArtCraft branding and the early alpha badge as the project's own framing rather than as independent assessments of readiness.
Editorial conclusion
PhotoCraft is worth a look if you want a layered editor you can compile, inspect and script, and you are willing to accept early alpha behaviour while a single large file changes often. The engine is genuinely native Rust on wgpu, the crate boundaries are sensible, and the automation channel means the same operations run from the UI or from a JSON command. Verify three things before depending on it: whether the 307 of 309 psd-tools render figure holds for the specific PSDs you need, whether the dual MIT and Apache-2.0 terms in `Cargo.toml` match the single Apache-2.0 entry on the repository page, and whether the v0.2.0 automation file-root requirement has been wired into whatever you planned to script. Start by reading `crates/psd`, `crates/engine` and `apps/photocraft-cli` in that order.
Frequently asked questions
What licence is PhotoCraft released under?
The repository page records Apache-2.0, while the README badge and the workspace manifest both say MIT OR Apache-2.0, and the tree carries LICENSE-APACHE, LICENSE-MIT and a NOTICE file. The files at the root are the reliable signal here, and the two licences differ enough in patent grant terms that choosing between them is a real decision.
Can PhotoCraft open and save real layered PSD files?
It can open, edit and save layered Photoshop documents. The README states that re-saving keeps the render of 307 of the 309 psd-tools test files, which is a measured result against a third-party corpus rather than an unqualified promise of Photoshop parity.
What does it take to build PhotoCraft from source?
It is a Cargo workspace in edition 2024 with a stated minimum toolchain of Rust 1.90, so a recent Rust install is required. The workspace members are every directory under crates/ and apps/ plus xtask, while the default member set is narrower: the crates, the photocraft-cli app, and xtask.
Can an agent or script drive PhotoCraft instead of the UI?
Yes. Every action is a command, so the same engine runs from the interface, a CLI, a JSON control channel or an MCP server. As of v0.2.0 automation file access is limited to roots you grant explicitly and fails closed without them, and the desktop control channel requires a per-launch token.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/storytold-photocraft)