Generate professionally formatted .docx resumes from JSON data.
Project description
ResumeCraft
A Python CLI tool and library that generates professionally formatted .docx resumes from JSON data. Define your resume content in a simple JSON file and get a polished Word document with proper formatting — right-aligned dates, bold keyword highlighting, clickable hyperlinks, and clean page breaks.
Features
- JSON-driven — All resume content lives in a single JSON file, easy to version control
- Auto bold keywords — Define a list of keywords and they get bolded automatically in all bullet points
- Right-aligned dates — Company locations and durations are properly right-aligned using tab stops
- Clickable hyperlinks — Email, LinkedIn, GitHub, and project links are real clickable hyperlinks
- Smart page breaks — Section headers never get orphaned at the bottom of a page
- Separate project sections — Professional projects and personal/open source projects in distinct sections
- Tech stack tags — Italic grey tech stack line under each project
- Pydantic validation — JSON is validated against strict data models before building
- Custom section ordering — Control which sections appear and in what order
- Watch mode — Auto-rebuild on file save
- PDF output — Optional PDF conversion via
docx2pdf - Auto-open — Open the generated file after building with
--open
Installation
From PyPI
pip install resumecraft
With optional extras:
pip install resumecraft[pdf] # PDF output support
pip install resumecraft[watch] # Watch mode support
pip install resumecraft[pdf,watch] # Both
As a CLI tool (recommended)
pipx install resumecraft
# or
uv tool install resumecraft
Quick Start
# 1. Generate a template
resumecraft init -o my-resume.json
# 2. Edit my-resume.json with your details
# 3. Build your resume
resumecraft build my-resume.json
# 4. Build and open immediately
resumecraft build my-resume.json --open
# 5. Validate without building
resumecraft validate my-resume.json
# 6. Watch for changes and rebuild automatically
resumecraft watch my-resume.json -o resume.docx
CLI Reference
resumecraft --help Show all commands
resumecraft --version Show version
resumecraft init -o FILE Generate a blank JSON template
resumecraft build FILE [-o FILE] [--open] Build .docx (or .pdf) from JSON
resumecraft validate FILE Validate JSON without building
resumecraft watch FILE [-o FILE] Watch and rebuild on file changes
When -o is omitted from build, the output file is automatically named with a timestamp, e.g., resume_2026-04-01_03-45pm.docx.
Use as a Library
from resumecraft import Resume, DocxBuilder
# From JSON file
resume = Resume.from_json("my-resume.json")
DocxBuilder(resume).save("resume.docx")
# Or build the model directly
from resumecraft.models import Resume, Contact, Link, Experience
resume = Resume(
name="John Doe",
contact=Contact(
location="New York, NY",
email="john@example.com",
phone="+1-234-567-8900",
links=[Link(label="GitHub", url="https://github.com/johndoe")],
),
summary="Software engineer with 5 years of experience...",
bold_keywords=["Python", "React", "FastAPI"],
experience=[
Experience(
company="Acme Corp",
location="New York, NY",
title="Senior Developer",
duration="JAN 2022 - PRESENT",
bullets=["Built APIs using FastAPI and PostgreSQL."],
)
],
)
DocxBuilder(resume).save("resume.docx")
JSON Structure
Run resumecraft init to generate a full template. Here's the structure:
{
"name": "Your Name",
"contact": {
"location": "City, Country",
"email": "your@email.com",
"phone": "+1-234-567-8900",
"links": [
{ "label": "LinkedIn", "url": "https://linkedin.com/in/you" },
{ "label": "GitHub", "url": "https://github.com/you" }
]
},
"summary": "A brief professional summary...",
"bold_keywords": ["FastAPI", "React", "PostgreSQL"],
"experience": [
{
"company": "Company Name",
"location": "City, Country",
"title": "Your Title",
"duration": "JAN 2023 - PRESENT",
"bullets": ["What you did and the impact it had."]
}
],
"professional_projects": [
{
"name": "Project Name",
"subtitle": "| Location | Type",
"tech_stack": "FastAPI, React, PostgreSQL",
"link": null,
"bullets": ["What you built."]
}
],
"personal_projects": [
{
"name": "Side Project",
"subtitle": "| Personal Project",
"tech_stack": null,
"link": { "label": "GitHub", "url": "https://github.com/you/project" },
"bullets": ["What you built and why."]
}
],
"skills": [
{ "category": "Backend", "items": "Python (FastAPI, Django), Node.js" },
{ "category": "Frontend", "items": "React, TypeScript" }
],
"education": [
{
"institution": "University Name",
"degree": "Bachelor of Computer Science",
"duration": "2019 - 2023"
}
],
"languages": "English - Native | Hindi - Professional",
"section_order": [
"summary",
"experience",
"professional_projects",
"personal_projects",
"skills",
"education",
"languages"
]
}
Field Reference
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Full name displayed at the top |
contact |
object | Yes | Location, email, phone, and links |
summary |
string | Yes | Professional summary paragraph |
bold_keywords |
string[] | No | Words to auto-bold in all bullet points |
experience |
object[] | No | Work experience entries |
professional_projects |
object[] | No | Client/employer projects |
personal_projects |
object[] | No | Side projects and open source work |
skills |
object[] | No | Categorized skill lists |
education |
object[] | No | Degrees and institutions |
languages |
string | No | Language proficiencies |
section_order |
string[] | No | Custom order of sections (omit for default). Only listed sections are rendered. |
Available sections for section_order
summary, experience, professional_projects, personal_projects, skills, education, languages
Project Structure
resumecraft/
├── pyproject.toml
├── README.md
├── LICENSE
├── src/resumecraft/
│ ├── __init__.py # Public API (Resume, DocxBuilder, __version__)
│ ├── cli.py # Typer CLI commands (build, validate, init, watch)
│ ├── models.py # Pydantic data models
│ ├── builder.py # DocxBuilder — converts models to .docx
│ ├── styles.py # Styling constants (fonts, sizes, colors, margins)
│ └── utils.py # Helpers (hyperlinks, keep_with_next, bold patterns)
└── tests/
├── fixtures/
│ └── sample.json # Sample resume for tests
├── test_models.py
├── test_builder.py
├── test_cli.py
└── test_utils.py
Development
git clone https://github.com/mdfarhankc/resumecraft.git
cd resumecraft
uv sync --extra dev
Run tests
uv run pytest
Build
uv build
This creates dist/resumecraft-x.x.x.tar.gz and dist/resumecraft-x.x.x-py3-none-any.whl.
Publish to PyPI
Create a GitHub release (e.g., v0.2.0) and the CI workflow will publish to PyPI automatically via trusted publishing.
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file resumecraft-0.2.0.tar.gz.
File metadata
- Download URL: resumecraft-0.2.0.tar.gz
- Upload date:
- Size: 61.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
63e7bfaf76aac15002b24a45fcfa2b3ccc2100b171f2195accca2ccd6e90f8ad
|
|
| MD5 |
85fe87ec8e07b64da8c92554dcc98946
|
|
| BLAKE2b-256 |
e345a178fc9c1b41e7dde5183523cda8c77b8bbfc2cb98a0db920858f350fc6d
|
Provenance
The following attestation bundles were made for resumecraft-0.2.0.tar.gz:
Publisher:
publish.yml on mdfarhankc/resumecraft
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
resumecraft-0.2.0.tar.gz -
Subject digest:
63e7bfaf76aac15002b24a45fcfa2b3ccc2100b171f2195accca2ccd6e90f8ad - Sigstore transparency entry: 1205786908
- Sigstore integration time:
-
Permalink:
mdfarhankc/resumecraft@6040db9742ab4d42526ff28b37dc877fe3293380 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/mdfarhankc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6040db9742ab4d42526ff28b37dc877fe3293380 -
Trigger Event:
release
-
Statement type:
File details
Details for the file resumecraft-0.2.0-py3-none-any.whl.
File metadata
- Download URL: resumecraft-0.2.0-py3-none-any.whl
- Upload date:
- Size: 12.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
243b690a704257079106d7660299550a5655ac0a4b94932ebb29cab74c423965
|
|
| MD5 |
4aa4890e9c403479ea965b2f1a0a956a
|
|
| BLAKE2b-256 |
4f78cb274f532c5e82a57474bfd65d2f09872bfd9c4939838b23451a30c92cd6
|
Provenance
The following attestation bundles were made for resumecraft-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on mdfarhankc/resumecraft
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
resumecraft-0.2.0-py3-none-any.whl -
Subject digest:
243b690a704257079106d7660299550a5655ac0a4b94932ebb29cab74c423965 - Sigstore transparency entry: 1205786915
- Sigstore integration time:
-
Permalink:
mdfarhankc/resumecraft@6040db9742ab4d42526ff28b37dc877fe3293380 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/mdfarhankc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6040db9742ab4d42526ff28b37dc877fe3293380 -
Trigger Event:
release
-
Statement type: