Back to selected work
On-device AI · 2026 · MVP shipped · v0.1

NanoApply

AI job-fit assistant running Gemini Nano fully on-device — no server, no API keys, nothing leaves the browser.

Solo — design, product, engineering

View on GitHub

The problem

Job seekers spend hours tailoring resumes to postings, mostly guessing at what the recruiter's ATS is scoring for. Existing tools (Teal, Rezi) send resume and posting text to a server, which is a privacy problem and a running cost problem for anyone applying to 20+ roles a week. I wanted the assistant to live on the same tab as the job posting, run on-device, and cost me zero to keep in front of me.

The approach

Chrome MV3 side-panel extension so the assistant stays open while the user browses. All AI inference runs through Chrome's built-in Gemini Nano via the Prompt API — no OpenAI key, no backend, no per-token cost. Storage is chrome.storage local-only. The one network call the extension makes is anonymous GA4 event pings for install / scan / build counts, opt-out in settings.

Selected details

  • Side panel architecture chosen over popup so the extension survives tab switches — critical when you're moving between LinkedIn, company careers pages, and Notion tracking.
  • Resume input starts as plain text — deliberate MVP scope. PDF/DOCX parsing is Phase 2 to avoid shipping a broken parser.
  • Scoring prompt is a strict JSON schema with fit_score, missing_keywords, and tailored_bullets — no free-form output to avoid Gemini Nano hallucinating structure.
  • CV builder opens a full tab with the tailored resume, click-to-edit sections, and Save as PDF via the print dialog — no PDF library, no bundle bloat.
  • GA4 pings never include resume or job posting text, only event names and counts. Documented in PRIVACY_POLICY.md so the Chrome Web Store review passes cleanly.

Outcome

MVP shipped and running against real job postings on LinkedIn, Naukri, Instahyre, and company career pages. Score-first-pass matches recruiter intuition ~70% of the time on my own applications. Phase 2 (PDF parsing, foreign-role cost-of-living compare) is planned; Phase 3 is auto-fill of application forms.

What I'd do differently: Ship the CV builder as a separate flow from day 1 rather than bolting it onto the analyzer — the two have different user intent and got tangled in the sidepanel.js single-file architecture.

Stack

Chrome MV3Gemini Nano / Prompt APIVanilla JSGA4 Measurement ProtocolPDF.js