Minimalistic and printable web-based resume.
Minimalist CV is a simple and minimalist web-based resume built with Astro and Tailwind CSS. It provides a user-friendly layout optimized for printing and supports multiple languages through internationalization. Inspired on Bartosz Jarocki CV and Minimal Porfolio from Midudev.
- Print-friendly design: The layout ensures a clean and professional print output.
- Multi-language support: Easily switch between languages (English and Spanish by default).
- PDF Generation: Create a PDF for each language with a simple command.
- Structured Data: Store and manage user information in JSON files.
- API-like JSON Routes: Serve static JSON data for external use (e.g., in a portfolio).
- Framework: Astro.
- Language: TypeScript.
- Styling: Tailwind CSS.
- PDF scripts: Pupeteer.
src/ # Astro Main Folder
├── components/ # Components
│ ├── icons/ # Icons
│ ├── layout/ # Layout
│ ├── sections/ # Sections
│ └── ...
├── data/ # Data schemas and utilities
├── i18n/ # Internacionalization files
├── layouts/ # Astro layouts
├── models/ # Models and interfaces
├── pages/ # Astro pages routing
├── styles/ # Styles
└── content.config.ts # Astro content configuration file
data/ # User information content
├── en/ # Language folder
│ ├── education.json # JSON data
│ ├── projects.json
│ ├── skills.json
│ ├── user.json
│ └── work.json
└── es/
└── ...
public/ # Autogenerated pdf, og image and favicon.
└── ...
scripts/ # Generate pdf scripts
... # Config files (package.json, etc.)
User information is stored in the data/ directory, organized by language:
data/ # Data content
├── en/ # Language folder
│ ├── education.json # JSON data
│ ├── projects.json
│ ├── skills.json
│ ├── user.json
│ └── work.json
└── es/
└── ...
Each JSON file follows a specific schema (defined with astro:schema).
user.json: Personal details, contact information, social profiles.
| Property | Data Type | Validation |
|---|---|---|
| name | String | Required |
| label | String | Required |
| image | String | Required |
| String | Must be a valid email | |
| phone | String | Required |
| url | String | Must be a valid URL |
| blog | String | Must be a valid URL |
| summary | String | Required |
| location | Object | Contains address (String) and map (valid URL) |
| profiles | Array | Contains objects with url (valid URL), network (String), and username (String) |
work.json: Work experience.
| Property | Data Type | Validation |
|---|---|---|
| name | String | Required |
| position | String | Required |
| summary | String | Required |
| location | String | Required |
| url | String | Optional, must be a valid URL |
| startDate | String | Required |
| endDate | String | Required |
| remote | Boolean | Required |
| highlights | Array | Contains Strings |
education.json: Education details.
| Property | Data Type | Validation |
|---|---|---|
| institution | String | Required |
| url | String | Optional, must be a valid URL |
| area | String | Required |
| course | String | Required |
| studyType | String | Required |
| startDate | String | Required |
| endDate | String | Required |
skills.json: List of skills.
| Property | Data Type | Validation |
|---|---|---|
| skills | Array | Contains Strings |
projects.json: Projects with descriptions and links.
| Property | Data Type | Validation |
|---|---|---|
| name | String | Required |
| description | String | Required |
| url | String | Optional, must be a valid URL |
| urls | Array | Contains valid URLs |
| tags | Array | Contains Strings |
| highlights | Array | Contains Strings |
By default, if a translation is missing for a specific language, the English translation will be used.
- Add a new language in
src/i18n/ui.tsunder thelanguagesconstant. You can also translate theuiconstant by copying an existing language's translation (e.g.,fr). Astro will automatically configure itself using thelanguagesconstant. - Copy and paste the
data/en/folder and rename it todata/fr/. - Translate the content inside
data/fr/. - That's it! The language button will redirect to the next available language according to the order defined in the
languagesconstant.
Warning
To generate pdf with generate-pdf command you need Node v22.6.0 or higher.
Add the new language to the languages constant on scripts/web-to-pfd.ts. Run the following command to generate a PDF for each available language:
npm run generate-pdfMinimalist CV exposes static JSON endpoints, allowing external applications (e.g., a portfolio) to retrieve user data. Example routes:
https://cv.uspiri.com/api/user.jsonhttps://cv.uspiri.com/api/work.json
- Clone the repository:
git clone https://github.com/USpiri/cv.git- Navigate to the project directory:
cd cv- Install dependencies:
npm install- Start the Tauri development server:
npm run devContributions are welcome! If you'd like to contribute:
- Fork the repository.
- Create a new branch for your feature or bug fix.
- Commit your changes with a descriptive message.
- Submit a pull request for review.


