[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-94942":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":9,"totalLinesOfCode":9,"stars":12,"forks":13,"watchers":14,"openIssues":14,"contributorsCount":9,"subscribersCount":14,"size":14,"stars1d":14,"stars7d":14,"stars30d":14,"stars90d":14,"forks30d":14,"starsTrendScore":14,"compositeScore":15,"rankGlobal":9,"rankLanguage":9,"license":9,"archived":16,"fork":16,"defaultBranch":17,"hasWiki":16,"hasPages":16,"topics":18,"createdAt":9,"pushedAt":9,"updatedAt":39,"readmeContent":40,"aiSummary":41,"trendingCount":14,"starSnapshotCount":14,"syncStatus":42,"lastSyncTime":9,"discoverSource":43},94942,"freehire","strelov1\u002Ffreehire","strelov1","freehire — the open-source search engine for job seekers",null,"https:\u002F\u002Fgithub.com\u002Fstrelov1\u002Ffreehire","Go",387,78,0,42.69,false,"main",[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"ats","careers","hiring","job-aggregator","job-board","job-search","jobs","recruitment","remote-jobs","job-scraper","career","job-portal","golang","langchain","llm","meilisearch","postgresql","self-hosted","svelte","sveltekit","2026-08-24 04:01:23","\u003Cdiv align=\"center\">\n\n\u003Cpicture>\n  \u003Csource media=\"(prefers-color-scheme: dark)\" srcset=\"docs\u002Fassets\u002Flogo-dark.svg\">\n  \u003Cimg src=\"docs\u002Fassets\u002Flogo-light.svg\" alt=\"freehire\" width=\"84\" height=\"84\">\n\u003C\u002Fpicture>\n\n# freehire\n\n### Every IT job, straight from the source.\n\n**3.3M+ live postings pulled directly from company career pages — no recruiters, no reposts, no dead links. Fully open source.**\n\n[**Try it live →**](https:\u002F\u002Ffreehire.me) · [Features](docs\u002Ffeatures.md) · [Architecture](docs\u002Farchitecture.md) · [Sources](#sources) · [API](#api) · [Add a source](#adding-a-source) · [Contributing](CONTRIBUTING.md)\n\n[![Live](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flive-freehire.me-0a0a0a)](https:\u002F\u002Ffreehire.me)\n[![License: MIT](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flicense-MIT-blue.svg)](LICENSE)\n![Go version](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fgo-mod\u002Fgo-version\u002Fstrelov1\u002Ffreehire)\n![Last commit](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Flast-commit\u002Fstrelov1\u002Ffreehire)\n[![Stars](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fstars\u002Fstrelov1\u002Ffreehire?style=social)](https:\u002F\u002Fgithub.com\u002Fstrelov1\u002Ffreehire\u002Fstargazers)\n[![Discord](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FDiscord-join-5865F2?logo=discord&logoColor=white)](https:\u002F\u002Fdiscord.gg\u002FaAXS2rghW)\n\n\u003Cbr>\n\n\u003C!-- Product Hunt: launching 26 August 2026. The badge is Product Hunt's own embed,\n     one SVG per theme, picked by prefers-color-scheme the same way the logo above is.\n     Its own utm_campaign so this traffic is separable from the site footer's badge. -->\n\u003Ca href=\"https:\u002F\u002Fwww.producthunt.com\u002Fproducts\u002Ffreehire?embed=true&amp;utm_source=badge-featured&amp;utm_medium=badge&amp;utm_campaign=badge-readme\">\n  \u003Cpicture>\n    \u003Csource media=\"(prefers-color-scheme: dark)\" srcset=\"https:\u002F\u002Fapi.producthunt.com\u002Fwidgets\u002Fembed-image\u002Fv1\u002Ffeatured.svg?post_id=1196233&amp;theme=dark\">\n    \u003Cimg src=\"https:\u002F\u002Fapi.producthunt.com\u002Fwidgets\u002Fembed-image\u002Fv1\u002Ffeatured.svg?post_id=1196233&amp;theme=light\" alt=\"freehire — every IT job, straight from the source | Product Hunt\" width=\"250\" height=\"54\">\n  \u003C\u002Fpicture>\n\u003C\u002Fa>\n\n\u003Ca href=\"https:\u002F\u002Ftrendshift.io\u002Frepositories\u002F55060?utm_source=trendshift-badge&amp;utm_medium=badge&amp;utm_campaign=badge-trendshift-55060\" target=\"_blank\" rel=\"noopener noreferrer\">\u003Cimg src=\"https:\u002F\u002Ftrendshift.io\u002Fapi\u002Fbadge\u002Ftrendshift\u002Frepositories\u002F55060\u002Fdaily?language=Go\" alt=\"strelov1%2Ffreehire | Trendshift\" width=\"250\" height=\"55\"\u002F>\u003C\u002Fa>\n\n\u003Cbr>\n\n\u003Cimg src=\"docs\u002Fassets\u002Ffreehire.gif\" alt=\"freehire — faceted search narrowing 3.3M+ live postings by region, work format, specialization and seniority, each linking straight to the company's own careers page\" width=\"860\">\n\n\u003C\u002Fdiv>\n\n## Why freehire?\n\n- **Straight from the source.** Every listing is crawled directly from a company's\n  own ATS — Workday, Greenhouse, Lever, Ashby, iCIMS and a long tail of others — and\n  links to the original posting. No recruiter reposts, no aggregator middlemen, no\n  dead links.\n- **One schema, deduplicated.** The same role posted to three boards collapses into\n  one entry: every posting is normalized into a single shape and deduplicated on a\n  stable key.\n- **Search that understands jobs.** Faceted full-text search over region, work mode,\n  seniority, skills and salary — derived from curated dictionaries, never guessed.\n- **Actually open.** MIT-licensed and self-hostable, pipeline and data both in the\n  open. Adding a company is one line of YAML.\n- **Yours to build on.** A clean HTTP API, a CLI, Telegram digests, and a whole\n  workspace on top of the catalogue — see [Beyond the catalogue](#beyond-the-catalogue).\n  Use the hosted site, run your own, or build on top.\n\nAggregating **3.3M+ live postings** from **294,000+ companies** across **92 ATS\nplatforms** and a long tail of aggregators and direct feeds — **225 live sources**\nin all, see [Sources](#sources) for the full breakdown.\n\n> If freehire saves you time — or you just like the idea of jobs straight from the\n> source — a ⭐ helps other people find it.\n\n## Beyond the catalogue\n\nFinding the posting is half the problem. The other half — writing the CV,\nsending it, and knowing what happened to it — is built on the same data, in the\nsame repository, under the same licence.\n\n| | |\n| --- | --- |\n| **Find** | Faceted search, curated collections, saved searches with email\u002FTelegram digests, shared boards, market analytics, the ghost-job signal |\n| **Apply** | CV builder with ATS-safe PDF templates, deterministic CV↔vacancy scoring, AI fit analysis, CV tailoring that invents nothing, tracer links, referrals |\n| **Track** | An application board with stages, a mail inbox that links recruiter replies to the application they answer, an append-only event ledger, reminders |\n| **Ask** | An in-process agent with five presets — chat, browse, profile, CV tailoring, interview rehearsal — with no shell and no minted credential |\n| **Build on** | A keyless public API, a [CLI](https:\u002F\u002Fgithub.com\u002Fstrelov1\u002Ffreehire-cli), an [MCP server](https:\u002F\u002Fgithub.com\u002Fstrelov1\u002Ffreehire-mcp) for Claude Desktop and Claude Code, a form-filling browser extension, ChatGPT Actions |\n\n**[Full feature reference → `docs\u002Ffeatures.md`](docs\u002Ffeatures.md)** — what each one\ndoes, where it lives in the tree, which need an LLM endpoint configured, and\nwhich draw on AI credits.\n\n## Stack\n\n- **Go** + [Fiber v2](https:\u002F\u002Fgofiber.io\u002F) — HTTP server\n- **PostgreSQL** + [pgvector](https:\u002F\u002Fgithub.com\u002Fpgvector\u002Fpgvector) — storage, filtering, semantic embeddings\n- **[sqlc](https:\u002F\u002Fsqlc.dev\u002F)** — type-safe DB access from SQL (no ORM)\n- **[Meilisearch](https:\u002F\u002Fwww.meilisearch.com\u002F)** — full-text and faceted job search\n- **[langchaingo](https:\u002F\u002Fgithub.com\u002Ftmc\u002Flangchaingo)** — LLM access over any OpenAI-compatible endpoint (no vendor baked in)\n- **[SvelteKit](https:\u002F\u002Fkit.svelte.dev\u002F) 2** (Svelte 5 runes) + **Tailwind 4** — the server-rendered frontend under `web\u002F`\n- **Redis** — rate limiting and realtime fan-out · **S3-compatible object storage** — CVs, headshots, previews\n- **Docker Compose** — local development\n\n## Quick start\n\n```bash\nmake up        # build + start the whole stack in Docker:\n               # api, web, postgres, meilisearch, redis, minio\ncurl localhost:8080\u002Fhealth\ncurl localhost:8080\u002Fapi\u002Fv1\u002Fjobs\n```\n\nMigrations are applied automatically on first Postgres volume init\n(the `migrations\u002F` folder is mounted into `\u002Fdocker-entrypoint-initdb.d`).\nChanging a migration does not re-apply to an existing volume — recreate it with\n`docker compose down -v && make up`, or apply pending files manually with\n`make migrate`.\n\nIf port 8080 is already taken, pick another host port:\n\n```bash\nHIRE_HOST_PORT=8090 make up\n```\n\n## Local development\n\n```bash\ndocker compose up -d db   # database only\nmake run                  # server on host, reads DATABASE_URL\n```\n\nCopy `.env.example` to `.env` and adjust as needed. `JWT_SECRET` is required for\nthe server to start; OAuth and LLM credentials are optional (the features they\ngate stay disabled when unset).\n\n## Commands\n\n```bash\nmake help      # list all commands\nmake sqlc      # regenerate code from SQL (via Docker, no local sqlc needed)\nmake tidy      # go mod tidy\nmake psql      # psql inside the DB container\nmake reindex   # rebuild the Meilisearch index from Postgres\nmake migrate   # apply migrations manually to an existing DB volume\n```\n\n## Workers\n\nThe server only serves the API. Everything else — crawling, enrichment, indexing,\nnotifications — is a standalone, run-once worker meant for cron: it crawls or\ndrains its queue and exits. `ls cmd\u002F` for the full list; the ones you are most\nlikely to run:\n\n```bash\ngo run .\u002Fcmd\u002Fmigrate       # apply pending migrations (run before deploying code that reads new schema)\ngo run .\u002Fcmd\u002Fingest sources\u002Fgreenhouse.yml  # crawl one board file and upsert jobs (path also via SOURCES_FILE)\ngo run .\u002Fcmd\u002Fenrich        # drain the enrichment queue (LLM); needs LLM_* config\ngo run .\u002Fcmd\u002Fembed         # drain the semantic queue into pgvector chunks\ngo run .\u002Fcmd\u002Fsearch-drain  # push queued job writes into the live search index (run every 1-2 min)\ngo run .\u002Fcmd\u002Freindex       # rebuild the Meilisearch index from Postgres (full swap)\ngo run .\u002Fcmd\u002Ftg-ingest     # crawl the Telegram channels in sources\u002Ftelegram.yml\ngo run .\u002Fcmd\u002Ftg-extract    # LLM-extract vacancies from crawled Telegram posts\ngo run .\u002Fcmd\u002Fcapture-apply-form  # fetch queued postings' ATS application forms\ngo run .\u002Fcmd\u002Fbackfill-derive     # re-derive every deterministic column — facets, fingerprints,\n                                 # slugs — in one keyset pass (follow with make reindex)\n```\n\nEvery worker needs `DATABASE_URL` and exits non-zero on failure. `prune` is the\nonly hard-delete path in the system, and it is dry-run by default.\n\n## Layout\n\n```\ncmd\u002F                 entry points: server + the standalone workers above\nsources\u002F             board files, one per provider (e.g. greenhouse.yml = company + board id),\n                     plus a mixed custom.yml and telegram.yml (Telegram channels to crawl)\nmigrations\u002F          SQL schema (source for both sqlc and initdb)\nweb\u002F                 the SvelteKit frontend\nextension\u002F           the Chrome side-panel extension\ndesign-system\u002F       shared tokens and components, linked into web\u002F and extension\u002F\ninternal\u002F            ~130 domain packages; the load-bearing ones:\n  config\u002F            env configuration\n  database\u002F db\u002F      pgxpool pool; generated sqlc code + queries\u002F*.sql\n  handler\u002F           HTTP handlers\n  auth\u002F              auth primitives (JWT cookie, API keys) + OAuth sign-in\n  sources\u002F           source adapters (greenhouse \u002F lever \u002F adzuna \u002F …) + registry\n  pipeline\u002F          ingest runner (fetch → normalize → dedup → upsert)\n  linksource\u002F        resolves outbound job links found in Telegram posts\n  telegram\u002F          Telegram-channel crawl + LLM vacancy extraction\n  enrich\u002F            typed AI-enrichment contract + queue-draining runner\n  search\u002F searchdrain\u002F  Meilisearch indexing and query; incremental drain of the write queue\n  embed\u002F             semantic chunk embeddings into pgvector\n  location\u002F classify\u002F skilltag\u002F  the curated facet dictionaries — never guess, emit nothing\n  ghost\u002F             the posting-reality signal behind \"is this job real?\"\n  jobview\u002F           the single public wire shape of a job\n  cv\u002F cvedit\u002F        structured CVs + PDF rendering; cvedit is their only writer\n  experience\u002F        durable employments + evidence atoms behind every CV claim\n  cvmatch\u002F matchanalysis\u002F  deterministic CV↔vacancy score; the LLM fit analysis on top\n  applyform\u002F         captured ATS application forms, in the platform's own vocabulary\n  userjob\u002F appevent\u002F per-user tracking (view \u002F apply \u002F save \u002F stages) + the event ledger\n  inbox\u002F             recruiter mail → classify → link to an application\n  assistant\u002F         the in-process agent: turn loop, tools, transcripts\n  browsertools\u002F      relays tool frames between the agent and the browser extension\n  referral\u002F collections\u002F  employee referrals; curated company tags\n  llm\u002F llmkey\u002F       provider-agnostic LLM client + per-user spend attribution\n```\n\n## Architecture\n\nHow the pieces fit together — the crawl-to-search topology, what each directory\nabove is for, and walkthroughs of the three main flows (finding a job, tailoring a\nCV, the in-app assistant), plus the auth model, notifications and the job\nlifecycle: **[docs\u002Farchitecture.md](docs\u002Farchitecture.md)**.\n\nIt is the map; the per-package `AGENTS.md` files it links to are the territory.\n\n## API\n\nThe catalogue is served over a public, keyless HTTP API — `GET\nhttps:\u002F\u002Ffreehire.me\u002Fapi\u002Fv1\u002Fjobs` needs no credential. All responses use\n`{\"data\": ...}` (single), `{\"data\": ..., \"meta\": {...}}` (lists), or\n`{\"error\": msg}`; jobs and companies are addressed by their public slug.\n\n**Full reference — every endpoint, its parameters, auth mode and the whole\nsearch-filter vocabulary: [freehire.me\u002Fdocs\u002Fapi](https:\u002F\u002Ffreehire.me\u002Fdocs\u002Fapi).**\n\n## Sources\n\nLive catalogue snapshot — **3,300,615 open postings** across **294,282 companies**,\ncrawled from **225 live sources**. Counts are open postings unless noted; a\ncompany crawled from two sources is counted under each. Every source is one of\nthree kinds:\n\n- **ATS platforms** — one adapter per multi-tenant applicant-tracking system,\n  each serving many companies (Workday, Greenhouse, Lever, iCIMS…).\n  **92 platforms · 157,399 companies · 2,644,796 open postings.**\n- **Aggregators & job boards** — third-party feeds that republish many\n  companies' postings (Adzuna, trudvsem, himalayas, Telegram channels…).\n  **100 sources · 172,884 companies · 629,571 open postings.**\n- **Company career sites** — direct single-company feeds crawled from a\n  company's own careers page (Amazon, Apple, Google, Yandex, Sber…).\n  **30 feeds · 59 companies · 26,222 open postings.**\n\nA source's kind is not configuration but a property of the adapter's own Go type,\nso `internal\u002Fsources` classifies every provider without a network call.\n\nFull per-source breakdown — every source with its own companies\u002Fopen-jobs\ncount — lives on its own page: [docs\u002Fsources.md](docs\u002Fsources.md).\n\n## Adding a source\n\nAdding a company is one entry in the provider's board file (`sources\u002F\u003Cprovider>.yml`,\nor the mixed `sources\u002Fcustom.yml`) — `company` + `board` (and `provider` when an\nentry overrides the file's). Adding an ATS platform is a new adapter in\n`internal\u002Fsources` plus one line in `sources.All` — every adapter speaks the same\n`Source` interface, and `cmd\u002Fingest` validates the file against the registry before\nany crawl.\n\nFor most companies the platform is already supported, so adding them is just one\nline in the board file. Only when a company runs on an ATS we don't cover yet does\nit need a new provider (a new adapter). Either way, if you want a source added,\n**start by [opening an issue](https:\u002F\u002Fgithub.com\u002Fstrelov1\u002Ffreehire\u002Fissues)** — name\nthe company and its careers URL, and we'll confirm whether it's a one-line add or a\nnew provider before any code.\n\n## Frontend\n\nA server-rendered SvelteKit 2 app (Svelte 5 runes, Tailwind 4, `adapter-node`)\nlives under `web\u002F` and consumes the API same-origin; a dev Vite proxy forwards\n`\u002Fapi` to the backend. Shared tokens and components come from the sibling\n`design-system\u002F` package — install it before building `web\u002F` or `extension\u002F`,\nsince it is symlinked, not copied. See [web\u002FAGENTS.md](web\u002FAGENTS.md).\n\n## Browser extension\n\nA Chrome extension puts the job-application agent in a side panel next to\nwhatever posting you're on: it reads the page when you ask it something, shows\na deterministic skill-coverage match against your freehire profile, and can\nfill the application form for you. Source lives under `extension\u002F`\n([extension\u002FAGENTS.md](extension\u002FAGENTS.md)).\n\n**[Install it from the Chrome Web Store →](https:\u002F\u002Fchromewebstore.google.com\u002Fdetail\u002Ffreehire\u002Fijfaechijopdlikalojadpojmpilplnj?hl=en-US&utm_source=ext_sidebar)**\n\n## Contributing\n\n**Contributions are welcome, and issues and PRs are open to everyone.** No\nallowlist, no approval step — open one.\n\nThe easiest way to help is to **add a source**: one entry in a `sources\u002F` board\nfile, or a new adapter in `internal\u002Fsources`. Missing a company you would apply\nto? That is a one-line PR, and it is the single most useful thing you can send.\n\nQuestions and half-formed ideas are equally welcome in\n[Discussions](https:\u002F\u002Fgithub.com\u002Fstrelov1\u002Ffreehire\u002Fdiscussions) — no need to\npolish them into an issue first. For anything large, an issue up front saves you\nfrom building the wrong thing, but nothing stops you from just opening the PR.\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the checks CI runs and\n[AGENTS.md](AGENTS.md) for the architecture and conventions.\n\n## Security\n\nFound a vulnerability? Report it privately — see [SECURITY.md](SECURITY.md). Do\nnot open a public issue for security-sensitive reports.\n\n## License\n\n[MIT](LICENSE)\n","freehire 是一个面向求职者的开源职位搜索引擎，专注于 IT 领域。它通过自研爬虫直接从公司官网职业页面（对接 Workday、Greenhouse、Lever 等主流 ATS）实时抓取并去重 330 万+ 在线职位，统一归一化为标准字段，并提供基于地区、远程类型、职类、职级的多维筛选与 Meilisearch 支持的全文检索。项目采用 Go 后端 + SvelteKit 前端，支持完全自托管，适用于希望绕过中介、获取一手真实岗位信息的技术求职者及小团队招聘工具集成。",2,"trending"]