Track the opportunity, not the website where you found it.
A job search rarely stays in one place. The same opportunity can appear in a search, return under a new URL, arrive by email, and become an application whose history is scattered across bookmarks, notes, and inbox messages. Spreadsheets and generic project boards can store those fragments, but leave you to connect them.
Job Tracker is a self-hosted workspace built around one lasting record per job. Listings, status changes, notes, decisions, and materials stay attached to that opportunity. A browser extension captures details and reliable lifecycle updates, while a local Kanban dashboard keeps the process visible and under your control.
- One opportunity, one history. Keep multiple listing URLs, status changes, notes, events, decisions, and materials connected to the same job.
- Capture what can be captured. Record supported listing details and lifecycle updates while you browse instead of retyping them later.
- Catch reposts without losing control. Review suggested matches, confirm genuine reposts, and preserve the history already gathered; merging is never automatic.
- Decide with context. Surface experience requirements, languages, pay, seniority, applicant activity, listing age, custom terms, and company history with the evidence around each signal.
- Act where you encounter the job. Use in-page controls or the context-seeded popup to search, update status, backdate events, comment, add notes, or create a job manually.
- Follow through. Use a correctable timeline, attention rules, material records, custom fields, and a Kanban dashboard to keep applications moving.
- Stay local and extensible. Use SQLite by default, opt into Turso synchronization, and add new built-in or private integrations through the adapter model.
Explore all features and workflows, including automation boundaries, repost handling, decision signals, and follow-up tools.
| Surface | Support |
|---|---|
| LinkedIn jobs | Listing capture and in-page triage on search cards and job details |
| LinkedIn job emails in Gmail | Recognizes supported messages and adds tracker actions |
| Sites without a built-in integration | Add a job manually from the popup |
LinkedIn and supported LinkedIn job emails in Gmail are the only built-in integrations today. The integration layer is designed to support additional built-in or private/local adapters without changing the core job model.
These unofficial integrations depend on third-party page layouts, may require adapter updates when those layouts change, and remain subject to each platform’s terms.
Keep every opportunity and its current stage visible from the local Kanban dashboard.
Capture job details, review decision signals, and update tracked opportunities without leaving the listing.
Job Tracker is a single-user, self-hosted application designed for localhost use. By default, records stay in a local SQLite file on your own machine; Turso synchronization is optional. The extension talks only to the configured Job Tracker server, uses no third-party analytics, and keeps optional search diagnostics off by default.
On Gmail, the extension recognizes supported LinkedIn job messages in the browser and sends only the structured job and action data needed by the tracker; it does not send or store the email body as a job description. See Privacy for captured fields, permissions, retention, and deletion, and Security for the supported localhost threat model.
Every path needs a Chromium browser — Chrome, Edge, or Brave — that can load an unpacked extension. The rest depends on which installation path you pick:
| Path | Get the files | Platforms | Host tools |
|---|---|---|---|
| Source checkout | Clone the repository | Linux, macOS | Git, Node.js as pinned in .node-version, pnpm through Corepack, uv |
| Docker Compose | Clone the repository or download the source archive; pull the published image | Linux/amd64 | Docker Engine with Compose |
| Linux release | Download the latest release | Linux x86_64, including Windows 11 WSL2 x86_64 | uv |
Neither the runtime bundle nor the wheel is a native executable, and neither contains Python: uv provisions the pinned Python runtime and dependencies. Native Windows and Git Bash are unsupported, and there is no packaged macOS artifact — on macOS, install from source.
git clone https://github.com/Muatasim-Aswad/job-tracker.git
cd job-tracker
bash scripts/setup.sh
bash scripts/start.shSetup installs the locked dependencies and builds the dashboard and extension. It prints the absolute extension path needed below. The development guide covers the contributor launcher, quality gate, and per-component commands.
From the cloned repository or extracted source archive:
docker compose pull
docker compose up -dThis runs the current stable image through its latest tag. Use docker compose up -d --build instead to build the checked-out source. The container serves the API and dashboard; use the matching extension ZIP from the latest release in the shared step below. Containers covers configuration, volumes, backups, and updates.
Download the runtime archive, extension ZIP, wheel, and SHA256SUMS from the latest release into a single directory, then verify them:
sha256sum -c SHA256SUMSInstall the runtime bundle:
mkdir -p job-tracker-app
tar -xzf job-tracker-<version>-linux-x86_64.tar.gz -C job-tracker-app
job-tracker-app/job-tracker startOr install the wheel instead:
uv tool install job_tracker-<version>-py3-none-any.whl
job-tracker startOn Windows 11, run this path inside a WSL2 distribution and follow WSL2 for its requirements.
After starting the server with any method above, open http://localhost:3456. Then load the matching extension unpacked:
- Open
chrome://extensions. - Enable Developer mode.
- Select Load unpacked.
- Choose the
apps/extension/distpath printed by source setup, or the directory extracted fromjob-tracker-extension-<version>.zipfor a release or container installation.
Reload the extension after updating the server. It uses the local address above by default; another address means reconfiguring and rebuilding it from source.
Stop the server first. Each path then has one authoritative procedure:
- Source checkout: run
git pull --ff-only,bash scripts/setup.sh, and reload the extension. This path keeps its database and configuration inside the checkout, so removing the checkout removes them too. - Runtime bundle or wheel: Distribution and lifecycle for upgrading, removal, and purging; Packaged CLI for the
backup,restore, and diagnostic commands. - Docker Compose: Containers.
The API guide holds the tested backup and restore procedure for every local and Turso mode.
- Architecture and component boundaries:
docs/ARCHITECTURE.md - API, configuration, database modes, and maintenance:
apps/api/README.md - Dashboard development:
apps/web/README.md - Extension build, keyboard controls, and adapter guide:
apps/extension/README.md - Private/local adapter overlay:
docs/PRIVATE.md - Developer policy — quality gate, generated files, comment and Markdown style, migrations, and versioning:
docs/DEVELOPMENT.md - Contributions and support:
CONTRIBUTING.md - Release history:
CHANGELOG.md