~/pairkan

[← back]

$ ./pairkan

pairkan.com

// personal · 2025—

// A consumer-facing web service. Solo full-stack design and build.

one-liner

A consumer-facing web service. Solo full-stack design and build, intentionally minimal for one-person economics.

screenshots

pairkan hero shot
// hero shot
pairkan onboarding
// onboarding flow
pairkan main UI
// main UI
pairkan detail view
// result / detail

problem → design → build

problem.
Couples and families sharing a household accumulate constant low-grade friction — who fronted what, and when to settle up. Expenses with different closing dates (rent on the 25th, credit card on the 10th, cash month-end) break when squeezed into a single pool by spreadsheets or generic budgeting apps. I built it because my partner and I needed a settlement tool that handles multiple closing cycles natively in one app.

design.
Modeled the domain around four first-class concepts — Group / Bucket / Cycle / Invoice. A Bucket carries the closing day and cycle length; each cycle finalizes into one Invoice with the OPEN → PAID → CLOSED state machine. After PAID, line items freeze (no edits except an explicit revert), so the issued bill doesn't shift under the receiver's feet. Recurring costs are semi-automated: templated items appear as candidates at close time, with only the variable portion entered by hand. Postgres Row Level Security pushes the "only the two members of this group can touch these rows" rule into the database layer, keeping the app layer thin.

build.
Deliberately minimal stack — Next.js 16 (App Router, RSC), Supabase (Postgres + Auth + RLS), shadcn/ui + Tailwind v4. Cloudflare Workers via @opennextjs/cloudflare for always-on edge execution on the free tier; Vercel kept as a DNS-flip backup. Tests split into Vitest fast / UI lanes plus Playwright (Chromium) E2E. Schema-first workflow with supabase/schemas/ as the source of truth and supabase db diff generating migrations. Server Components by default, Client Components only at leaves, to keep hydration cost low — and the design → implement → deploy loop tractable for one person.

stack & trade-offs

chosen considered why
frontend Next.js 16 (App, React 19) Astro · SvelteKit SSR + auth + streaming in one runtime
db / auth Supabase (Postgres + Auth) Postgres + Auth0 1 vendor cuts ops surface
api Next.js Route Handlers Hono on CF Workers minimize context switching for solo dev
hosting Cloudflare Workers (opennextjs) Vercel · Fly edge + free tier (Vercel kept as DNS-flip backup)
ui shadcn/ui + Radix + Tailwind v4 Mantine · Chakra copy-and-edit primitives, no runtime lock-in
testing Vitest + Playwright Jest + Cypress Vite-native + cross-browser E2E
analytics (none yet) Posthog · Plausible ship first, measure later

note: at scale, auth and heavy compute would split out to Hono on CF Workers. The current minimalism is intentional — cost, speed, single-person cognitive load.

current state · what's next

  • - live: pairkan.com
  • - recent ship: full landing-page refresh (Hero / Steps / Settle / Features / CTA sections), send-money UX polish, empty-state illustrations
  • - next: PWA push notification foundation; invoice UX flow upgrade; settings page; stricter expense edit-lock guarantees