Self-hosted service
amruthpillai/reactive-resume avatar
amruthpillai/reactive-resume

Reactive Resume: self-hosted resume builder with client-side PDF export

Reactive Resume is a self-hosted resume builder with editable layouts, PDF export, import tools, and privacy-focused local control.

43,555 stars4,800 forksTypeScriptMIT

At a glance

What is it?
Reactive Resume is an MIT-licensed resume builder that runs on your own infrastructure with Docker Compose. It is a good fit if you want to own the data and can run PostgreSQL; it is the wrong tool if you need a hosted service with no operational work.
Who is it for?
Adopt Reactive Resume if you want your resume data on your own PostgreSQL and are willing to run a Docker Compose stack. Skip it if you want a hosted service with no server to run, or if you need a print service to generate PDFs, since v5.1.0 moved PDF generation into the browser.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
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 29, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

Who Reactive Resume is for and what it replaces

Reactive Resume solves a narrow problem: keeping a resume in a format you control while still getting a live preview, multiple templates and a PDF export. The README frames it as a free and open-source resume builder that makes it easy to create, update, and share your resume. The repository is MIT licensed, which means you can read the code, fork it, and run it without a commercial agreement.

The project targets two audiences. The first is an individual who wants a resume builder without an account: the README states that basic use needs no account, and that you can pick a template, fill in your details, and export to PDF. The second is an operator who wants the whole application on their own infrastructure. That second audience is the one that matters for adoption decisions, because it implies running PostgreSQL and a web server. The README is explicit about the privacy claim: you own your data, and the codebase has no tracking, no ads, and no hidden costs.

If you only need a one-off PDF and do not care where it is stored, the hosted site at rxresu.me covers that. If you need a resume that lives in your own database and can be exported as JSON at any time, the self-hosted path is the point of the project.

How the stack fits together: TanStack Start, PostgreSQL and ORPC

The README lists the tech stack in a table. The framework is TanStack Start with React 19 and Vite, the runtime is Node.js, the language is TypeScript, and the database is PostgreSQL with Drizzle ORM. The API layer is ORPC, described as type-safe RPC. Authentication is Better Auth. Styling is Tailwind CSS, UI components come from Base UI plus a shadcn-style package, and state is handled by Zustand and TanStack Query.

That combination is a single TypeScript application rather than a set of microservices. The compose file confirms the runtime shape: a postgres service, a redis service, and an optional seaweedfs service. Redis is described in the compose file as potentially holding agent stream data including user chat content, and the ports block is commented out so it stays internal to the Docker network. That is a deliberate default, and it tells you the maintainers expect Redis to be reachable only from the app.

PDF generation is the part that changed most. The README states that from v5.1.0 onwards, PDF generation runs entirely client-side via @react-pdf/renderer, and that new deployments no longer need Browserless, Chromium, or any external print service. The PRINTER_* and BROWSERLESS_* environment variables are no longer read and can be removed from your .env. That removes a whole class of deployment problems, but it also moves the rendering work to the user's browser, which is a trade-off discussed below.

Installing Reactive Resume with Docker Compose

The quickest path is the one in the README. Clone the repository shallowly, change into it, and start the services with Docker Compose. The README gives this exact sequence:

bash
git clone --depth=1 https://github.com/amruthpillai/reactive-resume.git
cd reactive-resume

docker compose up -d

open http://localhost:3000

After that, the app should be reachable at http://localhost:3000. If you prefer to run the published image rather than build from source, the README documents pulling from Docker Hub or GitHub Container Registry:

bash
docker pull amruthpillai/reactive-resume:latest
docker pull ghcr.io/amruthpillai/reactive-resume:latest

The environment file is where the real configuration lives. The .env.example sets PORT to 3000, SERVER_PORT to 3001, and APP_URL to http://localhost:3000. It also sets DATABASE_URL to postgresql://postgres:postgres@postgres:5432/postgres, which matches the postgres service name in the compose file. AUTH_SECRET is expected to be generated with openssl rand -hex 32, and the comment warns to change it in production. Social sign-in for Google, GitHub and LinkedIn is optional and stays disabled until both client ID and secret are set.

The compose file defines a postgres service on port 5432 with a healthcheck using pg_isready, a redis service with appendonly enabled, and a seaweedfs service on port 8333. SeaweedFS is marked optional in the README, so a deployment that does not need file uploads can leave it out. If you do run it, note that the compose file supplies AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY both set to seaweedfs, which is a development default rather than a production credential.

What breaks: client-side PDF, optional storage and thin docs

The move to client-side PDF generation is the most consequential design choice in the current release line. It removes the need for Chromium or a print service, which simplifies deployment. It also means the browser does the rendering. On a low-powered machine or a phone, a long resume with custom fonts may take noticeably longer to export, and any rendering bug is now something the user experiences in their own tab rather than on the server. The README does not document a server-side fallback, so if you need deterministic server-generated PDFs, this release line is not the tool for that.

SeaweedFS being optional creates a second decision point. The README labels it as S3-compatible storage for file uploads, and the compose file wires it up with a bucket-creation job. If you skip it, anything that depends on uploads has no backing store. The README does not spell out which features degrade when it is absent, so verify that against your own usage before you decide.

The documentation is split between the README and docs.rxresu.me. The README points to guides for getting started, self-hosting with Docker, development setup, project architecture, and exporting your resume. What the README does not cover is rollback: there is no documented procedure for downgrading a deployment or reverting a migration. The repository does contain a migrations/ directory and db:migrate and db:generate scripts in package.json, so migrations exist, but the README does not describe how to reverse one. Treat upgrades as one-way unless you have tested otherwise.

Reactive Resume compared with Open Resume and JSON Resume tooling

The closest comparison people search for is Reactive Resume versus Open Resume. Both are resume builders, and both are aimed at people who want more control than a hosted form gives them. The difference is in the delivery model. Reactive Resume is a full application: TanStack Start, PostgreSQL, Drizzle ORM, Better Auth, and a Docker Compose stack with Redis and optional SeaweedFS. Open Resume is not described in this repository, so any claim about its internals would be guesswork. What can be said is that adopting Reactive Resume means adopting a database-backed web application, not a static generator.

The other relevant comparison is JSON Resume. Reactive Resume supports importing from the JSON Resume format, which means the two are not mutually exclusive. If your content already lives in JSON Resume, you can bring it in. If you want a pipeline where a JSON file is the source of truth and a static site is the output, Reactive Resume is heavier than you need, because it wants PostgreSQL and a running server to hold the same data.

The practical split: pick Reactive Resume when you want a UI, templates, and share links backed by your own database. Pick a JSON-file-plus-static-generator approach when you want the resume to be a file in a git repository with no server at all.

Licence, maintenance and the cost of upgrading

The repository is MIT licensed, and the Dockerfile carries the label org.opencontainers.image.licenses="MIT". MIT is permissive: you can use, modify and redistribute the code, including in commercial settings, provided the licence notice is preserved. That is a statement about the licence text, not legal advice; if you are embedding the project in a product, have your own counsel read the terms.

Maintenance looks current. The last push to the default branch was on 2026-08-27, and the most recent releases are v5.2.9 on 2026-08-27, v5.2.8 on 2026-08-24, and v5.2.7 on 2026-08-17. That is a steady release cadence over roughly ten days. The repository is not archived. The package.json declares version 5.3.0 and requires Node.js >=24, with pnpm pinned as the package manager, so a source build needs a modern Node runtime.

The upgrade cost is mostly in the environment file and the database. The v5.1.0 change is the clearest example: PRINTER_* and BROWSERLESS_* variables stopped being read, so any deployment still carrying them is carrying dead configuration. Migrations are managed through the db:migrate script, and the README does not document a rollback path, so an upgrade that runs a migration should be treated as forward-only unless you have a tested restore. Budget for a database backup before each version bump, not just for the application image.

Editorial conclusion

Adopt Reactive Resume if you want your resume data on your own PostgreSQL and are willing to run a Docker Compose stack. Skip it if you want a hosted service with no server to run, or if you need a print service to generate PDFs, since v5.1.0 moved PDF generation into the browser. Before committing, verify that the Docker image tag you pull matches the release you expect, and confirm whether you need SeaweedFS for file uploads or can run without it.

Frequently asked questions

Is Reactive Resume legit?

The repository is open source under the MIT license and the README states there is no tracking, no ads, and no hidden costs. The code is public on GitHub, so you can inspect what the application does before running it.

How do I use Reactive Resume?

The README says you pick a template, fill in your details, and export to PDF, and that basic use needs no account. For more control you can run the whole application on your own infrastructure with Docker Compose and open it at http://localhost:3000.

What is Reactive Resume?

It is a free and open-source resume builder for creating, updating and sharing a resume, according to the README. It supports PDF, JSON and DOCX export, 15 templates, and self-hosting on your own infrastructure.

Is Reactive Resume ATS friendly?

The README does not make any claim about applicant tracking system compatibility. It lists 15 templates, A4 and Letter page sizes, and PDF, JSON and DOCX export, but says nothing about how parsing systems read the output.

Is Reactive Resume free?

Yes. The README describes it as a free and open-source resume builder under the MIT license, with no tracking, no ads, and no hidden costs. The README also notes that basic use needs no account.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
For maintainers

Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/amruthpillai-reactive-resume.svg)](https://hysenlabs.com/projects/amruthpillai-reactive-resume)
Community notes

Community notes