A single professional knowledge base in Markdown that generates resumes as projections. A local, open-source (MIT) command-line tool.
You treat your resume as a single knowledge base: you write your experiences, projects and education once, in Markdown. Each resume is a projection of that base for a given job - you select what goes in, and the tool generates a consolidated Markdown file and a PDF (ATS template, readable by screening systems).
The pain it tackles: keeping several resume documents (Word, Google Docs, LinkedIn) and adapting them to each job leads to duplicated content, versions that drift apart, high maintenance cost and no decent versioning. Here there is one single source of truth, versionable in git; nothing is duplicated to serve a specific job.
The content lives in Markdown files organized by section, with conditional snippets marked by tags. A resume config (YAML) chooses the language, filters by tags and adjusts what goes in. Validation is all-or-nothing - the worst possible failure would be a silently incomplete resume, so the whole base is checked before anything is generated.
The repository ships with a complete example base in data/ - a fictional frontend engineer's resume, bilingual (pt/en), with experiences, projects, education, skills, logos and ready-made resume configs. With Docker installed, from a clone you generate a resume in one command:
docker compose run --rm forge generate resume-configs/fullstack.yamlImportant
⏳ The first run is slow. The image is built on the spot (Node + Pandoc + LaTeX), and downloading TeX Live alone usually takes 5 to 10 minutes on a clean machine - it is normal for the first run to look stuck at that step. This happens only once: with the image cached, later runs are almost instant.
Each config lists its languages in output.locales, so this writes one document set per language (fullstack-en and fullstack-pt) into data/output/.
There are configs for different targets - try them out and compare:
docker compose run --rm forge generate resume-configs/frontend.yaml # frontend focus
docker compose run --rm forge generate resume-configs/short.yaml # short version
docker compose run --rm forge validate # checks the whole base
docker compose run --rm forge list # lists blocks and tagsTip
Compare fullstack with frontend: the conditional tags turn the backend content of the same resume on and off.
Write your base in a directory of your own (keep it outside the repository if it is personal), with the same structure as data/:
<your-base>/
├── content/
│ ├── sections/
│ │ └── experiences/
│ │ └── acme.md # one content unit
│ ├── titles.yaml # section titles
│ └── personal_info.yaml # personal information (optional)
└── resume-configs/
└── my-job.yaml # one config per job
Point forge at it with the RESUME_DATA variable (without it, the example in data/ is used):
RESUME_DATA="$HOME/Desktop/my-resume-data" docker compose run --rm forge generate resume-configs/my-job.yamlA content file (content/sections/experiences/acme.md) - each file opens with a front matter (id + tags) and uses a minimal markup:
---
id: acme
tags: [backend, java]
---
::locale{en-US}
## Acme Corp
REST API development::span{tags=[cloud]}{ on AWS}.
::div{id=leadership tags=[leadership]}
- Led a team of 6 people.
::end::locale{en-US}declares the region's language (translations share the sameid).::span{tags=[cloud]}{…}conditions a snippet in the middle of a line (it enters only if the job asks forcloud).::div{…}…::endconditions a block of lines bytags.- Text outside any block enters whenever the section and the language match.
And content/titles.yaml gives each section's title:
experiences:
en-US: ExperienceA resume config (resume-configs/backend.yaml):
title: Backend Developer
tags: [backend, java] # a block enters with ≥1 tag in common
sections: # section order
- experiences
output:
locales: [en-US, pt-BR] # one document set per language
formats: [pdf, md]Generates one resume per language (backend-en, backend-pt) with the blocks that match backend or java.
- Usage guide - everything about writing the base, the full grammar, experience/education entries, personal information, all the resume config fields, the selection semantics, commands and outputs.
- Technical characteristics - stack, determinism, the Markdown → PDF contract, exit codes and the Docker environment.
- Automation - the prebuilt runtime image and the CI flow that generate resumes and publish them as dated releases.
docs/product.md- the product specification (the source of truth for behavior).
MIT.