ResumeLM: a self-hostable AI resume builder built on Next.js 15 and Supabase
Open-source AI resume builder • Next.js 15, React 19, Tailwind CSS • Tailor job-ready resumes in minutes.
At a glance
- What is it?
- ResumeLM is an AGPL-3.0 Next.js application that generates and scores tailored resumes against a job listing, with bring-your-own AI keys or a paid hosted plan. It is a real codebase, not a template, and the install path runs through Supabase and Postgres before it runs through a model.
- Who is it for?
- Adopt ResumeLM if you want a resume builder you can run on your own infrastructure and point at your own model keys, and if you are comfortable operating Supabase and Postgres alongside it. Do not adopt it if you want a hosted product with no database to run, or if you are unwilling to accept the AGPL-3.0 network-copyleft obligation.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What ResumeLM actually solves for job seekers
The problem ResumeLM targets is specific: a single resume sent to every posting. The README describes it as an "open-source AI resume builder" that helps job seekers "create professional, ATS-aware resumes and tailored versions for specific applications." The unit of work is not one document but a pair: a base resume stored in the profiles table, and tailored versions stored in the resumes table, with a jobs table holding the listings those versions target.
That structure is the whole pitch. Version control across applications is normally something you manage by hand with folders named final_v3. Here the tailoring is a first-class object linked to a job record, and the AI features operate on that pair rather than on a blank page. The README lists four capabilities: AI-assisted bullet editing, resume performance scoring with ATS compatibility analysis and keyword insights, an AI cover letter generator, and a dashboard for organizing the search.
Who it is for is narrower than "job seekers." The README calls it a builder "for tech job applications," and the stack confirms that audience. A self-hoster needs Node.js 18+, pnpm, a PostgreSQL database, and a Supabase account before the first resume exists. If you are not willing to run that, the hosted instance at resumelm.ca is the intended path, and the README states the free plan supports your own AI provider keys while Pro is $20/month with app-funded premium model access.
How the AI layer and the data model fit together
The architecture is a Next.js 15 App Router application on React 19 and TypeScript, with Supabase providing auth and Postgres, and a model layer that is deliberately multi-provider. package.json shows AI SDK adapters for Anthropic, DeepSeek, Google, Google Vertex, Groq, OpenAI, and OpenRouter, plus @react-pdf/renderer for PDF output and Stripe for payments. That is a lot of provider surface for one feature set, and it tells you the model choice is meant to be swappable rather than fixed.
The data flow implied by the README's database section is: a profile row holds base information in JSON fields (work_experience, education, skills) with a one-to-one relationship to auth.users; a resumes row holds either a base or tailored version, links to a job, and stores section_order and section_configs as JSONB; a jobs row holds the listing. Row Level Security is enabled, which the README frames as security but which in practice means every query path has to respect the policy or it returns nothing.
The AI features sit on top of that. The assistant suggests bullet content, the scoring feature analyses ATS compatibility and keywords, and the cover letter generator produces a document matched to the job. Note what is not in the README: there is no description of how the ATS score is computed, no rubric, no list of checks. The scoring is presented as a feature with screenshots, not as a documented algorithm. Treat the number it returns as a directional signal from a model, not as a validated ATS simulation.
Installing ResumeLM locally with pnpm
The README's quick start is a standard Node workflow. You need Node.js 18+ and pnpm (npm is listed as acceptable), plus a PostgreSQL database and a Supabase account. Clone the repository and move into it, then install dependencies with pnpm.
git clone https://github.com/olyaiy/resume-lm.git
cd resume-lm
pnpm installNext, create your local environment file from the example. The README copies .env.example to .env.local.
cp .env.example .env.localThen fill in the variables the README lists: DATABASE_URL, SUPABASE_URL, SUPABASE_ANON_KEY, OPENROUTER_API_KEY, ANTHROPIC_API_KEY, GOOGLE_AI_API_KEY, NEXTAUTH_URL, NEXTAUTH_SECRET, and optionally STRIPE_SECRET_KEY and STRIPE_PUBLISHABLE_KEY. The .env.example file marks OPENROUTER_API_KEY as the one required for the app-funded defaults, and notes OPENAI_API_KEY is retained for compatibility with custom or legacy deployments.
Before the app will start usefully, the schema has to exist. The README says to run schema.sql in your Supabase SQL editor, or use the Supabase CLI.
supabase db push --db-url=your_supabase_db_url schema.sqlFinally, start the development server and open http://localhost:3000 in a browser.
pnpm devWhat you should see is a local ResumeLM instance at that address, with sign-in handled by Supabase and an empty resume dashboard until you create a base resume.
Running the full stack with Docker Compose
The repository ships a docker/ directory, and the README presents Docker as the alternative that brings up "Supabase, PostgreSQL, Redis, and all services." The .env.example file is pre-configured for this path: NEXT_PUBLIC_SUPABASE_URL points at http://localhost:54321 and both anon and service role keys are filled in with Supabase demo values. It also defines SEED_ADMIN_EMAIL and SEED_ADMIN_PASSWORD for an admin user created on startup, and AUTO_PRO_SUBSCRIPTION=true to skip Stripe locally.
The sequence the README gives copies the environment file, starts the stack from the docker directory, waits roughly 60 seconds, checks health, then runs the app from the project root. The compose file is invoked with an explicit --env-file pointing at the parent .env.local, which matters because the compose file lives one level down.
cp .env.example .env.local
cd docker
docker compose --env-file ../.env.local up -d
docker compose --env-file ../.env.local ps
cd ..
pnpm devOne warning in the README is worth repeating rather than paraphrasing: create a local account with credentials you control, and do not reuse the example credentials in development or production. The seed values in .env.example are public in the repository. The stack exposes the app on port 3000, the Supabase API on 54321, Supabase Studio on 54323, and Redis Commander on 8081. For cloud deployments the file notes USE_LOCAL_REDIS=false with UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN instead of REDIS_URL.
Where ResumeLM is the wrong tool
The clearest limitation is operational weight. This is not a static site generator for resumes, and it is not a YAML-in, PDF-out pipeline. It is a web application with auth, a relational database, row level security, Redis, and optional Stripe wiring. If your actual need is a versioned plain-text resume that renders to PDF in CI, ResumeLM is several orders of magnitude more machinery than the job requires, and you would be maintaining a Supabase instance to produce a document.
The second limitation is that the AI output is unverified by the project. The README markets ATS-aware formatting and keyword optimization but does not document the scoring methodology, so there is no way from the repository description alone to know whether a given score correlates with any real applicant tracking system. A resume that scores well here can still be rejected by a recruiter, and the reverse is also true.
The third is maintenance. The last push to the default branch was on 2026-09-03, and the repository is not archived, so the codebase is recent. That is not the same as a stable release history: no releases were retrieved, and package.json still carries version 0.1.0. There is no published upgrade path, and the README does not document rollback or migration between schema versions. If you self-host, you are tracking main.
How ResumeLM differs from hosted resume builders
The obvious alternative is a hosted builder such as resume.io, which is a closed product where you pay a subscription and your resume lives on someone else's infrastructure. The difference is not feature parity, it is control and cost structure. With ResumeLM self-hosted, the storage is your Postgres, the model calls are billed to your provider key, and the code is inspectable. With a hosted builder, you get a maintained product with no database to operate and no provider keys to manage, and you give up the ability to change how tailoring works.
A second alternative is the template-and-Markdown approach: keep a resume in YAML or Markdown, version it in Git, and render it with a tool like a JSON Resume theme or a LaTeX template. That approach has no AI tailoring and no ATS scoring, but it has no server either, and the diff between two applications is readable in a pull request. ResumeLM's tailoring is model-generated and stored in JSONB, which is far harder to review line by line.
The meaningful difference between ResumeLM and both alternatives is that it treats the job listing as a first-class row. Tailoring is a relation between a resume and a job, not a manual edit. If you apply to many similar roles and want that relation tracked, the data model is doing real work. If you apply to a handful of roles a year, it is not.
Licence and the cost of running your own copy
ResumeLM is licensed AGPL-3.0. For a job seeker running a private instance, the practical effect is minimal. For anyone who modifies the code and offers it to users over a network, the AGPL's network clause is the part to read carefully, because it can require offering the corresponding source to those users. This is a description of the licence's known shape, not legal advice; if you plan to run a modified ResumeLM as a service, get counsel rather than a README summary.
The upgrade cost is the more immediate concern. The README documents first-time setup and nothing about applying schema changes to an existing database. schema.sql is a top-level file, and the Supabase path runs it once via the SQL editor or supabase db push. There is no migrations directory described in the repository and no documented procedure for moving an existing instance forward when the schema changes. That means a self-hoster should expect to read schema.sql diffs by hand before applying them, and should keep a database backup outside the app's own tooling. The scripts directory contains check-public-contracts.mjs, exposed as pnpm check:trust, which the repository layout suggests is a guard on public interfaces, but the README does not explain what it enforces.
Editorial conclusion
Adopt ResumeLM if you want a resume builder you can run on your own infrastructure and point at your own model keys, and if you are comfortable operating Supabase and Postgres alongside it. Do not adopt it if you want a hosted product with no database to run, or if you are unwilling to accept the AGPL-3.0 network-copyleft obligation. Before committing, verify that schema.sql applies cleanly against your Supabase project, that your chosen provider key works under the model names the app expects, and that the docker compose stack comes up healthy on your host.
Frequently asked questions
Is ResumeLM free to use?
The README states ResumeLM is open source and self-hostable, and that the free plan supports your own AI provider keys. Pro is listed at $20/month and provides app-funded premium model access. A payment method is required for the optional trial.
Can employers detect AI resumes?
The README does not address detection. It describes AI-assisted bullet editing, ATS compatibility scoring, and cover letter generation, and presents the output as ATS-aware, but it makes no claim about whether a recruiter or a screening system can identify AI-written content.
Which is the best AI tool for resume?
The README does not compare ResumeLM to other tools, so it offers no ranking. What it does state is that ResumeLM is open source, self-hostable, and supports multiple AI providers including OpenAI, Claude, Gemini, DeepSeek, and Groq through the AI SDK adapters listed in package.json.
What database does ResumeLM need?
PostgreSQL, with Supabase providing auth and the backend services. The README lists a PostgreSQL database and a Supabase account as prerequisites, and the Docker path brings up Supabase, PostgreSQL, and Redis together.
Does ResumeLM require an OpenAI key?
The .env.example marks OPENROUTER_API_KEY as required for ResumeLM's app-funded defaults and lists ANTHROPIC_API_KEY as an optional bring-your-own-key provider. OPENAI_API_KEY is described as retained for compatibility with custom or legacy deployments.
Community notes