Draw·24 Mar · 2026·6 min read

Local-first, six weeks in.

Notes from wrapping a beloved web tool in a native shell — autosave, atomic writes, and the bits that are quietly hard.

Draw started as a one-evening Tauri experiment: wrap Excalidraw in a native shell, save files to disk, see what happens. Six weeks later it's the editor I open every day, and there's a list of things I wish I'd known on day one.

The hardest problem wasn't rendering, or the file format, or even the auto-updater. It was autosave. Specifically: how do you write a file 200 times a minute without ever — not once, not in a power outage, not in the middle of a stroke — leaving the user with a corrupt drawing?

The answer is atomic writes. Every save lands as `<file>.tmp` next to the real file, gets fsync'd, and only then gets renamed over the original. POSIX rename is atomic. macOS gives you APFS clone-and-rename for free. The .tmp guard means the worst case is you lose 500ms of strokes — the file you had a second ago is the file you reopen. We tested this by literally pulling the plug. It works.

Things we got wrong: the first sidebar was too clever. We tried to mirror the folder tree with virtual sections and tags and a quick-switcher. Users wanted a folder. We removed everything except the folder.

"

The .tmp guard means the worst case is you lose 500ms of strokes — the file you had a second ago is the file you reopen.

— Field Notes № 03

Tagged
  • draw
  • tauri
  • local-first