Skip to main content

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.

Unofficial community guideUpdated Oct 10, 2026

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>/:

FileWhat it is
index.htmlThe page. It loads everything through relative URLs.
photocraft-web-<hash>.jsThe wasm-bindgen glue (an ES module)
photocraft-web-<hash>_bg.wasmThe app itself
_headers, .htaccessSample 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

  1. Download photocraft-web-<ver>.zip and SHA256SUMS.txt from 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
    
  2. Unzip it and try it locally:

    unzip photocraft-web-0.6.0.zip
    cd photocraft-web-0.6.0
    python3 -m http.server 8765
    

    Open http://localhost:8765/. localhost counts as a secure context, so WebGPU works here.

  3. 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.

  4. Check it: open the page, open an image, and save or export it.

Server settings that matter

  • MIME type: serve .wasm as application/wasm and .js as text/javascript. With the wrong type, browsers can't stream-compile the wasm, and the app loads slowly or not at all. For nginx, make sure mime.types has application/wasm wasm;.
  • Compression: turn on gzip or Brotli for .wasm, .js and .html. On the 0.2.x build, that cut the .wasm download from about 19 MiB to 8 MiB (gzip) or 5.6 MiB (Brotli).
  • Caching: the .wasm and .js file names contain a content hash, so give them Cache-Control: public, max-age=31536000, immutable. Give index.html no-cache so visitors pick up new versions.
  • HTTPS: WebGPU and the clipboard only work in a secure context (https:// or http://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 COEP require-corp, also send Cross-Origin-Resource-Policy on 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:

URLEffect
(no flag)WebGPU if available, otherwise WebGL2
?webglForce WebGL2, useful when a WebGPU driver misbehaves
?cpuForce the CPU canvas (slowest, most compatible)

Web build vs desktop

WebDesktop
Opening filesBrowser file pickerNative dialogs, drag and drop, file associations
SavingSave and Export download a fileWrites to disk
Autosave and crash recoveryNone, so save often. Since v0.6.0, the page asks before you close or reload it with unsaved work (#1424)Yes
PreferencesBrowser localStorage (may be forgotten in third-party iframes)Settings folder
Pen pressure and tiltYes, via Pointer EventsWindows only for now (#79)
Chinese, Japanese and Korean interfaceNot yet: the text shows as empty boxes (#1615), so use EnglishYes, with Japanese UI fonts embedded in release builds
CLI, MCP server, --control channelNot availableAvailable

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.

Related guides