A local-first, privacy-first developer toolbox for the desktop.
73 tools across 10 categories — plus tasks, notes and snippets. Fully offline, no account, no telemetry.
Install · Tools · Architecture · Development · Add a tool · Self-hosting sync
- Nothing leaves your machine. Every tool runs locally; data lives in IndexedDB. No network call is made unless you turn on sync.
- Privacy is enforced, not promised. Each tool declares a privacy level —
PUBLIC,LOCAL_ONLYorNEVER_PERSIST. ANEVER_PERSISTtool (JWT parser, encryption) can't write history to disk even if it wanted to. - One window instead of thirty tabs. JSON, crypto, networking, images, dates and more, next to the tasks, notes and snippets that go with them.
- Sync only if you want it. Optional, self-hosted, one Cloudflare Worker + D1 — free tier is plenty. There is no hosted DevDesk server.
- Genuinely extensible. A tool is a pure function plus one metadata entry — the UI is generated. See adding a tool.
Download the executable for your OS from the latest release and run it — a single self-contained file, no installer, no runtime to set up.
| Platform | Asset |
|---|---|
| macOS | devdesk-mac_universal |
| Windows | devdesk-win_x64.exe |
| Linux | devdesk-linux_x64 |
On macOS/Linux, mark it executable first: chmod +x devdesk-*.
Or build it yourself — see Development.
| JSON (3) | JSON Editor · JSON Diff · JSON → TypeScript |
| Data formats (5) | JSON ⇄ YAML · JSON ⇄ CSV · JSON ⇄ JSON Lines · XML ⇄ JSON · .env ⇄ JSON |
| Encoding (6) | Base64 · URL Encoder · HTML Escape · Hex / Binary · Unicode Inspector · Escape for Code |
| Crypto (14) | UUID / ULID / Token / Password generators · Password Strength · RSA Key Pair · Hash · HMAC · TOTP / HOTP · Encrypt / Decrypt · JWT Parser · JWT Signer · Certificate Inspector · UUID Inspector |
| Web (8) | URL Parser · Basic Auth · Slugify · User-Agent Parser · HTTP Status Codes · cURL Converter · Cookie Inspector · Cache-Control Explainer |
| Networking (8) | CIDR Calculator · IP Converter · Subnet Splitter · IP Range ⇄ CIDR · IP / CIDR Matcher · MAC Generator · MAC Inspector · Port Reference |
| Development (7) | Regex Tester · Cron Generator · Random Port · Git Cheatsheet · Email Normalizer · Case Converter · Chmod Calculator |
| Date & time (5) | Timestamp Converter · Time Zone Converter · Duration Calculator · Date Calculator · ISO 8601 Duration |
| Images & color (9) | QR Code · WiFi QR · SVG Placeholder · Color Converter · Palette Generator · Contrast Checker · Gradient Generator · Image Converter · SVG Optimizer |
| Math (8) | Percentage · ETA · Byte Converter · Number Statistics · Uptime / SLA · Number Base · Aspect Ratio · Transfer Time |
DevDesk is a plugin platform, not a set of pages. The boundaries that matter:
- Tools are pure functions.
packages/toolsexports each tool's{ metadata, schema, run }with zero UI. The desktop app renders them generically (ToolRunner+ a smallTOOL_UIspec), so a new tool is logic + one metadata entry — no bespoke component required. - Data flows one way:
Vue → Services → Repositories → Dexie. Components never touch the database. - Native access is isolated:
Vue → DesktopService → NeutralinoAdapter, with aWebAdapterfallback so the exact same app runs in a browser. - Features are decoupled through a typed event bus (
src/lib/events.ts). A mutation emitsentity:mutated; the sync queue and the UI react independently. - Privacy levels drive behaviour automatically — history, favourites and snippets are switched on or off by the tool's declared level, not by hand.
apps/
desktop/ Vue 3 + Vite + Tailwind + Nuxt UI + TanStack Router. Neutralino shell.
sync-api/ Hono worker on Cloudflare Workers + D1. Auth + sync endpoints.
packages/
shared/ Types, Zod schemas, constants (the contract everything shares).
tools/ Pure, headless tool logic + the plugin registry. No Vue, no DOM.
database/ Dexie schema + repositories (local persistence).
sync/ Framework-independent sync engine + API client.
ui/ Reusable Vue components (dialogs, feedback, badges).
utils/ Small framework-independent helpers.
Tasks, notes and snippets belong to a workspace. Exactly one is active at a time; the repository layer stamps new records with it and scopes every listing to it, so nothing has to pass a workspace id around. The active workspace is shown in the app header and managed in Settings → Workspaces. Switching reloads the window — the simplest way to guarantee every open view re-reads the new scope.
The first run creates a Personal workspace (id default). The choice is stored per-install in
localStorage; if it points at a workspace that no longer exists, the app falls back to default.
Local-first, last-write-wins (v1). Every mutation is saved locally, queued, and pushed in the
background; the client pulls remote changes and merges them by updatedAt. Soft deletes sync as
tombstones. See packages/sync/src/engine.ts and docs/self-hosting.md to run
the server side yourself.
Requires Node ≥ 20 and pnpm.
pnpm install
pnpm dev # sync API + desktop app together
pnpm dev:desktop # desktop app only (Vite dev server, http://localhost:5173)
pnpm dev:api # sync API only (wrangler dev, http://localhost:8787)
pnpm test # all packages
pnpm typecheck # all packages
pnpm lintpnpm --filter @devdesk/desktop build # build web assets into dist/
pnpm --filter @devdesk/desktop neu:run # run the native window (needs neu CLI)
pnpm --filter @devdesk/desktop neu:build # produce release binariesTagging a v* release pushes the cross-platform binaries to GitHub Releases automatically
(.github/workflows/release.yml).
Vitest across every layer: tool logic, utils, repositories (fake-indexeddb), services, the sync engine, Vue components (@vue/test-utils), and the worker's routing/auth.
Contributions are welcome — new tools especially. Start with
docs/adding-a-tool.md; a tool is a pure function and a catalog entry, and
the UI comes for free. Before opening a PR, run pnpm test, pnpm typecheck and pnpm lint.
For anything larger, open an issue first so we can agree on the shape.
