Back to home
Self-Engine

Case study · My own productLive since July 2026

Work, time, money and everyday life. In one app.

Self-Engine is my own product: a productivity app for freelancers and the self-employed in which time tracking, tasks, calendar, finance and habits share one data model. I design, build and run it on my own — offline-first, on the web, on the Mac and soon on your phone.

  • Web app
  • macOS (alpha)
  • iOS beta
  • Offline-first
commits since December 2025
2,100+
releases since July 2026
79
automated tests
~5,900
database migrations
137
synced tables
37
architecture decisions (ADRs)
38
The idea

Separate tools know nothing about each other.

Time trackers don't know what an hour is worth. Finance apps don't know which work earned the money. And calendars show what was planned — never what actually happened. The connections between them only existed in my head.

In Self-Engine, those connections are the product: an appointment starts a timer, the timer becomes a time entry, and a payout marks the entries as paid and books the money in Finance.

  1. 01

    Appointment

    planned in the calendar

  2. 02

    Timer

    started from the appointment

  3. 03

    Time entry

    with hourly rate and rounding

  4. 04

    Payout

    marks entries as paid

  5. 05

    Cashflow

    in the right account and currency

And habits fill themselves in — from the time you track on a linked project.

Modules

One data model, five modules.

Each module works on its own — and knows about the others.

Tasks

Inbox, Today, Upcoming and a Kanban board — with your own statuses in fixed categories.

  • Planned day and deadline kept apart
  • Subtasks, tags, priorities, reminders
  • Fuzzy search across everything

Calendar

Appointments and tracked time side by side in week and month views — plan and reality at a glance.

  • Two-way sync with Google and Apple (iCloud)
  • Syncs on the server, even with the app closed
  • Start a timer right from the appointment

Finance

Accounts in one currency each, one-off and recurring payments, transfers and currency conversions.

  • Reports strictly per currency
  • Pause and resume recurring payments
  • Fixed-price projects and contact profiles

Habits

Daily, on chosen weekdays, or as a flexible quota per week or month.

  • Streaks always computed from history
  • Pause without losing your history
  • Progress filled in from tracked time
AI & agents

An assistant with guardrails.

The built-in assistant knows 39 typed capabilities across every module. It works pull-first: the model gets counts and hints instead of user data and has to ask through typed read tools. The server enforces rate limits, cost tracking and routing through zero-data-retention endpoints only.

If you'd rather use your own agent, connect Claude, Claude Code or Cursor to Self-Engine's MCP server over OAuth. Permissions apply per data type, agents can at most move things to the trash, and every call lands in the agent log.

  1. Preparea preview from live data
  2. Approveonce, bound to the exact input
  3. Executethe same domain mutation as a click
Architecture

Offline-first — for real.

Every app writes to a local SQLite database first; a write never waits for the cloud. PowerSync queues the change and uploads it in order to Supabase, where Postgres, with row-level security on every table, stays the source of truth. Changes from other devices flow back into the local database, and the UI updates through live queries — no manual cache invalidation anywhere.

The domain lives in shared packages: 37 synced tables, Zod schemas and typed collections that web and mobile consume identically. Business rules are pure functions behind a persistence port — the same rule guards a tap in the mobile app, a click on the web and an AI agent's tool call on the server.

Identity is a single Clerk JWT for both data paths: PowerSync validates it for replication, and Postgres enforces it through row-level security on every query. The desktop app is an Electron shell around the web app — with a menu-bar timer, quick capture and signed auto-updates.

App UIReact · React Native · Electron
Local SQLiteevery write lands here first
PowerSyncordered upload · live queries
Supabase Postgressource of truth · row-level security
Persistence port: the same business rules on the device, on the server and in tests
Learnings

Hard-won lessons.

01

One domain, three runtimes

So that AI agents on the server hit the same rules as the app on the device, I pulled the domain logic off PowerSync and behind a persistence port — with three adapters (PowerSync, in-memory, Postgres) and a test that checks every rule's import graph.

02

One broken write must not block the rest

Offline queues upload in strict order — a single invalid write would hold up every one after it. So fatal Postgres errors are classified and dropped, writes that belong together are sent atomically, and you learn which area lost a change.

03

Calendar sync on an offline foundation

The hard part of syncing with Google and iCloud isn't the API, it's identity: deterministic IDs make creates idempotent, ETags catch concurrent edits, expired sync tokens trigger a full resync, and the server-side reconciliation shares a lock with the sync from the app.

04

Swapping the identity provider in production

Migrating every user ID from Supabase Auth to Clerk meant rewriting every row-level security policy in one migration and moving two independent data paths to one JWT — without losing a single offline queue.

Stack

Built with

Web

  • TanStack Start
  • TanStack Router
  • TanStack DB
  • TanStack Query
  • Mantine
  • Paraglide

Mobile

  • Expo
  • React Native
  • Expo Router
  • HeroUI Native
  • EAS Updates

Desktop

  • Electron
  • electron-builder
  • electron-updater

Data & sync

  • SQLite
  • PowerSync
  • Supabase
  • Postgres
  • Clerk
  • Zod

AI

  • TanStack AI
  • OpenRouter
  • Model Context Protocol

Quality & tooling

  • TypeScript
  • Bun
  • Turborepo
  • Vitest
  • pgTAP
  • Oxlint
  • Knip
  • Sentry

Try it yourself.

Self-Engine runs in the browser and on the Mac — free for 30 days.

Self-Engine is a commercial product; its source code is not public.