PhotoCraft Web: Self-Host the WebAssembly Build
What the PhotoCraft web (WASM) build is, how to host photocraft-web.zip on any static server or Docker, browser requirements (WebGPU or WebGL2) and its limits.
PhotoCraft's whole engine and interface also compile to WebAssembly. Each release ships them as photocraft-web-<ver>.zip, a static website you can host on any web server, with no backend. Images are opened and edited on the visitor's own device and are never uploaded. The table above links the zip from the official GitHub release. To try the web build without hosting anything, open the online editor right here. Like the desktop app, the web build is early alpha.
What's in the zip
The zip contains one folder, photocraft-web-<ver>/:
| File | What it is |
|---|---|
index.html | The page. It loads everything through relative URLs. |
photocraft-web-<hash>.js | The wasm-bindgen glue (an ES module) |
photocraft-web-<hash>_bg.wasm | The app itself |
_headers, .htaccess | Sample header rules for Netlify / Cloudflare Pages and for Apache |
In v0.6.0, the .wasm is 25,145,515 bytes (just under 24 MiB) and the whole zip is 11,094,419 bytes (10.6 MiB). The project's only compressed figures are for the 0.2.x build, whose .wasm measured about 19 MiB raw, 8 MiB with gzip and 5.6 MiB with Brotli. The release script fails if the .wasm ever grows past 24 MiB, so it stays under the 25 MiB per-file limit of Cloudflare Pages and Workers.
Self-host it in four steps
-
Download
photocraft-web-<ver>.zipandSHA256SUMS.txtfrom the release, and check the zip:sha256sum -c --ignore-missing SHA256SUMS.txt # Linux shasum -a 256 photocraft-web-0.6.0.zip # macOS: compare with SHA256SUMS.txt -
Unzip it and try it locally:
unzip photocraft-web-0.6.0.zip cd photocraft-web-0.6.0 python3 -m http.server 8765Open http://localhost:8765/.
localhostcounts as a secure context, so WebGPU works here. -
Upload the folder's contents to any static host: nginx, Apache, Caddy, an S3-style bucket behind a CDN, Netlify, or Cloudflare Pages. Every URL is relative, so it works at a domain root (
https://example.com/) or under a path (https://example.com/tools/photocraft/) without rebuilding. -
Check it: open the page, open an image, and save or export it.
Server settings that matter
- MIME type: serve
.wasmasapplication/wasmand.jsastext/javascript. With the wrong type, browsers can't stream-compile the wasm, and the app loads slowly or not at all. For nginx, make suremime.typeshasapplication/wasm wasm;. - Compression: turn on gzip or Brotli for
.wasm,.jsand.html. On the 0.2.x build, that cut the.wasmdownload from about 19 MiB to 8 MiB (gzip) or 5.6 MiB (Brotli). - Caching: the
.wasmand.jsfile names contain a content hash, so give themCache-Control: public, max-age=31536000, immutable. Giveindex.htmlno-cacheso visitors pick up new versions. - HTTPS: WebGPU and the clipboard only work in a secure context (
https://orhttp://localhost). Over plain HTTP elsewhere, the app falls back to WebGL2. - No isolation headers needed: PhotoCraft doesn't use
SharedArrayBuffer, so you don't need COOP/COEP. If your site already sends COEPrequire-corp, also sendCross-Origin-Resource-Policyon the app's files.
The nginx example from the project's hosting guide:
location /photocraft/ {
types { application/wasm wasm; text/javascript js; text/html html; }
gzip on;
gzip_types application/wasm text/javascript text/html;
location ~* \.(wasm|js)$ { add_header Cache-Control "public, max-age=31536000, immutable"; }
location ~* index\.html$ { add_header Cache-Control "no-cache"; }
}
On Netlify, Cloudflare Pages or Apache, the bundled _headers and .htaccess files cover the same ground.
Hosting with Docker
The repository has a Dockerfile that builds the web app from source and serves it with nginx on port 8080. The project labels this recipe community-maintained: CI doesn't build it and releases don't use it, so it can lag behind the official zip. From a clone of the repository:
docker build --load -t photocraft-web:local .
docker run -d --name photocraft-web --restart unless-stopped \
-p 8080:8080 photocraft-web:local
Then open http://localhost:8080/. The first build takes several minutes. For a public deployment, put an HTTPS reverse proxy in front of it, and bind it to loopback (-p 127.0.0.1:8080:8080) when the proxy runs on the same host. The hosting guide covers build arguments and serving under a sub-path.
Embedding in another page
PhotoCraft fills whatever iframe you put it in:
<iframe
src="https://example.com/photocraft/"
title="PhotoCraft image editor"
style="width: 100%; height: 720px; border: 0;"
allow="fullscreen; clipboard-read; clipboard-write"
allowfullscreen>
</iframe>
A sandboxed iframe needs at least allow-scripts allow-same-origin allow-downloads allow-popups. Without allow-downloads, Save and Export are blocked. Don't send X-Frame-Options: DENY from the PhotoCraft host.
Browser requirements
You need a browser with WebGPU or WebGL2. PhotoCraft renders with wgpu: it uses WebGPU when the browser has it and falls back to WebGL2 on its own. A browser with neither gets a message instead of the app. Add a flag to the URL to override the choice:
| URL | Effect |
|---|---|
| (no flag) | WebGPU if available, otherwise WebGL2 |
?webgl | Force WebGL2, useful when a WebGPU driver misbehaves |
?cpu | Force the CPU canvas (slowest, most compatible) |
Web build vs desktop
| Web | Desktop | |
|---|---|---|
| Opening files | Browser file picker | Native dialogs, drag and drop, file associations |
| Saving | Save and Export download a file | Writes to disk |
| Autosave and crash recovery | None, so save often. Since v0.6.0, the page asks before you close or reload it with unsaved work (#1424) | Yes |
| Preferences | Browser localStorage (may be forgotten in third-party iframes) | Settings folder |
| Pen pressure and tilt | Yes, via Pointer Events | Windows only for now (#79) |
| Chinese, Japanese and Korean interface | Not yet: the text shows as empty boxes (#1615), so use English | Yes, with Japanese UI fonts embedded in release builds |
CLI, MCP server, --control channel | Not available | Available |
The web build is a good way to try PhotoCraft, or to give a team an editor without installing anything. For day-to-day work, the Windows, macOS or Linux app adds crash recovery, native file access, the CLI and a working Chinese, Japanese or Korean interface. See Troubleshooting if the page stays blank.
Use it here or host it yourself
photocraft.im is an unofficial community guide. Its online editor runs an unmodified copy of the official web build, served from this site's own storage. That page shows which version it runs and the SHA-256 of the release zip it comes from, so you can check it against the official SHA256SUMS.txt.
To host it yourself, still download the web zip from the official storytold/photocraft GitHub releases and check it against SHA256SUMS.txt, as in step 1 above.
Treat any "online PhotoCraft" run by an unknown third party with care. Before you open private images in one, check that it says which version it runs and gives a checksum you can match against the official release, that it serves the build unchanged, and that it adds no ads or trackers inside the editor. Without that, you have no way to know which build it serves or how it was changed.