A React + Vite implementation of my personal CV designed to separate content from presentation. All copy lives in YAML/Markdown (content/cv.yaml) while Tailwind-driven React components render a faithful web layout that can be printed to PDF. This avoids the layout limits of @react-pdf/renderer so you have the full power of HTML+CSS for styling. It keeps the content portable for future templates.
- Headless content: The CV data is structured in YAML (contact info, skills, experience, etc.) so prose updates never touch JSX.
- Web-first rendering: Running in a browser gives precise typography, native fonts, and browser print preview for PDF export. Plus more layout freedom than PDF-focused libraries.
- Template flexibility: Each visual block—header, profile, details, experience, etc.—is a dedicated React component. Swapping or extending templates is as simple as composing different components around the same content payload.
- Markdown everywhere: Narrative sections use Markdown plus
react-markdown/remark-gfm, ensuring bullets and emphasis render consistently.
| Layer | Details |
|---|---|
| Framework | React 19 + Vite (TypeScript) |
| Styling | Tailwind CSS with custom theme + print utilities |
| Content parsing | js-yaml + custom TypeScript types |
| Markdown rendering | react-markdown with remark-gfm |
| Icons | lucide-react |
headless-cv/
├── content/ # Structured CV data (YAML)
├── src/
│ ├── components/ # One component per section (Header, Details, Experience, ...)
│ ├── data/ # YAML loader and schema types
│ ├── index.css # Tailwind layers + custom print utilities
│ └── main.tsx # App bootstrap
└── dist/ # Vite build output (after `npm run build`)
- Edit
content/cv.yaml. Every field supports Markdown (e.g., bullet lists inexperience.description). - Run the dev server and the page updates automatically thanks to Vite HMR.
- Because data is independent from the template, you can reuse the YAML with other renderers (CLI generators, PDF pipelines, etc.) without touching the UI.
- Node.js ≥ 20
- npm (bundled with Node)
npm installnpm run devVisit http://localhost:5173 (strict port enforced) to view the CV. The layout is optimized for desktop widths (~850px) since it targets print/PDF.
npm run builddist/ now contains the static site. Serve dist/index.html or open it directly in a Chromium browser and use Print → Save as PDF for a high-fidelity CV export.
npm run lint- Colors/typography: Update the DaisyUI theme tokens near the top of
src/index.css(inside the@plugin "daisyui/theme"block). Adjust values like--color-primary,--color-secondary, and--color-base-100to rebrand the buttons, links, and page background. - Layout tweaks: Modify the relevant section component (e.g.,
ExperienceSection.tsx). Tailwind utilities keep styles co-located with markup. - Print-only adjustments: Add rules to
@layer baseinsrc/index.css(e.g., page margins, page-break helpers).
MIT. Feel free to adapt the code and content structure for your own CVs.