Skip to content

Desktop App

If you would rather not use a browser, or want something that works offline, there is a desktop build. It bundles the backend and frontend together — double-click and it runs, no network needed.

Download

Look for installers on this fork's Releases page and choose by system and chip. If your platform has no custom build yet, build custom-base as described below. Upstream installers do not represent this fork's features.

System File
Windows .exe installer (NSIS), or the portable exe
macOS (Apple Silicon) .dmg

Only Apple Silicon Mac builds are published

There is currently only an arm64 macOS build; Intel Macs cannot install it. Windows builds are unaffected.

macOS blocks it on first launch

The desktop build is neither code-signed nor notarised — there is no Apple Developer certificate in the project. So macOS blocks it the first time you open it. On macOS 15 and later the warning may say the file is "damaged" outright.

That warning has two possible meanings — work out which one you are looking at:

  • Most of the time it is the quarantine attribute: macOS tags every downloaded file with it, and an unsigned app trips over it on first launch. The file itself is fine.
  • It can also mean the file really is corrupted, or has been tampered with. Be especially wary of installers obtained from anywhere other than the official channel.

So first confirm you downloaded the installer from this repository's Releases page. If the source checks out, use one of the methods below to let it through. If you cannot verify where it came from, do not bypass the warning and do not open the app.

Once confirmed, run this once in a terminal:

xattr -dr com.apple.quarantine /Applications/HandwritingWeb.app

Or go to System Settings → Privacy & Security and click "Open Anyway".

Both of these tell macOS to stop blocking the app. They are necessary only because the project has no Apple Developer certificate to sign and notarise the build — they do not mean the build is safe. Hence the "verify the source first" step above is not boilerplate.

How it differs from the web version

The desktop build uses the same React frontend and Python rendering service. The main differences are:

  • Local generation — there is no fixed ten-page truncation, but memory, paper dimensions, and hardware still constrain rendering.
  • Error reporting disabled — the desktop runtime disables Sentry; the frontend does not load analytics or chat scripts.
  • No pandoc download — .docx files are handled by python-docx when pandoc is absent.
  • No overload guard interference — the CPU guard is relaxed so the app cannot rate-limit itself.

Where your data lives

The task database, temporary files, logs and fonts live in the user data directory. Deleting it is equivalent to a factory reset:

System Location
Windows %LOCALAPPDATA%\HandwritingWeb
macOS ~/Library/Application Support/HandwritingWeb

Roughly:

  • tasks.db — the task queue (SQLite)
  • temp/ — rendered images
  • logs/ — logs
  • fonts
  • studio/ — editor drafts, presets, and uploaded assets, independent of backend task expiry

Building it yourself

The build must run on the target platform — PyInstaller cannot cross-compile, so Windows packages can only be produced on Windows and macOS packages only on a Mac of the matching architecture.

bash desktop/build.sh                 # full build: frontend → backend executable → installer
bash desktop/build.sh --app-only      # Electron directory only, no installer
PYTHON=python bash desktop/build.sh   # pick the interpreter (used by CI)

Artifacts land in desktop/build/. For development, run --app-only first, then npx electron . from desktop/.

Read AGENTS.md for development conventions and Architecture for persistence and saving before exit. Consult the corresponding source and tests before changing build, security, or platform behavior.