I built JobOps to solve a problem I kept running into: job links expire, descriptions get edited, and by the time an interview invitation arrives weeks later, I have no idea what I actually applied for or which resume version I sent.
What it does:
Snapshots job descriptions at application time (so dead links don't kill your context)
Generates tailored resumes and stores the exact version you sent with each application
Supports local LLMs (Ollama, LM Studio) alongside cloud providers for resume tailoring
Command bar (Cmd+K) and keyboard shortcuts for bulk operations
Webhook integration for automation (n8n, Zapier, etc.)
Dashboard for tracking application velocity and success rates
Technical details:
TypeScript monorepo. React 18 + Vite 6 frontend, Node/Express backend, SQLite + Drizzle ORM. Self-hosted via Docker Compose with persistent ./data volume.
The LLM integration is provider-agnostic—swap between OpenAI, Gemini, OpenRouter, or local models without code changes. Built an adapter pattern that made adding Ollama support trivial.
Job extraction uses a pluggable system: JobSpy (Python wrapper), Gradcracker, UKVisaJobs, manual imports, Glassdoor. Everything normalizes to a unified schema with deduplication.
Why local-first:
Your job hunt data is sensitive. This runs entirely on your machine. No SaaS, no tracking, no data leaving your infrastructure unless you explicitly configure webhooks.
Current state:
Been shipping daily for 3 weeks. 200+ stars, 570+ Docker pulls, 5 contributors I've never met, users answering each other's questions in issues. It's gone from "tool for myself" to something people are actually using.
It would also be quite cool if it could read your emails and notify you when you get and email about an OA or an interview or something. Have had a couple of those emails slip through the cracks previously. Would also make the part of manually entering status into the tool a lot easier.
These all sound like really useful features. Since it tracks which resume you sent, does it give you some insight into which variations are the best performers?
Hi HN,
I built JobOps to solve a problem I kept running into: job links expire, descriptions get edited, and by the time an interview invitation arrives weeks later, I have no idea what I actually applied for or which resume version I sent.
What it does:
Snapshots job descriptions at application time (so dead links don't kill your context) Generates tailored resumes and stores the exact version you sent with each application Supports local LLMs (Ollama, LM Studio) alongside cloud providers for resume tailoring Command bar (Cmd+K) and keyboard shortcuts for bulk operations Webhook integration for automation (n8n, Zapier, etc.) Dashboard for tracking application velocity and success rates Technical details:
TypeScript monorepo. React 18 + Vite 6 frontend, Node/Express backend, SQLite + Drizzle ORM. Self-hosted via Docker Compose with persistent ./data volume.
The LLM integration is provider-agnostic—swap between OpenAI, Gemini, OpenRouter, or local models without code changes. Built an adapter pattern that made adding Ollama support trivial.
Job extraction uses a pluggable system: JobSpy (Python wrapper), Gradcracker, UKVisaJobs, manual imports, Glassdoor. Everything normalizes to a unified schema with deduplication.
Why local-first:
Your job hunt data is sensitive. This runs entirely on your machine. No SaaS, no tracking, no data leaving your infrastructure unless you explicitly configure webhooks.
Current state:
Been shipping daily for 3 weeks. 200+ stars, 570+ Docker pulls, 5 contributors I've never met, users answering each other's questions in issues. It's gone from "tool for myself" to something people are actually using.
Demo (read-only): https://jobops.dakheera47.com Repo: https://github.com/DaKheera47/job-ops
Open to feedback, questions, and PRs.
It would also be quite cool if it could read your emails and notify you when you get and email about an OA or an interview or something. Have had a couple of those emails slip through the cracks previously. Would also make the part of manually entering status into the tool a lot easier.
These all sound like really useful features. Since it tracks which resume you sent, does it give you some insight into which variations are the best performers?