JK
>LOADING // LOADING
INITIALIZING VIEW
A frontend-first, privacy-focused resume builder for IT professionals that generates ATS-friendly, single-page A4 LaTeX resumes. The frontend handles all data editing, live preview, and template rendering entirely in the browser with localStorage persistence. A lightweight Go backend exists solely to compile LaTeX to PDF via Tectonic.
Building publication-quality resumes typically requires LaTeX knowledge. This project solves that by letting users fill structured forms, choose from 9 ATS-optimized templates, see a live HTML/CSS preview, and export to either .tex source or compiled PDF — all without writing a single line of LaTeX.
| Technology | Version | Purpose | Why Chosen |
|---|---|---|---|
| React | 19 | UI framework | Latest concurrent features, lazy loading |
| TypeScript | ~6.0 | Type safety | Prevents runtime errors on complex resume data model |
| Vite | 8.x | Build tool & dev server | Fast HMR, native ESM, code splitting via glob imports |
| Tailwind CSS | v4 | Utility-first styling | Rapid UI development, consistent design tokens |
| Zustand | 5.x | State management | Minimal boilerplate, built-in persist middleware |
| @dnd-kit | core 6, sortable 10 | Drag-and-drop | Accessible, performant sortable lists |
| Go | 1.25+ | Backend runtime | Fast startup, small binaries, excellent concurrency |
| Gin | 1.12 | HTTP framework | High performance, middleware ecosystem |
| Tectonic | 0.16.9 | LaTeX→PDF compiler | Self-contained, no TeX distribution needed |
| Docker | — | Containerization | Reproducible builds, production parity |
| SQLite | modernc.org/sqlite 1.54 | Stats persistence | No CGO dependency, cross-compilation |
| Sentry | 10.x | Error tracking & monitoring | Session replay, performance monitoring, feedback widget |
| Method | Route | Purpose |
|---|---|---|
| POST | /api/compile | Compile LaTeX to PDF (HTTP) |
| GET | /api/compile/ws | WebSocket compile with progress streaming |
| POST | /api/stats/visit | Record page visit |
| POST | /api/stats/download | Record PDF download |
| GET | /api/stats | Get aggregate stats |
| GET | /api/health | Health check (Tectonic + DB status) |
| GET | /metrics | Prometheus metrics |
| Column | Type | Notes |
|---|---|---|
| keyPK | TEXT | Counter name: 'visits' or 'downloads' |
| value | INTEGER | Counter value, default 0 |
Single table with 2 key-value rows. WAL mode enabled. Used only for aggregate visit/download statistics — no user data stored.
No relationships. Single table with 2 counter rows.
Decision: All resume data, editing, preview, and LaTeX generation happen in the browser
Why: Privacy-first: all data stays in browser with localStorage persistence
Benefits: Zero server costs for editing, user privacy, offline-capable editing
Trade-offs: No cloud sync, no cross-device access, localStorage size limits
Decision: Use Tectonic instead of pdflatex or other TeX distributions
Why: Self-contained binary, no TeX distribution needed on the server
Benefits: Simple Docker image, reproducible builds
Trade-offs: Slower than pdflatex for complex documents
Decision: Use Zustand for state management with built-in persist middleware
Why: Minimal boilerplate, built-in localStorage persistence
Benefits: Simple state management, easy persistence
Trade-offs: Less ecosystem than Redux
Decision: Use WebSocket instead of HTTP polling for PDF compilation
Why: Real-time progress feedback improves UX during 5-60s compilation
Benefits: User sees compilation stages (validating → writing → compiling → done)
Trade-offs: More complex than HTTP polling
Decision: Each template implements a Template interface with config, Preview, and generateLatex
Why: Multiple visual styles with shared data model
Benefits: Extensible, each template self-contained, lazy-loadable via import.meta.glob
Trade-offs: Code duplication across templates
Decision: Use SQLite for aggregate visit/download counters only
Why: Zero-config embedded DB adequate for 2 counter rows
Benefits: No external database dependency, simple deployment
Trade-offs: Write contention under concurrent access