How to build an applicant tracking system with OpenAI Codex
Build the hiring system your team actually wants instead of the one a vendor sells. Candidates apply through your own careers page, applications move along a pipeline your team defines, interviewers score against the same questions, and offers go out signed. Describe it from your terminal and Codex writes the schema, the permissions, and the screens.
OpenAI Codex
$ Build an applicant tracking system: a careers page people apply through, a pipeline my team moves applications along, structured scorecards per interview, and offers that go out as signed PDFs, with every table locked down so a hiring manager only reaches the searches they are on.
- Data model written as migrations
- Access scoped per job
- Ready for your review
What an applicant tracking system actually is
An applicant tracking system is the single place a role lives from the day it opens to the day someone signs: every applicant, every interview note, every decision, and who is allowed to see which of them.
Without one, a role is scattered across an inbox, a shared drive of resumes, and a spreadsheet somebody renames every Friday. Two people interview the same candidate and neither reads the other’s notes. A promising applicant goes three weeks without a reply because nobody owned the reply. An ATS pulls all of it into one record per candidate that the whole hiring team works from.
Two things make this genuinely hard, and neither is the screens. One is the permission model, where a hiring manager should see their own roles and not the compensation discussion on someone else’s. The other is that a candidate is not the same thing as an application, because one person can apply to three roles and be at a different stage in each. Get those two right and the rest of the system is mostly forms and lists on top.
One record, many readers
A recruiter, a hiring manager, and three interviewers all touch the same candidate. They need different views of it, and different permission to change it, without anyone keeping a private copy in their own notes.
A candidate is not an application
The person exists once. Their application to a specific role exists per role, with its own stage, its own scorecards, and its own outcome. Modelling those as one table is the mistake that costs a rewrite later.
Access is per job, not just per role
Job title is too blunt a permission. A hiring manager for one opening has no business reading the pipeline for a role in another department, and confidential searches need to be invisible rather than merely uninteresting.
What a bad process costs
~$4,700
is the average cost of a single hire, per SHRM’s benchmarking data as published in 2022, money that is spent whether or not the process that spent it was organised.
SHRM, 2022 (The Real Costs of Recruitment) · checked August 2026
The parts every applicant tracking system is built from
Before you build, it helps to know the pieces. Almost every ATS comes down to these six, and each one is something you can ask your AI coding tool to build or extend in plain words.
Roles, candidates, and applications
A job opening, a person, and that person’s application to that opening: three separate things that get confused constantly. Model them separately and someone can apply to two roles without their history in one overwriting the other.
A pipeline everyone reads the same way
Named stages a candidate moves through, with the move recorded rather than implied. When someone asks why a candidate is still in screening, the answer is on the record instead of in somebody’s memory.
A public way to apply
A careers page listing open roles and a form that takes an application without an account. This is the one part of the system strangers touch, so it has to work on a phone and it has to not lose a file.
Interviews and structured scorecards
Scheduling that produces a real calendar invite, and the same set of questions for every interviewer on a panel. Structured feedback is what makes two interviewers comparable rather than two opinions.
Offers, approvals, and a signature
An offer usually needs someone else to approve it before it goes out, then arrives as a document the candidate signs. Both halves belong in the system, or they end up back in email.
Reporting that answers “where is this role?”
How many candidates sit at each stage, how long they have been there, and where people drop out. Without it, a stalled search looks exactly like a healthy one until someone asks.
Own your hiring system or rent it every month
Most teams reach for a hosted ATS, then discover the tier with scorecards is two steps above the price they were quoted. Owning the system changes that arithmetic. Here is the trade-off, side by side.
Build your own
Your own hiring system is a one-time build shaped around the process your team already uses, and with an AI coding tool writing the plumbing, that build is days rather than a quarter.
- Pay to build it once, then only your own infra bills: no monthly subscription that grows with headcount
- Stages, scorecard questions, and approval chains that match how you actually hire
- Add every colleague as a user without moving up a tier to do it
- Candidate data sits in a database you control, which matters more here than in most tools
- Add your own AI on the model you pick: resume parsing, screening summaries, interview questions
- Full ownership of the code and data: export anytime, zero lock-in
Buy a hosted ATS
Workable · Greenhouse · Ashby · Breezy HRA hosted ATS is running this afternoon and someone else keeps it up. The costs are that the features you want are often gated a tier or two above the advertised price, and the process is theirs to define.
- Live in minutes: sign up and start, nothing to build or host
- Job-board distribution, sourcing extensions, and compliance reporting come built in
- Support, onboarding, and someone to call when it breaks
- Priced per company or per employee band rather than per seat, so the bill tracks how big you are, not how much hiring you do
- The features this template treats as core (scorecards, e-signature, offer management) are frequently mid or top-tier
- Two of the four vendors below publish no price at all above their entry tier
- Your candidates’ personal data lives on their servers under their retention rules
Priced per company against an employee-count selector, not per seat. The figures here are the 1-20 employee band the page opens on, and no price is published for the larger bands the same selector offers. Annual billing is quoted as a yearly total with a stated 20% saving. Watch the add-ons on Standard, which are what the sticker price leaves out: Texting+ $89/mo, Video interviews+ $109/mo, Assessments+ $59/mo, Performance & Engagement+ $39/mo, all bundled in from Premier up. The 15-day trial covers the Standard feature set but not Workable Agent.
workable.com · checked August 2026
Three named tiers and not one dollar figure anywhere on the page. Every button is “Get a demo”. Greenhouse’s own FAQ explains why, verbatim: “The cost of Greenhouse is influenced by the plan you choose (Core, Plus or Pro), your hiring volume and organizational complexity, and the features and capabilities required to support your workflows.” We quote no estimate of what it actually costs, because the vendor publishes none.
greenhouse.com · checked August 2026
Foundations is the only published price, and it is capped at 100 employees. Past that, verbatim: “Our pricing is based on company size, usage, and commitment.” Annual commitments carry a stated 10% discount. Ashby’s analytics product is priced separately, on usage, for teams running it over an ATS they already have.
ashbyhq.com · checked August 2026
The only genuinely free tier of the four, and its limit is the whole story: “1 Active Pool or Position”, with unlimited users and candidates behind it. Useful if you are hiring for exactly one job. The workflow this template ships is not on the entry paid tier either: scorecards, interview guides, and electronic signatures start at Growth ($273/mo annual), and offer management starts at Business ($439/mo annual), so a team wanting structured interviews and signed offers is comparing against those, not against $157. Annual billing is described as two months free.
breezy.hr · checked August 2026
Rule of thumb: if you hire continuously and your process has opinions (your own stages, your own scorecard questions, an approval chain that matches your org), building your own pays back quickly against a mid-tier subscription you would be on for years. If you hire two people a year, or you need job-board distribution and compliance reporting on day one without touching a codebase, buy. The awkward middle is a growing team on a free or entry tier that is about to need scorecards and signed offers, because that is the upgrade that changes the number.
Why build with Codex
Most software looks simple from the outside, but almost all of the actual work is invisible: a database, logins, permission checks, forms that validate what people type, and dozens of screens that read and write records. Doing that by hand means knowing the whole stack cold, so weeks pass before the first feature a customer would notice actually works.
Codex closes that gap by working the way a developer would, just faster. The whole workflow becomes a simple loop:
Describe
Tell Codex what you want, in plain language.
Build
It edits the real project files, backend and auth and UI, rather than replying in a chat.
Check
Run the app yourself and confirm the change works.
Repeat
Describe the next change.
None of that loop needs a computer-science background, which is why one person can take an idea to a working app over a handful of focused sessions.
Three hard partshandled for you
The data model, authentication, and access rules are the pieces that make software like this genuinely hard to build alone. Describe them and Codex scaffolds all three, leaving mostly screens to build on top.
Any language is the interface
There’s no code to write, and no requirement to describe it in English. Ask for a new field, a renamed step, or an AI summary in whatever language you think in, and Codex implements it.
Local files it edits directly
Codex works on the project on your own disk rather than a copy somewhere else, so what it changes is exactly what you see when you run the app. Point it at the handful of files that matter and it stays fast and focused.
Pay a developer, or do it with AI
Two ways to get the same app built: pay a developer for their hours, or spend your own describing it to an AI coding tool. Here is what each one costs to build, and what it costs to keep running once it is live.
Hire a developer
Custom build, from scratch- Developer
- ~$14k-$54k
- Supabase (backend)
- Free tier · $25/mo (Pro plan)*
- Hosting
- $0 free tier
- Build time
- ~270 hrs of their work
~$14k-$54k to build, then ~$25/mo after launch
That range is our ~270-hour estimate priced at market developer rates. The rate survey below puts North American contractors at $45-$75/hr and senior US developers at $100-$150+/hr, with agencies adding 20-40% on top, so roughly $50/hr at the low end, up to about $200/hr for an agency putting a senior on it. All of that is spent before your first candidate applies. After launch, your only standing costs are the database and the host.
Build it with Codex
From scratch, with Codex- Codex
- ~$20/month (Plus) to ~$200/month (Pro)
- Backend (Supabase)
- Free tier · $25/month (Pro plan)*
- Hosting
- $0 on a free tier
- Your time
- ~128 hrs
~$20-$200/month while you build, then whichever plan you keep using
Codex itself is free to install. The cost sits in the ChatGPT plan behind it, or in API usage if you sign in with a key instead. Plus, around $20/month, covers a template import or a short build. A from-scratch build that runs for weeks usually needs Pro’s top usage-multiplier tier instead, which lands around $100 to $200 a month. The fee doesn’t shrink when you start from a template the way a per-hour developer bill would: the template changes how many of the hours in the estimator above you actually spend, not which ChatGPT plan you’re paying for.
* The free Supabase tier is sized for building, not for hiring on: 500 MB of database, 2 active projects, and a pause after a week of no activity, which for a careers page means an applicant arriving at a dead link. Resumes count against storage too. The Pro plan, from $25/mo, keeps it awake.
Either column leaves you owning the system outright, so the tenth interviewer and the eleventh open role both cost nothing to add. What neither column carries is the fee every hosted system in the table above runs on: a price per seat, or per job slot, or per hire, charged for as long as you keep hiring. Yours has none of those, and the only bill that moves after launch is the database and the host.
Prices and rates from supabase.com, developex.com and learn.chatgpt.com, checked August 2026.
Decide before you build
Settle these six and the build goes smoothly. Each is a decision about how your team hires, not code to write.
Your stages, named your way
Applied, screening, interview, offer, hired is the default nobody argues with and few teams actually use. Write down the stages your team really moves people through, including the ones you would rather not admit to, before anything is built around them.
Whether stages differ per role
An engineering hire with a take-home task and a sales hire with a role-play do not fit one stage list. Decide now whether every job shares one pipeline or each job defines its own, because retrofitting per-job stages later touches every screen that reads them.
Who can see which job
The decision that shapes the whole permission model. Options run from everyone sees everything, through per-department, to an explicit list of people per job. Confidential searches are the case that decides it: if you will ever run one, you need the per-job list.
What an offer has to pass through
Nobody, a manager, or finance and a manager in sequence. The approval chain is a workflow with states and notifications, so it is much cheaper to specify now than to add once offers are already going out.
How long you keep candidate data
Rejected candidates’ data does not get to sit in your database forever, and the rules differ by where you and they are. Pick a retention period and decide whether deletion is automatic or someone presses a button, then build to it.
Which outside services you actually need
A mail sender is not optional, since the system sends candidates real email. E-signature and AI resume parsing are. Decide which of the three you are wiring up before you build, because each one is an account, a key, and a fallback for when it is down.
Comparing your build options
The starting point decides how much of the estimate goes on plumbing rather than on the parts a recruiter touches. Below is one hiring system built three ways: entirely by hand, on a UI kit that leaves everything behind the screens to you, or with Codex working task by task on the real source.
The pipeline is the small part. Most of this is the work underneath it: a schema that survives a candidate applying to three roles at once, permissions per job rather than per person, resume files, an e-signature service, and a mail sender that does not land in spam.
You get a dashboard shell, a board component, and some table screens. None of them know what a candidate is. The schema, the stage rules, the scorecards, the offers, and every integration are still yours to write.
Hand Codex one task at a time and it edits the real files (migrations, policies, screens) from the terminal, an editor extension, or a cloud run you check back on later. The same task list, worked as diffs you approve.
Estimate your exact build timeframe
Tick the parts your hiring process actually uses. Plenty of teams never send an offer through the system, or never need a careers page. The estimate below follows what you keep.
Your estimate
128 hrs
start to finish
Based on the 7 of 7 features you’ve selected, plus ~31h of groundwork. Toggle any on the left to watch the number move, and open the groundwork row to untick what you have already, such as a database that is already running or going live if you are only building a mock-up for now.
A rough estimate, not a quote. Real time depends on how much you customize and how clean your data is.
Let’s set up the tools you need
Before step 01, four things go on your computer. It takes about 15 minutes in total, and none of it is coding. Three are ordinary installers, and the fourth is a ChatGPT plan with Codex access switched on. After that, you build by describing what you want in plain language.
OpenAI Codex
Your main AI assistant. The app itself costs nothing and installs with a single command from OpenAI, then runs in your Terminal. What it costs to use is the next card: every request spends the usage allowance on your ChatGPT plan, and the free plan’s allowance is small enough that a build of this size stops early. Codex is also built into an extension for popular code editors and into the ChatGPT desktop app, which can hand a longer task off to Codex cloud to keep running in an isolated environment while you do something else.
Install Codex CLIChatGPT plan
Codex is technically included on the free ChatGPT plan too, but Free’s usage is the tightest of any tier. OpenAI doesn’t publish Free’s own cap, only that every paid tier gets a larger multiple of it, so treat Free as a way to try Codex rather than to build with it. ChatGPT Plus, around $20/month, is the realistic starting point, and a long, from-scratch build tends to need the top ChatGPT Pro tier, priced by usage multiplier at roughly $100 to $200/month. Codex can also run on pay-as-you-go API billing instead of a ChatGPT plan, if you’d rather pay per token than hold a subscription.
Compare ChatGPT plansNode.js engine
The engine that runs your app on your own computer. You never have to learn how it works: download the version marked LTS (the most stable one), install it, and forget about it.
Download Node.js (LTS)Supabase (database)
Where your project keeps its data. Install it, then sign in once by running supabase login. Words like migrations and row-level security turn up later in the guide, and Codex writes those parts for you.
Install Supabase CLINothing here is worth memorizing. These four just need to exist on your machine. From step 01 on, you say what you want and Codex runs the commands.
Build your hiring core, one Codex task at a time
Nothing here asks you to write code. You describe a task and Codex writes the files and runs the commands. The order below is deliberate: the project, then the data model, then the permission model, then the screens that depend on both. Give Codex one task, read the diff, then start the next.
- 01
Write AGENTS.md before anything is scaffolded
Codex reads AGENTS.md at the start of every task, so writing it first means the conventions are loaded before there is any code to be inconsistent with. The scaffold comes second, in the same task.
PromptSet up the projectStart by writing an AGENTS.md at the project root: the stack is React 18, Vite, TypeScript, Tailwind, and the Supabase JS client, and this project is an applicant tracking system, so note the vocabulary you should keep consistent (jobs, candidates, applications, interviews, scorecards, offers) and any conventions you want held to. You load that file automatically at the start of every later task, so nothing in it needs repeating by hand. Then scaffold the project itself: a typed Supabase client under src/lib reading VITE_SUPABASE_URL and the publishable key (the sb_publishable_… key that replaced the older anon key) from .env, with .env confirmed present in .gitignore. Start the dev server once to prove it boots before you stop.
Writing AGENTS.md first is what stops task four from inventing its own name for what task two already called an application.
- 02
Get the candidate-versus-application split right
Have Codex write the migrations for the part everyone models wrong the first time: a person exists once, and each role they apply to is a separate application with its own stage. Ask to see the SQL before it runs.
PromptDesign the hiring data modelWrite the Supabase migrations for the core of a hiring system. Jobs carry a title, department, location, employment type, description, and a status through draft, open, on hold, and closed. Candidates are the people (one row each, holding name, contact details, and a resume file in Storage) and they exist independently of any particular role. Applications sit between the two, one per candidate per job, carrying that application's own stage, source, and eventual outcome, so somebody applying to two openings ends up with two separate histories rather than one that overwrites itself. Add a job_stages table too, so each job defines its own ordered stages instead of every role sharing one list. Print the SQL for me before it runs, and regenerate the TypeScript types once it is applied.
Per-job stages are cheap now and expensive later. Every screen that reads a stage has to change if you add them after the fact.
- 03
Narrow permissions, then wire up sign-in and job access
This task touches authentication, which is exactly the kind of change worth scoping Codex down for rather than leaving the wider settings you would use for routine edits.
PromptAdd auth, roles, and job accessThis task touches authentication, so narrow your permissions to just this one rather than keeping whatever you had set for routine edits. Wire in Supabase Auth for email-and-password sign-up, login, logout, a persisted session, a profiles row per user, and a useUser hook. Then build the permission model in two layers. First, an app_role enum of 'basic', 'job_admin', and 'site_admin' with a user_roles table linking a user_id to a role, kept in its own table rather than on the account, since anything stored on the account is editable by the person it belongs to, plus a SECURITY DEFINER function has_role(_user_id uuid, _role app_role) that reads it without recursing. Second, a job_acl table listing which users can reach which specific job, and can_access_job(_user_id uuid, _job_id uuid), also SECURITY DEFINER, returning true for a site_admin or for anyone named on that job. One migration, and walk me through the diff before it runs.
A role says what kind of user someone is. The access list says which searches they are on, and only the second one can hide a confidential role.
- 04
Read this diff properly: it is the one that protects candidates
Row-level security across every table, and matching rules on the resume files. Of every diff in this build, this is the one to actually read rather than approve on trust.
PromptAdd row-level security and storage rulesTurn on row-level security across jobs, candidates, applications, and job_stages, and write the policies through can_access_job. A site_admin reaches every row. A job_admin reaches the jobs they are named on, plus the candidates and applications attached to those jobs, with write access. A basic user sees the same set read-only. Give every insert and update its own WITH CHECK clause naming exactly which job the new row is allowed to belong to, so nobody can file an application against a search they cannot see. Then carry the same rule into Storage: the resumes bucket must not be public, and fetching a file has to fail for anyone who could not read the application it belongs to. Once it is applied, walk me through proving all of it: a job_admin querying a job they are not on should come back empty, and a resume URL from that job should refuse to download.
Table policies and storage policies are written separately, so it is entirely possible to secure one and leave the other wide open.
- 05
Point Codex at the screens, a few files at a time
The public careers page and the internal board are the two surfaces this system is judged on. Codex only needs the files each screen actually touches, not the whole project.
PromptBuild the screensNow the screens, on top of what is already there. Publicly: a careers page listing open jobs, and a job page with an application form that takes a resume upload and creates the candidate and the application without asking anyone to register. Internally: a pipeline board per job using that job's own stages as columns, with drag-and-drop between them and bulk select for moving or rejecting several applications at once. And a candidate profile pulling together their details, every application they have open, and a timeline of what has happened on each. Keep the data access in typed hooks rather than spread through the components.
- 06Destination
Finish the loop to a signed offer, then verify it yourself
Interviews, scorecards, and offers close the process. This is a long, well-scoped piece of work, a reasonable one to hand to a cloud run while you do something else, provided you read the diff before it merges.
PromptAdd interviews, offers, and testAdd the last three pieces. Interviews: a table linking an application to a panel of interviewers, a time, and a stage, sending a calendar invite by email when one is booked. Scorecards: one submission per interviewer against a shared set of questions for that stage, with a combined view on the application that shows who said what rather than an average. Offers: an approval chain that has to clear before anything sends, a generated PDF, and an e-signature request against it. When that is in, run the app and take it end to end yourself (post a job, apply through the careers page as an outsider would, move the application along the board, book an interview, submit two scorecards that disagree, then send an offer), then fix whatever does not hold up.
Protecting candidate data, and who sees which pipeline
A hiring system holds personal data about people who do not work for you and never agreed to anything beyond applying. Here is how that stays protected, in simple terms, and the rule that keeps it that way.
Proven logins for your team
Your colleagues sign in through the same battle-tested system every other app uses. You do not write login security yourself. Email and password works out of the box, and social sign-in is a small addition. Candidates applying through the careers page need no account at all.
Three roles, then a list per job
The template ships three roles (a basic team member, a job admin who runs the roles they own, and a site admin over everything) and then an access list per job on top. That second layer is what makes a confidential search possible: membership of the job, not seniority, decides who can open it.
Candidate data is the sensitive kind
Resumes, contact details, interview notes, and whatever someone volunteered in an application form. This is personal data about people outside your company, which raises the stakes on every access rule and makes your retention decision a real one rather than a formality.
Row-level security across every table
The template ships 133 row-level security policies because the interesting question is never “is this person logged in” but “is this person on this job”. The database answers that itself on every read and write, so a screen that forgets to filter still cannot leak another team’s pipeline.
Resume files need the same rules as the rows
An uploaded resume is a file in storage, not a database row, and it is easy to lock the candidate record down carefully while leaving the file itself reachable by anyone holding the link. Storage gets its own access rules, written at the same time as the table’s.
Four keys, and none of them ship to the browser
Only a “publishable” key reaches the app, and it is designed to be seen. The four that matter (the database’s service key, the e-signature account, the mail sender, and whichever AI model you use) stay on the server. A hiring system accumulates more of these than most apps, which is a good reason to route them all through one place rather than four.
Your database is the only copy until you pay for one
The free tier keeps no backups at all, so during the build a bad migration is unrecoverable. Supabase Pro (from $25/mo) adds a daily backup with 7 days of history. Get on it before the first real applicant, because losing candidate records is not a setback you can quietly rebuild from memory.
Review the access rules (row-level security policies) on every table. For each one, tell me in simple terms who can view, add, edit, and delete records, confirm that people can only reach their own data while the right roles can reach more, and flag anything left open that shouldn’t be.
Paste this before launch so Codex checks nobody can see data they shouldn’t.
The one rule that matters: never put a secret key (database, e-signature, mail, or AI) in the app or a public repo. If one ever leaks, reset it right away.
What speeds the build, and what slows it
Speeds the build
- An AGENTS.md file at your project root: Codex reads it automatically before every task, so you never have to remind it
- Setting Codex’s permissions once for the session, instead of approving every small edit by hand
- Handing a long, well-scoped task to Codex cloud, so it keeps working in an isolated environment while you do something else
- Reviewing a diff in the IDE extension, next to the code it touched, before you keep it
Slows the build
- Leaving permissions wide open for a sensitive change instead of narrowing them for that one task
- Skipping the AGENTS.md file, so Codex starts each new task without your conventions loaded
- Handing Codex cloud a vague, open-ended task, where you can’t steer it mid-run the way you can in a live terminal session
- Merging a cloud task’s changes back in without reading the diff first
Git: what it is, and why you need it
Before you build anything, meet the one tool that makes building safe. You need no coding background for it: Git remembers every version of your project, so you can try things, break things, and get back to a working state in seconds.
What Git actually is
Git is a quiet recorder that runs alongside your project. Each time you save your work it keeps a full snapshot, so the entire history of your project lives on your computer, not just whatever the files look like right now.
Why you need it
Codex asks before it edits files or runs commands, unless you widen its permissions for the session. Once you do, Git is what makes that safe: there’s always a working version to return to, so you can hand it a bigger task without the fear of losing what already works.
A commit is a save point
Each commit is a snapshot with a short note, like “added the home page”. Make one after every working step and you can jump back to any of them later.
GitHub’s beginner guide to GitUndo anything, safely
If a change breaks something, you roll back to the last good commit instead of unpicking it by hand. It’s the safety net that keeps a Codex session low-risk even once you’ve widened its permissions.
GitHub is also where Codex can start from
Git lives on your computer. GitHub is a free, private cloud copy of the same project. Keep it private, and never commit secret keys or passwords. Once your project is pushed there, Codex cloud can pick up a task straight from a GitHub issue or repo, without you opening a terminal at all.
Create a free GitHub accountYou rarely type git commands
There’s little to memorize. Ask Codex to “commit this” or “undo the last change” and it runs the git steps for you, inside whatever permission boundary you’ve set. Prefer clicking to typing? The Codex extension for your editor shows each change next to the code it touched before you keep it, and GitHub Desktop gives you plain buttons for saving and rolling back.
Get CodexWhere to host your application
Hosting gives your app a home on the internet so anyone can open it via a web link. Choose a service below to make your site live. (Your database, logins, and business records are stored separately in Supabase, covered below).
| Host | Best for | Notes | Free tier |
|---|---|---|---|
| Vercel | One-click deploys | Connect the project and it publishes itself. A standard Vite setup needs no configuration. One catch worth reading before you pick it: the free Hobby tier is for personal, non-commercial projects, and a hiring system for a company is neither, so budget for Pro at $20/user/mo. | Pro from $20/user/mo (Hobby is non-commercial) |
| Netlify | Drag-and-drop or Git | Either connect the repository or drag the built folder onto the page. The quickest way to get a careers page in front of someone who wants to see it today. | Free tier |
| Cloudflare Pages | Cheapest at scale | Connect it once and every applicant loads the careers page from whichever of Cloudflare’s locations is nearest them. | Generous free tier |
| GitHub Pages | Free Git-based hosting | Publishes straight from your GitHub project, with one small setting so page links resolve. The catch matters more here than on most projects: publishing from a private repository needs a paid GitHub plan, and a hiring system’s repo should stay private, so treat this as free only if you are comfortable making the code public. | Free from a public repo only |
| Firebase Hosting | Companies already on Google | Configure it once, then every release is a single publish command. Mostly worth it if your company already lives in Google’s tooling and this is one fewer vendor to explain. | Free Spark tier |
| AWS Amplify Hosting | Teams already on AWS | Connect the project in the AWS console and set one routing rule so deep links work. Worth it mainly if procurement has already blessed AWS. | Free tier (build + hosting) |
| Surge | Publish from the terminal | One command publishes the built folder, with no repository in the loop at all. Handy for showing a work-in-progress to a colleague. | Free - unlimited publishing |
| DigitalOcean App Platform | DigitalOcean users | Point it at the project and it builds and serves the site for you, alongside whatever else you already run there. | Free - 3 static sites, 1 GB/mo transfer |
Any of these will serve the app. The thing to check before you settle is not the price but the licence: a free tier is not automatically free for business use, and Vercel’s Hobby tier is explicit that it is for personal projects only. An internal hiring tool is company use however few people log in, so read the plan terms for whichever host you pick.
Keep your data in Supabase
Postgres for the records, auth for your team, storage for resumes and offer documents, and edge functions for anything that needs a key. Whichever host serves the frontend above, all four run here.
| Service | Best for | Notes | Free tier |
|---|---|---|---|
| Supabase | Data, auth, files, functions | Postgres database, authentication, storage for resumes and offer documents, and edge functions for the parts that need a key. Create a free project and your AI coding tool connects the app to it. | Free tier, then usage-based |
Where AI genuinely helps a hiring team
With the core working, each of these is one more prompt, and they go in as written. All four call the same server-side function, so the key sits on the server where no browser can read it.
Resume parsing into a real profile
Reads an uploaded resume and fills in the candidate’s roles, dates, skills, and contact details, so nobody retypes a CV into a form. The highest-value one on this list, because it runs on every single application.
Add a server-side function that takes an uploaded resume, sends its text to your ai function, and returns structured fields (name, contact details, work history with dates, education, and skills) then pre-fills the candidate profile with them and shows the recruiter what was extracted before saving.
A screening summary against the role
Produces a short read on how an application lines up with the job description, with the specific evidence it used. It is there to save the recruiter a first pass, not to make the decision.
Add a "Summary" panel on the application view that sends the job description and the candidate’s parsed profile to your ai function and returns a short summary of where they line up and where they do not, quoting the evidence for each point. Present it as a note for the reviewer, never as a score or a recommendation to reject.
Interview questions from the role and the resume
Drafts questions for a specific panel based on the job and what the candidate has actually done, so an interviewer walking in cold still asks something worth asking.
Add a "Suggest questions" action on the interview screen that sends the job description, the interview stage, and the candidate’s profile to your ai function and returns a handful of specific questions the interviewer can edit before the call.
Pulling scorecards into one view
Rolls a panel’s separate scorecards into a summary of where interviewers agreed and where they did not, so the disagreement is the thing that gets discussed.
Add a "Panel summary" block on the candidate page that sends every submitted scorecard for that application to your ai function and returns a short summary of consensus and disagreement, listing which interviewer said what rather than averaging them into one verdict.
Each prompt above should pick whichever model tier fits the job: a fast, lower-cost model for high-volume work, and a stronger reasoning model for anything that weighs tradeoffs against each other. Codex’s model names change faster than this page does, so check OpenAI’s current model line-up (linked in the references below) before you build, rather than copying a name you saw once. Keep all of it behind that same ai function, so one key and one rule set covers every feature you add.
Get a head start with our template
Everything above assumes you are starting from an empty folder. You do not have to. The same hiring system is available already built, which turns most of that estimate into an afternoon of renaming stages to match your process.
Hiring & ATS
The exact ATS this guide builds, packaged so you can open it, point it at your own backend, and make it yours from there. An applicant tracking system for internal HR teams, agencies, and project-based hiring. Your team runs the whole process from one place - creating roles, tracking candidates, and moving them from application to offer - with AI resume parsing, shared interview scorecards, offers as signed PDFs, and real-time analytics on where every role stands.
The key benefits of starting with a template
The parts nobody enjoys building are already done and running: the schema, per-job access rules, resume storage, the offer chain, and three integrations. That leaves your time for the stages and scorecards that make it yours.
Building the core from scratch
~128 hrs
Opening the template, already built
~1 hr
~127 hrs of building you skip
Two different measurements, deliberately: ~128 hrs is what building the core costs you, and ~1 hr is how long the finished one takes to open and point at your own database. Adapting it to your stages, your scorecard questions, and your approval chain takes the same time whichever column you start from, so neither side counts it.
A working hiring system from day one
Open a functional app, not an empty folder. Jobs, candidates, the pipeline board, interviews, scorecards, offers, and the dashboard over them are ready to use.
Pre-configured access rules
Team accounts, three roles, a per-job access list, and 133 row-level security policies work out of the box, so a hiring manager reaches their own roles and nobody reaches a confidential search by accident.
The integrations already wired
Resume parsing, generated offer PDFs, e-signature, calendar invites, and transactional email are connected and working. Each one is an account and a key you supply, not a feature you build.
Clean structure your AI can safely customize
Typed throughout, organised by feature, and documented, which matters more than it sounds, because every later change you describe lands better when the tool has a clear pattern to follow.
From founders who build on our templates
We needed to get a live product in front of users fast. Instead of building from a blank repo, I picked up this template, customized it with our AI tool, and shipped straight away, bypassing the usual setup process.
Jeevan ThomasFounder & CEO, Hado.aiCommon questions
No, and you will not write the access rules by hand either. Describe what you need in plain language and your AI coding tool produces the schema, the row-level policies, the storage rules for resume files, and the server-side functions behind them. The one thing you do yourself is create a free Supabase project to point it at, so the data ends up somewhere you own.
Yes, and the data model is built for it. The candidate is one record. Each application to a specific job is its own record with its own stage, scorecards, and outcome. Someone can be rejected for one role and mid-interview for another without the two interfering.
Yes, and this is the part worth getting right early. Alongside the three roles, each job carries its own access list, so a confidential search is visible only to the people explicitly on it, enforced by the database rather than by hiding a link in the interface.
Yes. Resume parsing is the one most teams add first, followed by screening summaries, interview questions, and scorecard summaries. Add a small server-side ai function, pick the model tier that fits the job, and keep the key on the server, never in the app.
No, and the guide is written so it cannot. Every AI feature here summarises or extracts for a person who then decides. Nothing rejects an application on its own. Automated hiring decisions are regulated differently depending on where you and your candidates are, so check what applies to you before you go further than this guide does.
Only the services you connect with your own accounts: Supabase for the backend, a mail sender, and optionally an e-signature provider and an AI model. Supabase and hosting both start free. Before real candidates can apply, Supabase Pro starts at $25/mo, since free projects pause after 1 week of inactivity. You pay those providers directly.
Only the people your access rules allow, and it lives in the Supabase project you created. That makes you the sole controller of that data for GDPR purposes, which also means the retention decision is yours: decide how long rejected candidates’ records stay and build that in, rather than leaving them indefinitely by default.
There is nothing proprietary to be locked into. It is an ordinary PostgreSQL database, so an ordinary Postgres dump gives you every candidate, application, and scorecard, and any Postgres host will take it. Worth knowing for a second reason here: a request to delete a candidate’s data is much easier to honour when you can see exactly where all of it sits.
Yes. Whichever host you pick lets you connect a custom domain with free HTTPS in a few clicks, worth doing before the careers page goes out, since that URL ends up in every job ad.
No, though you will type the occasional command: installing Codex, starting the app, applying a database change. The setup section above lists what you need, with a link for each, and once it’s on your machine Codex runs most of those commands for you.
A regular ChatGPT chat can sketch ideas and write snippets, but it isn’t working on your actual project. Codex reads and edits the real files on your computer. The app you get out of it is one you can run and publish, not a preview.
On a ChatGPT plan, Codex’s usage resets on a rolling window rather than billing per token, so a heavy day of building can bump into a limit. You either wait for it to reset, move up a plan, or switch to pay-as-you-go API billing for the rest of the session. Nothing you’ve already built is lost either way, so the work only pauses.
References
Sources checked August 2026- 01The Real Costs of Recruitment (average cost per hire), SHRM. shrm.org (published 2022)
- 02Pricing, Workable. workable.com
- 03Pricing, Greenhouse. greenhouse.com
- 04Pricing, Ashby. ashbyhq.com
- 05Pricing, Breezy HR. breezy.hr
- 06Pricing (Pro plan, free-tier limits, backups), Supabase. supabase.com
- 07Web developer hourly rates 2026 (freelance and agency benchmarks). developex.com
- 08Row Level Security, Supabase docs. supabase.com
- 09Storage access control, Supabase docs. supabase.com
- 10Pricing (plans, usage limits), ChatGPT docs. learn.chatgpt.com
- 11Codex CLI, ChatGPT docs. learn.chatgpt.com
- 12API pricing (models), OpenAI for developers. developers.openai.com
- 13IDE extension, ChatGPT docs. learn.chatgpt.com
- 14ChatGPT desktop app, ChatGPT docs. learn.chatgpt.com
- 15Codex cloud, ChatGPT docs. learn.chatgpt.com
- 16AGENTS.md, ChatGPT docs. learn.chatgpt.com
This guide is general information, and not legal or HR advice. Hiring, candidate data, and automated decision-making are regulated differently depending on where you and your candidates are, so check what applies to you. Third-party prices, plan limits, and market rates are quoted from the sources above and were last checked on the date shown. Vendors change them without notice, so confirm before you budget. Build hours and the cost estimates derived from them are our own estimates, not quotes. Codex, ChatGPT, and the OpenAI API are products of OpenAI. Verify current capabilities and pricing before relying on them.