mrkeyoor.com_
Sat 17 Oct 13:35 UTC
Self-Hostedevaluationupdated 26 Aug 2026

freehire review

freehire is an open-source job search and career workspace that crawls employer systems, normalizes listings, and adds search, saved jobs, CV tools, application tracking, and an assistant. It can be used through the hosted catalogue or self-hosted as a Go, SvelteKit, Postgres, Meilisearch, Redis, and object-storage stack.

+95stars / 7d
Verdict

Our root check finished in 7 seconds but installed 0 packages and found no build or test target, so it says nothing about whether freehire's 7-service local stack starts cleanly. Use the hosted API first if you need job data; self-host only when owning the crawler, search index, candidate data, and worker schedules is worth the operating cost. The current source activity and detailed architecture are encouraging, while stale-listing and facet issues demand monitoring before the catalogue informs real decisions.

We ran it

Lab card: what happened when we ran freehireScreenshot of freehire (freehire.me)
Install✓ · 7s0 packages · 1 MB
Buildn/ano build script
Testsn/ano test script
Repo6555 files~466,086 lines of source · 50 MB · 7 CI workflows · Dockerfile

Answers from our run

Does freehire build from source?

Dependencies installed in 7 seconds (0 packages), and the project has no separate build step. We cloned commit 36828fe into a clean Debian container with 3 CPUs and no project-specific setup.

Does freehire have tests you can run?

Not through a standard command: the project exposes no test script or target that our harness could run.

Who should not use freehire?

Anyone wanting a small personal application tracker: our checkout had 6,555 files and about 466,086 source lines across a catalogue, CV system, mail pipeline, assistant, extension, and many workers.

What are the alternatives to freehire?

JobSync, career-ops, Career Pilot. Our root check finished in 7 seconds but installed 0 packages and found no build or test target, so it says nothing about whether freehire's 7-service local stack starts cleanly.

Setup2/5Root pnpm does not build the Go, SvelteKit, or service stack
Docs5/5Architecture, workers, services, credentials, API, and traps are mapped
Community4/5Pushed August 25, 2026, with 487 stars and 64 issues and PRs
Maturity3/5Broad working system, but freshness and facet defects remain open

Who it’s for

Job-search products that need normalized listings from many applicant-tracking systems.
Self-hosters willing to operate a database, search index, object storage, cache, web app, API, and scheduled workers.
Contributors adding company boards or new ATS adapters to a shared catalogue.
Developers building against a public job API or extending a full candidate workspace.

Who it’s NOT for

Anyone wanting a small personal application tracker: our checkout had 6,555 files and about 466,086 source lines across a catalogue, CV system, mail pipeline, assistant, extension, and many workers.
Operators expecting pnpm install to set up the product: our root install added 0 packages, and the root manifest has no build or test target.
Teams unable to run Postgres, Meilisearch, Redis, S3-compatible storage, the Go API, and the SvelteKit web service together.
Users who need every advertised open listing to be freshly confirmed: open issue 2017 documents providers with stale rows still served as open.
Analytics buyers who require every company facet to be dependable today: issue 2088 documents false industry matches for companies without curated classifications.

Setup reality

Our sandbox root install finished in 7 seconds, added 0 pnpm packages, and used 1 MB. No root build script or target existed, so the build was skipped. No root test script or target existed, so tests were skipped. These commands did not start freehire.

The documented path uses Docker Compose for the Go API, SvelteKit web app, Postgres, Meilisearch, Redis, and MinIO. JWT_SECRET is required. OAuth, inbound mail, S3, Typst, LLM, speech, and tracing settings activate additional features.

The 6,555-file checkout contains about 466,086 source lines and many run-once workers intended for cron. Migrations run automatically only on a fresh Postgres volume; changing an existing migration requires manual application or volume recreation. Full self-hosting needs schedules, backups, index operations, and source-health monitoring.

freehire is a job data platform with a candidate workspace attached

freehire starts with a crawler and normalization pipeline rather than a blank job-board CMS. Source adapters pull listings from applicant-tracking systems, company career pages, and selected aggregators. Postgres keeps the system record, while Meilisearch serves full-text and faceted results. On top sit saved searches, CV editing, job matching, application stages, mail handling, notifications, and an in-process assistant. The public API exposes the catalogue without a key.

The README reports 3.3 million open postings from 294,282 companies and 225 live sources. Those are the project's current catalogue figures, not counts our sandbox reproduced. That distinction matters because collection freshness is part of the product. A developer can use the hosted API without operating the crawl, but a self-hoster must populate data, schedule each source, drain indexing queues, and decide how closed listings leave the catalogue.

The local stack runs seven Compose services

The quick start launches database, search, cache, object storage, storage initialization, API, and web services through Docker Compose. Postgres also needs pgvector, and the web application is a SvelteKit package linked to a sibling design system. The Go server handles request-time work, while most crawling, enrichment, indexing, notification, and backfill jobs run once and exit for an external scheduler to invoke again.

That is substantial ownership for a job-search tool. Our checkout contained 6,555 files, about 466,086 source lines, and 50 MB before any service image or data volume existed. Backups must cover candidate records, applications, CV assets, and the catalogue. Meilisearch has its own rebuild and swap process. Redis supports rate limits and fan-out, while MinIO supplies the local S3-compatible path. A single-container hobby deployment is not what this repository describes.

What happened when we ran it

Our run at commit 36828fe executed the root pnpm install in 7 seconds. It installed 0 packages and occupied 1 MB because the root package.json only identifies the project and pnpm version. The repository contains separate frontend packages plus a Go backend, so this successful command did not fetch their dependencies, compile them, launch Docker Compose, apply migrations, or request the health endpoint.

The root manifest had no build script or target, so the build step was skipped. It also had no test script or target, so tests were skipped. The repository does contain Go test files and 7 CI workflow files, but our supplied lab run did not execute them. It would be false to describe this as a passing build or test result. The harness only proved that the nearly empty root Node install completed.

Our scan found a Dockerfile and Compose file, which match the documented deployment route. A deeper operational trial would need to start all services, verify localhost:8080/health, ingest a controlled board file, drain search writes, and compare API results with the source. None of those actions occurred in this sandbox measurement, so the hosted catalogue claims and runtime behavior remain outside our lab evidence.

Required secrets are small at first and expand with features

The server requires JWT_SECRET, and the default local database URL points at Postgres. Docker Compose supplies local Meilisearch, Redis, and MinIO plumbing. OAuth providers, inbound email, remote S3 storage, LLM calls, speech transcription, tracing, and notification delivery each add their own settings. The README says optional features stay disabled when their credentials are absent.

Migrations have a specific trap. Compose mounts them into Postgres initialization, so they apply automatically only when the volume is new. Editing a migration does not change an existing database. The documented choices are to apply pending files manually or recreate the volume, which destroys local database contents. With 466,086 source lines and many workers reading the schema, production changes need an explicit migration sequence rather than reliance on first-boot behavior.

Run-once workers replace one background job service

The API server does not perform crawling, bulk enrichment, or index maintenance in its request process. Commands under cmd/ crawl individual provider files, drain enrichment and embedding queues, rebuild search, capture application forms, send notifications, and perform backfills. Postgres outbox rows coordinate those processes. This isolates slow providers and lets each schedule differ, but the operator must supply cron or another scheduler and notice nonzero exits.

The README says prune is the only hard-delete path and defaults to dry-run. That is a sound safety choice, although it does not solve stale data by itself. Open issue 2017 reports live rows that had not been seen for more than 3 days across several providers, including complete stale shares for two sources in the issue's production query. The report was still open when fetched, so catalogue users should inspect last-seen data and provider health.

Search is fast because Meilisearch holds the full public job shape

Search results can render without a Postgres round trip because the index stores the public job representation. A full reindex builds a replacement and swaps it atomically. Incremental writes pass through an outbox so many source crawls can become fewer Meilisearch updates. The architecture document also warns that deploying a new filter before its index setting can turn a Meilisearch 400 into a failed filtered page.

Facet quality still depends on classification choices. Issue 2088 says companies without a curated industry can inherit an overly broad union of domains from their open postings. Its production analysis found 9,989 companies with at least 3 domains and no curated industry. The proposed threshold needs a materialized field and company reindex. Until that work lands, consumers using industry filters should sample results rather than treating the facet as ground truth.

Current activity is high, while the latest tag covers the extension

GitHub recorded the last push on August 25, 2026, with 487 stars and 64 combined issues and pull requests. The latest release endpoint returned extension-v0.1.6, published August 17, 2026. That tag concerns the browser extension rather than a versioned release of the entire platform. The repository's issue activity includes source requests, interface work, catalogue defects, and operational investigations.

Alternatives

ProjectWhat it isPick it when
JobSyncA self-hosted application tracker with resumes, job matching, discovery, and an AI assistant.pick this instead when personal tracking and resume workflows matter more than operating a multi-source public job catalogue.
career-ops gh↗A local AI-assisted job-search workflow that runs inside coding-agent CLIs.pick this instead when one candidate wants a file-based research and application process without hosting a web platform.
Career PilotA full-stack career application covering resumes, interviews, tracking, portfolios, and outreach.pick this instead when career coaching features are central and a large crawled job index is optional.

What people are saying

  1. [github-trending] strelov1/freehire

Sources

  1. freehire README
  2. freehire architecture
  3. Stale open jobs issue 2017
  4. False company industry facets issue 2088
  5. Extension v0.1.6 release

More self-hosted reviews

playport · edge-smart-doh · Comma · ProsperoEden · zulu · node_exporter · the whole board →