CLI tool that generates many PDF resumes from a single set of TOML data files via Typst.
If you have experience in different areas, you may need different resumes - each highlighting what's relevant. This tool automates that.
Inspired by Jake's Resume
Download from typst.app or use your package manager.
Go to the Releases page, download the binary for your platform, and place it somewhere in your PATH.
resumegenOn first launch you will be prompted to copy the default configuration to ~/.config/resumegen/.
~/.config/resumegen/data/
├── header.toml ← name, contacts, summary
├── jobs.toml ← work experience
├── projects.toml ← side projects
├── education.toml ← degrees
└── skills.toml ← skill categories
A profile defines which tags to include and in what priority order:
# ~/.config/resumegen/profiles/go-backend.toml
tags = ["go", "backend", "devops"]
lang = "en"
output = "go-backend.pdf"resumegen --profile go-backend
# → ~/.config/resumegen/output/go-backend.pdfresumegen [--profile <name>] [--path <appdir>]| Flag | Default | Description |
|---|---|---|
--profile |
default |
Profile name to use (matches profiles/<name>.toml) |
--path |
~/.config/resumegen |
Path to the application directory |
Output PDF is written to <appdir>/output/<profile.output>.
~/.config/resumegen/
├── config.toml # Paths and render settings
├── profiles/ # One .toml per target role
│ ├── default.toml
│ └── cpp-embedded.toml
├── data/ # Resume content
│ ├── header.toml
│ ├── jobs.toml
│ ├── projects.toml
│ ├── education.toml
│ └── skills.toml
└── templates/ # Typst templates (auto-managed)
A profile selects and ranks content by tags. Tags are ordered highest to lowest priority - they drive both filtering and trim order when the resume exceeds the page limit.
# profiles/go-backend.toml
tags = ["go", "backend", "devops"]
lang = "en" # any language key present in your data; always falls back to "en"
output = "go-backend.pdf"Jobs and projects with no matching tags are excluded entirely. Bullets with no matching tags are dropped. If a job ends up with no visible bullets, it is dropped too.
Content fields support Typst inline markup: *bold*, _italic_, #link("url")[text].
Job-level tags control whether the entire position is shown. Bullet-level tags control individual bullet visibility. If a job has no top-level tags, its visibility is determined by its bullets alone.
[[jobs]]
tags = ["go", "backend", "devops"] # job hidden entirely if none match
company = "Acme Corp"
[jobs.title]
en = "Software Engineer"
ru = "Инженер-программист"
[jobs.date]
en = "Jan. 2025 – Present"
[jobs.location]
en = "Moscow, Russia"
[[jobs.bullets]]
tags = ["go", "backend"]
[jobs.bullets.text]
en = "Built a *REST API* service in Go"
ru = "Разработал сервис *REST API* на Go"Note: Flat fields like
companymust appear before the first[jobs.*]subtable in each entry, otherwise TOML will assign them to the wrong table.
[[categories]]
[categories.name]
en = "Languages"
ru = "Языки программирования"
[[categories.items]]
name = "Go"
tags = ["go", "backend"]
[[categories.items]]
name = "C/C++"
tags = ["cpp", "embedded"]Education entries are always shown in full - no tag filtering.
[[edu]]
[edu.title]
en = "Moscow State University"
[edu.degree]
en = "B.S. Computer Science"
[edu.location]
en = "Moscow, Russia"
[edu.date]
en = "2020 – 2024"When a resume exceeds page_limit, the tool automatically trims the lowest-scored bullets until the resume fits. Scoring is based on tag priority: bullets matching higher-priority profile tags score higher and are kept longer.
You can tune the behavior in config.toml:
[render]
page_limit = 1.0 # trim until the resume fits this many pages
page_height_pt = 841.89 # must match the paper size in template.typ (A4 = 841.89, US Letter = 792)
[render.min_elements]
job_bullets = 1 # a job with fewer included bullets than this is dropped entirely
project_bullets = 1 # same for projects
skill_items = 1 # a skill category with fewer included items than this is dropped entirelymake buildBinary is placed at ./bin/resumegen.
make lint # run golangci-lint
make test # run tests
make tidy # go mod tidy
make rebuild # force rebuild all container images
make clean # remove build artifacts- Automated tests
- Chronological or manual ordering of bullets and entries
- Verbose mode for debugging filter and trim decisions
- Self-contained Docker/Podman builder - run
resumegenwith no local dependencies: Typst bundled inside the container, mount your data directory, get the PDF out
If this project helped u find a job - show your new employer a resume generated from the defaults :)
