* feat(resume): add a deterministic ATS parseability check Adds an offline ATS linter that reports whether a parser can read a resume, surfaced as an always-on panel in the builder. The existing Resume Analysis panel needs a configured AI provider, so users who never set one up get no feedback at all. These 22 rules run as a pure function over ResumeData with no provider, no network and no rendered PDF, so they work for everyone on every edit. Rules cover contact details, date parseability, sections that hold content but never render, column and sidebar placement, and typography thresholds. The catalog mirrors the Semantic CSS diagnostic catalog: stable codes carrying a severity, meaning and action, with no i18n dependency so the web layer translates by code. Each finding carries a JSON Pointer, which is what makes jump-to-field work. Deliberately no second score. Resume Analysis owns overallScore, so this reports "N of M checks passed" and counts by severity instead. * fix(resume): accept localized ongoing periods and reject bare ones Two period-parsing bugs found in review. The ongoing-token set was English-only, so a German resume reading "2020 - heute" was reported as unparseable and the panel told the user to rewrite a perfectly valid range. Rather than guess translations for 55 locales, a range ending that carries no digits and is not a month name in the resume's locale is now read as ongoing. That keeps a genuinely incomplete ending such as "Jan 2020 - Feb" reported, since "Feb" resolves as a month. A bare "Present" also parsed as a valid period, so an experience entry with no start date passed the check. A standalone ongoing token is now rejected; ongoing tokens remain valid as the end of a range. * feat(web): scroll ATS findings to the item they belong to Findings for different items in one section all landed on the section header, so a date problem on the third role gave no more help than naming the section. getAtsFindingTarget now resolves the offending item from the finding's JSON Pointer against the resume, and SectionItem carries a matching DOM id. The panel scrolls to that item and falls back to the section header when the item is not mounted, which is what happens while its section is collapsed. * fix(resume): recognize ongoing periods by token, not by shape The previous heuristic read any short, digit-free range ending as an ongoing marker, so "2020 - unknown", "2020 - later" and "2020 - tbd" parsed cleanly and suppressed the finding they should have raised. Replaced with an explicit table of ongoing words keyed by language, covering the locales the app ships. Matching is exact, so unrecognized endings are reported again. A locale missing from the table falls back to the earlier behaviour of reporting its ongoing periods, which is a visible gap someone can close by adding a word rather than a silent hole in detection. Tests assert every listed token parses and that the table stays lowercase, since lookups normalize that way. * fix(ats): parse punctuated ongoing tokens * fix(ats): parse Unicode punctuated ongoing tokens --------- Co-authored-by: Amruth Pillai <im.amruth@gmail.com>
Reactive Resume
Reactive Resume is a free and open-source resume builder that simplifies the process of creating, updating, and sharing your resume.
Reactive Resume makes building resumes straightforward. Pick a template, fill in your details, and export to PDF—no account required for basic use. For those who want more control, the entire application can be self-hosted on your own infrastructure.
Built with privacy as a core principle, Reactive Resume gives you complete ownership of your data. The codebase is fully open-source under the MIT license, with no tracking, no ads, and no hidden costs.
Sponsors
Reactive Resume stays free, open-source, and independent because companies choose to support the work behind it. Thank you to every sponsor who helps fund hosting, maintenance, and continued development for the community.
Atlas Cloud supports Reactive Resume as a project sponsor. Atlas Cloud provides a unified AI platform for developers, with access to hundreds of models for chat, image generation, video generation, media processing, and GPU cloud workloads through one API key, one endpoint, and one billing account.
If your company would like to sponsor Reactive Resume, email hello@amruthpillai.com.
Features
Resume Building
- Real-time preview as you type
- Multiple export formats (PDF, JSON, DOCX)
- Drag-and-drop section ordering
- Custom sections for any content type
- Rich text editor with formatting support
Templates
- Professionally designed templates
- A4 and Letter size support
- Customizable colors, fonts, and spacing
- Structured Style Rules for section and text styling
Privacy & Control
- Self-host on your own infrastructure
- No tracking or analytics by default
- Full data export at any time
- Delete your data permanently with one click
Extras
- AI integration (OpenAI, Google Gemini, Anthropic Claude)
- Multi-language support
- Share resumes via unique links
- Import from JSON Resume format
- Dark mode support
- Passkey and two-factor authentication
Templates
Azurill |
Bronzor |
Chikorita |
Ditto |
Gengar |
Glalie |
Kakuna |
Lapras |
Leafish |
Onyx |
Pikachu |
Rhyhorn |
Ditgar |
Meowth |
Scizor |
Quick Start
The quickest way to run Reactive Resume locally:
# Clone the repository
git clone --depth=1 https://github.com/amruthpillai/reactive-resume.git
cd reactive-resume
# Start all services
docker compose up -d
# Access the app
open http://localhost:3000
For detailed setup instructions, environment configuration, and self-hosting guides, see the documentation.
Tech Stack
| Category | Technology |
|---|---|
| Framework | TanStack Start (React 19, Vite) |
| Runtime | Node.js |
| Language | TypeScript |
| Database | PostgreSQL with Drizzle ORM |
| API | ORPC (Type-safe RPC) |
| Auth | Better Auth |
| Styling | Tailwind CSS |
| UI Components | Base UI + shadcn-style package |
| State Management | Zustand + TanStack Query |
Documentation
Comprehensive guides are available at docs.rxresu.me:
| Guide | Description |
|---|---|
| Getting Started | First-time setup and basic usage |
| Self-Hosting | Deploy on your own server |
| Development Setup | Local development environment |
| Project Architecture | Codebase structure and patterns |
| Exporting Your Resume | PDF and JSON export options |
Self-Hosting
Reactive Resume can be self-hosted using Docker. The stack includes:
- PostgreSQL — Database for storing user data and resumes
- SeaweedFS (optional) — S3-compatible storage for file uploads
From v5.1.0 onwards — PDF generation now runs entirely client-side via
@react-pdf/renderer. New deployments no longer require Browserless, Chromium, or any external print service as a dependency. ThePRINTER_*andBROWSERLESS_*environment variables are no longer read and can be removed from your.env.
Pull the latest image from Docker Hub or GitHub Container Registry:
# Docker Hub
docker pull amruthpillai/reactive-resume:latest
# GitHub Container Registry
docker pull ghcr.io/amruthpillai/reactive-resume:latest
See the self-hosting guide for complete instructions.
Support
Reactive Resume is and always will be free and open-source. If it has helped you land a job or saved you time, please consider supporting continued development:
Other ways to support:
- Star this repository
- Report bugs and suggest features
- Improve documentation
- Help with translations
Star History
Contributing
Contributions make open-source thrive. Whether fixing a typo or adding a feature, all contributions are welcome.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
See the development setup guide for detailed instructions on how to set up the project locally.
License
MIT — do whatever you want with it.














