Skip to content
← Back to projects

Task Manager

One codebase, two applications: desktop and PWA.

Year
2026
Status
In production
Stack
TypeScriptTauri 2PWASupabasePostgreSQLpnpm workspacesCaddy

The problem

I wanted my tasks on my PC and on my phone, in sync, without handing their contents to a third-party service. And without writing the same business logic twice.

The architecture

A monorepo where the domain logic and the API client live in shared packages. The applications are just interfaces on top: they differ in navigation and feel, not in rules.

importedimporteddirect accessdirect accessShared packagesDomain logic · API clientDesktop appTauri 2 · WindowsInstallable PWAStatic files · CaddySelf-hosted SupabasePostgres · per-row rules
No API server in the middle: both interfaces talk straight to the database, which enforces access rights itself.

The decisions that matter

  1. 01

    Dropping the Android app for a PWA

    The Android app worked, but every fix meant rebuilding an APK and reinstalling it by hand. A PWA installed to the home screen covers both Android and iOS, updates itself, and removes an entire build chain. The Android code still exists — it just isn't used any more.

  2. 02

    Deleting the API server

    There was a custom backend with its own database at first. All it did was relay requests and enforce permissions — two things Postgres can do on its own. Replacing it with direct Supabase access, with the security rules written into the database, removed a whole service to maintain and monitor.

  3. 03

    Permissions in the database, not in the code

    Every row carries its own access rules at the Postgres level. A badly written client, or one modified by its user, still can't read someone else's tasks: the barrier isn't in the application, it's underneath it.

  4. 04

    A deployment that's just a file copy

    The web side is nothing but a folder of static files served by Caddy. Shipping a version means copying that folder — no container restart, no downtime for users.

A look at it

Screenshot coming soon
Screenshot coming soon