Project case study · 2026
Applied Vacancies Tracker
A local-first Chrome extension for tracking job applications without spreadsheets, with status workflows, duplicate detection, migrations, and privacy-focused data controls.
![]()
The problem
During an active job search, I was repeatedly copying company names, vacancy links, dates, statuses, and notes into Google Sheets. The process was slow, easy to forget, and disconnected from the browser where applications actually happen.
I built Applied Vacancies Tracker as a small Chrome extension that keeps this workflow close to the user and stores the data locally without requiring an account.
What the product does
- Creates and edits application records with company, position, date, salary, link, notes, and status.
- Tracks the application lifecycle from initial application through interviews, offer, rejection, or expiration.
- Detects likely duplicate vacancies before creating another record.
- Supports search, filtering, pagination, and application details.
- Automatically expires old inactive applications using a configurable threshold.
- Exports and imports versioned JSON backups.
- Keeps application data inside the user’s Chrome profile.
From MVP to a production-oriented version
The first version proved the workflow, but its UI and internal structure were intentionally small. I later refactored it into a more production-oriented application with:
- a dashboard and clearer information hierarchy;
- a compact application detail panel;
- repository, use-case, domain, infrastructure, and UI boundaries;
- versioned data migrations that preserve records created by older versions;
- runtime validation for imported data;
- explicit privacy and data-management controls;
- a background service worker that restricts storage access to trusted extension contexts.
The extension currently requests only Chrome’s storage permission. It does not read vacancy pages or transmit application data to an external service.
Technical decisions
| Area | Decision |
|---|---|
| UI | React and TypeScript with a dedicated options-page workspace and compact popup |
| Persistence | chrome.storage.local behind repository and adapter interfaces |
| Data evolution | Versioned schema migrations and validated import/export |
| Business rules | Pure functions for expiration and duplicate detection |
| Security boundary | Content scripts cannot directly access the complete application store |
| Testing | Unit tests for migrations, matching rules, imports, and UI smoke rendering |
What I learned
Although it is a small extension, it has been a useful exercise in product development rather than only UI implementation. The work includes local persistence, backward compatibility, browser-extension constraints, privacy communication, data migrations, and balancing feature growth with a maintainable architecture.
Next direction
The next product phase is focused on reducing manual work while keeping the user in control:
- detect a vacancy on the currently opened page;
- preview extracted company, title, salary, location, and link;
- add the vacancy to the tracker after confirmation;
- highlight relevant skills and constraints;
- later compare a vacancy with one or more user-provided CVs.
These features are planned, not part of the currently published version.