As a freelance software engineer, it's important for me to regularly update my resume. There are various ways to create a decent resume, such as using Word or InDesign. But as a software engineer, I want to build it with development tools. This way, your resume becomes a showcase of your skills. In this blog post, I explain how I built my most recent resume using frontend software techniques.
Over the past years, I've created my curricula vitae with different tools. At the start of my career, I simply did this with Microsoft Word. Later, I used various open-source tools, including Scribus.
Steps
During my work as a freelance software developer, I regularly use frontend techniques like React with Typescript. That's why I wanted to build a resume with these techniques now. Here's an example of the result:

Techniques
Ultimately, I used a combination of the following techniques:
- React, Typescript & create-react-app: Frontend Javascript library as the foundation for the project.
- React-pdf: Node.js package for generating PDF documents in the browser (can also be server-side).
- React-pdf-tailwind (& Tailwind CSS): For styling react-pdf elements with Tailwind CSS.
- Google Fonts: Custom font. Note that not all fonts can be used with react-pdf. More on that later.
In the following steps, I'll explain how I built it.
1. Setting Up the Project
To start off, I used create-react-app to set up the initial project with Typescript (via NPX). Then I added
Tailwind CSS support:
Bash (/terminal)
1npx create-react-app demo-cv --template typescript
2cd demo-cv
3npm install -D tailwindcss
4npx tailwindcss initAfter adding it, I adjusted tailwind.config.js as needed, as indicated in the docs. I also added the Tailwind elements
to index.css:
CSS
1@tailwind base;
2@tailwind components;
3@tailwind utilities;Next, I removed all unnecessary items, like Jest, Web Vitals, and assets from the public folder, since they're
irrelevant for this project.
The only thing left to install is react-pdf & react-pdf-tailwind:
Bash (/terminal)
1npm install @react-pdf/renderer react-pdf-tailwind --saveNow that the foundation is ready, we can start shaping it.
2. Designing
2.1 HTML Template (index.html)
To ensure I can view the fullscreen PDF preview in the browser, I adjusted the HTML template so that #root takes up the
full height (public/index.html):
HTML
1<!DOCTYPE html>
2<html lang="nl">
3<head>
4 <meta charset="utf-8"/>
5 <meta name="viewport" content="width=device-width, initial-scale=1"/>
6 <style>
7 #root {
8 height: 100vh;
9 }
10 </style>
11 <title>demo-cv</title>
12</head>
13<body>
14<div id="root"></div>
15</body>
16</html>You can also see that I removed all unnecessary elements. A favicon, meta description, etc., aren't needed since I only want to generate a PDF.
2.2 Base Document & Metadata
And the last thing to adjust before getting to the content is index.tsx. Here, I wrapped the entire app
with PDFViewer and Document. PDFViewer ensures we can view the resulting PDF in the browser, and Document is the
absolute basis of the document. You can also add metadata to it:
JSX
1root.render(
2 <PDFViewer width="100%" height="100%">
3 <Document
4 title={"Curriculum Vitae van Nyef - Software Engineer - 2024"}
5 author={"Nyef"}
6 subject={"Overzicht werkervaring, skills & opleidingen."}
7 language={"nl-NL"}
8 >
9 <Cv/>
10 </Document>
11 </PDFViewer>
12);See the react-pdf documentation for all options. In the Cv component,
you'll find the content and structure (public/src/components/). Additionally, I configured the font and
react-pdf-tailwind in index.tsx.
2.3 Font
Since I wanted my resume to match the style of my website, I chose to use the same font: Fira Sans (Google Fonts).
To use a custom font, I had to register it in the code for react-pdf (
in index.tsx). I only added the font weights I needed:
JavaScript
1Font.register({
2 family: "Sans",
3 fonts: [
4 {
5 src: "/fonts/FiraSans-Regular.ttf",
6 fontWeight: 400,
7 },
8 {
9 src: "/fonts/FiraSans-Medium.ttf",
10 fontWeight: 500,
11 },
12 {
13 src: "/fonts/FiraSans-Bold.ttf",
14 fontWeight: 700,
15 },
16 ],
17});Note: You can only add TTF fonts.
2.4 Applying Tailwind CSS in the PDF Document
Now, only Tailwind CSS needs to be configured with react-pdf-tailwind. This is done as follows (
in index.tsx):
Typescript
1import {Style} from "@react-pdf/types";
2
3export type TwToStyle = (input: string) => Style;
4
5export const tw: TwToStyle = createTw({
6 theme: {
7 fontFamily: {
8 sans: ["Sans"],
9 },
10 extend: {},
11 },
12});The tw object is used to apply Tailwind CSS classes to react-pdf components, for example:
JSX
1<Text style={tw("text-[12px] font-bold text-slate-800")}>
2 {text}
3</Text>Now that all configuration is done, we can finally work on the resume's content.
2.5 Structure & Content
In this blog post, I won't go into what belongs in a resume or its design—there are better resources for that. In my case, I opted for a combination of a functional & chronological resume.
As mentioned earlier, I placed the general structure in the Cv component, which looks like this:
JSX
1const Cv = () => {
2 return (
3 <Page
4 size="A4"
5 style={tw("w-full h-screen bg-slate-100 flex flex-col justify-between font-sans text-[12px]")}
6 >
7 <View style={tw("flex flex-col items-start")}>
8 <Header/>
9
10 <View style={tw("w-full h-auto p-6 flex flex-row gap-6")}>
11 <PersonalDetails/>
12
13 <View style={tw("w-full flex flex-col gap-4")}>
14 <SkillsOverview/>
15 <ExperienceSection/>
16 </View>
17 </View>
18 </View>
19
20 <Footer/>
21 </Page>
22 );
23}My goal was to build the following structure:

From this, you can generally see which sections my resume consists of.
I divided everything into the most logical and smallest possible components for better code quality and reusable code. For example, in skills, I created an overview of badges with skills, divided into several categories:
JSX
1const SkillsOverview = () => {
2 return (
3 <>
4 <ProgrammingLangSkills/>
5 <FrameworksLibsSkills/>
6 <WebServerSkills/>
7 <ModelingPrinciplesSkills/>
8 <ProjectManagementSkills/>
9 </>
10 );
11};And each skill section can simply be created with consistent styling, for example:
JSX
1const ProgrammingLangSkills = () => {
2 return (
3 <BadgeSection
4 title={"Programmeer-, stijl- & markup-talen"}
5 items={[
6 "Java",
7 "Javascript (ES6)",
8 "SQL (PostgreSQL, MySQL, MS SQL)",
9 "HTML",
10 "CSS",
11 "Less",
12 "Markdown",
13 "PHP",
14 ]}
15 />
16 );
17};Note that not all CSS styles can be used with react-pdf, so check the documentation to see what's possible.
After implementing all components, I ended up with this:

3. Exporting & Sharing
Now it's just a matter of downloading an export, so I can share my software engineering resume in PDF format with others.
This can simply be done via the browser options of the PDF viewer.

React-pdf also offers several options for saving your document. In my case, I wanted to keep it as simple as possible.
Advantages of Building a Resume as a Software Developer
That's it! Overall, it's pretty straightforward to build a resume using React, Typescript, and Tailwind CSS.
Building a resume yourself with software development techniques offers the following advantages:
- You can relatively easily create multilingual resumes, for example, by adding react-intl (i18n).
- You can expand the project further so your resume is dynamically generated based on a configuration. Useful if you want to tailor your resume for different job applications.
- If you're more experienced with CSS, you'll feel more comfortable with this.
- Your resume itself becomes a showcase of your frontend skills! It helps demonstrate your abilities to potential employers.
