An opinionated, file-backed CV builder for iterating a baseline resume and generating role-specific CVs, with a strong print-to-PDF workflow.
Repo: shuurai/cv-builder
- Baseline Profile editor (personal info, experiences, education, languages, technical skills, passions & interests)
- CV Profile editor for tailoring experiences and content per role
- Theme system (light/dark palettes via CSS variables)
- Native PDF Export: Built-in programmatic PDF generation with exact layout matching, automated pagination, and offline font support via
@react-pdf/renderer(no browser print dialogs needed). - Export to Word (
.docx) - Optional AI assist for rewriting fields and analyzing job descriptions (OpenRouter)
- Tauri Desktop App: Native macOS
.appbundle with secure file saving, system notifications, and intelligent window unsaved-changes protection.
- Support customizing various CV layouts
- Better support for word doc exports
- Next.js (App Router) + React
- Tailwind CSS
- Zod validation
- Local JSON data store (no database by default)
- Node.js 20+ recommended
- npm (or your preferred package manager)
git clone https://github.com/shuurai/cv-builder.git
cd cv-builder
npm installAI features require an OpenRouter API key. If you don’t use AI features, you can skip this.
OPENROUTER_API_KEY(required for AI)OPENROUTER_BASE_URL(optional, defaults tohttps://openrouter.ai/api/v1)OPENROUTER_MODEL(optional, defaults toopenai/gpt-4.1-mini)OPENROUTER_MODEL_JD(optional, used for job-description analysis)
Create a .env.local file in the project root:
OPENROUTER_API_KEY=your_key_here
OPENROUTER_MODEL=openai/gpt-4.1-mininpm run devDefault dev URL: http://localhost:3000
To run on a different port:
npm run dev -- -p 3005npm run build
npm run startThis repo includes a Tauri wrapper so you can run CV Builder as a native macOS app (pin it to the Dock).
Prerequisites:
- Rust toolchain (rustc/cargo)
- Xcode Command Line Tools (or full Xcode)
- Node.js
Run in development:
npm run tauri:devBuild a .app bundle:
npm run tauri:buildNotes:
- The Tauri build bundles a Next.js standalone server and starts it locally inside the app.
- On startup, it launches a native loading screen showing initialization progress while resolving
PATHboundaries. - Desktop data lives in your user's home directory under
~/.cvbuilder. If you have existing data in.data/, simply copy it into~/.cvbuilderand the app will detect it.
Current checks:
npm run lint
npm run test
npm run buildnpm run build will fail on TypeScript and Next.js compilation errors.
This project is file-backed by default.
.data/is the local working data directory (your real CV data). It is gitignored.data/is committed sample data meant to be a safe, generic example/seed.
The app reads from .data/ first. If a file doesn’t exist yet in .data/, it
falls back to data/ as a seed/example.
.data/baseline.json— your baseline profile (shared defaults).data/profiles/*.json— per-role CV profiles.data/themes/*.json— theme definitions
Implementation details:
- Paths are defined in paths.ts
- Reads/writes are implemented in json-store.ts
Notes:
- This works great for local usage and single-user workflows.
- If you deploy to environments with read-only filesystems (or multiple users), you’ll need to replace the JSON store with a database or persistent storage.
The Baseline Profile editor supports uploading a profile photo.
- The uploaded photo is saved under
.data/assets/(for example.data/assets/profile.jpg). .data/is gitignored by default, so user photos (and CV data) are never meant to be committed or shared.- The photo is served via
GET /api/baseline/photowithCache-Control: no-store.
The application includes a fully programmatic native PDF generation engine built on top of @react-pdf/renderer.
- This bypasses all browser printing APIs, guaranteeing pixel-perfect alignment.
- When you click "Download PDF", it seamlessly exports a fully paginated document without any layout issues or missing margins.
- It dynamically assigns a filename based on the role and year (e.g.
CV2026-CTO.pdf). - It fully supports Light and Dark Mode PDFs based on your current active app theme.
- When running in the Tauri desktop environment, clicking download seamlessly summons your OS-native "Save File" dialog defaulting to your Downloads folder, followed by a chime and success notification.
Issues and PRs are welcome. See CONTRIBUTING.md.
See PRIVACY.md.
- Do not commit
.env.localor API keys.
MIT. See LICENSE.