Skip to content
All projects
ApplyOS: A Local-First Command Center for the Job Hunt
Developer Toolscompleted

ApplyOS: A Local-First Command Center for the Job Hunt

May 202610 weeks
0 serversjob-hunt data is sensitive — salary lines, where you're interviewing — so there's no backend state at all. Everything is local IndexedDB with portable JSON export. Zero trust required, zero hosting cost.

Overview

Applying to jobs means re-typing the same 40 fields and re-answering the same 5 questions hundreds of times, then losing track of who you even applied to. ApplyOS kills that loop: a Vault that stores every field and snippet once (with {{company}}/{{role}} variables that resolve at copy-time), a Tailor that scores a JD offline and drafts tailored bullets, a Tracker for the full pipeline, and a one-click autofill extension — all local-first.

Tech Stack

web
Next.js 14 (App Router)TypeScriptTailwindDexie / IndexedDB
extension
Chrome Manifest V3 (vanilla JS)
crypto
AES-256-GCMPBKDF2-SHA256 (310k iterations)
ai
Anthropic (BYOK, offline-capable)

Challenges

  • Setting input.value directly is ignored by React-controlled forms, so autofill silently does nothing.
  • Per-site scrapers break the moment an ATS changes its CSS.
  • Auto-capturing the company and role of a job even while the app is closed.
  • Storing passwords properly — or not pretending to at all.

Solution

Autofill is heuristic, not per-site: every input is scored by its surrounding signals (label, placeholder, name, aria-*, autocomplete) against an ordered pattern table, so it generalizes to ATSs it has never seen. To beat React-controlled forms it writes through the native prototype value setter and dispatches input/change/blur events, so frameworks register the change like a real keystroke. Auto-capture parses JSON-LD JobPosting first (then URL slugs, then the <h1>) and queues captures in a chrome.storage outbox that drains into IndexedDB next time the app opens. Passwords are AES-256-GCM under a PBKDF2 key that's non-extractable, in-memory only, and auto-wiped after 5 idle minutes — and never synced to the extension.

Outcome

Fill your vault once (15 minutes, pays off forever), paste a JD for an instant offline match score, one-click fill an application and have it auto-logged to your tracker — with an amber "already applied 4 days ago" warning if you've been here before. The dashboard even tells you which profile and which portal actually convert, so you know where to double down.

What I'd do differently

Long-form answers stay human-in-the-loop on purpose — copy-from-vault with variables resolved, never auto-submitted. Next: resume-PDF parsing to auto-populate the vault, fuzzy dropdown filling for degree and country pickers, and a Firefox port (MV3 is nearly compatible).

Built with

Next.js 14TypeScriptTailwindDexie / IndexedDBChrome MV3AES-256-GCMAnthropic (BYOK)