--- name: rendercv description: >- Create professional CVs and resumes with perfect typography using RenderCV (v2.8). Users write content in YAML, and RenderCV produces publication-quality PDFs via Typst typesetting. Full control over every visual detail: colors, fonts, margins, spacing, section title styles, entry layouts, and more. 6 built-in themes with unlimited customization. Any language supported (22 built-in, or define your own). Outputs PDF, PNG, HTML, and Markdown. Use when the user wants to create, edit, customize, or render a CV or resume. --- ## Quick Start **Available themes:** `classic`, `harvard`, `engineeringresumes`, `engineeringclassic`, `sb2nov`, `moderncv` **Available locales:** `english`, `arabic`, `danish`, `dutch`, `french`, `german`, `hebrew`, `hindi`, `hungarian`, `indonesian`, `italian`, `japanese`, `korean`, `mandarin_chinese`, `norwegian_bokmål`, `norwegian_nynorsk`, `persian`, `portuguese`, `russian`, `spanish`, `turkish`, `vietnamese` These are starting points — every aspect of the design and locale can be fully customized in the YAML file. ```bash # Install RenderCV uv tool install "rendercv[full]" # Create a starter YAML file (you can specify theme and locale) rendercv new "John Doe" rendercv new "John Doe" --theme moderncv --locale german # Render to PDF (also generates Typst, Markdown, HTML, PNG by default) rendercv render John_Doe_CV.yaml # Watch mode: auto-re-render whenever the YAML file changes rendercv render John_Doe_CV.yaml --watch # Render only PNG (useful for previewing or checking page count) rendercv render John_Doe_CV.yaml --dont-generate-pdf --dont-generate-html --dont-generate-markdown # Override fields from the CLI without editing the YAML rendercv render cv.yaml --cv.name "Jane Doe" --design.theme "moderncv" ``` ## YAML Structure A RenderCV input has four sections. Only `cv` is required — the others have sensible defaults. ```yaml cv: # Your content: name, contact info, and all sections design: # Visual styling: theme, colors, fonts, margins, spacing, layouts locale: # Language: month names, phrases, translations settings: # Behavior: output paths, bold keywords, current date ``` **Single file vs. separate files:** All four sections can live in one YAML file, or each can be a separate file. Separate files are useful for reusing the same design/locale across multiple CVs: ```bash # Single self-contained file (all sections in one file) rendercv render John_Doe_CV.yaml # Separate files: CV content + design + locale loaded independently rendercv render cv.yaml --design design.yaml --locale-catalog locale.yaml --settings settings.yaml ``` When using separate files, each file contains only its section (e.g., `design.yaml` has `design:` as the top-level key). CLI-loaded files override values in the main YAML file. The YAML maps directly to Pydantic models. The complete type-safe schema is provided below so you can understand every field, its type, and its default value. ## Pydantic Schema The YAML input is validated against these Pydantic models. ### Top-Level Model ```python class RenderCVModel(BaseModelWithoutExtraKeys): cv: Cv = pydantic.Field(default_factory=Cv, title='CV', description='The content of the CV.') design: Design = pydantic.Field(default_factory=ClassicTheme, title='Design') locale: Locale = pydantic.Field(default_factory=EnglishLocale, title='Locale Catalog') settings: Settings = pydantic.Field(default_factory=Settings, title='RenderCV Settings', description='The settings of the RenderCV.') ``` ### CV Content (`cv`) The `cv.sections` field is a dictionary where keys are section titles (any string you want) and values are lists of entries. Each section contains entries of the same type. ```python class Cv(BaseModelWithoutExtraKeys): name: str | None = pydantic.Field(default=None, examples=['John Doe', 'Jane Smith']) headline: str | None = pydantic.Field(default=None, examples=['Software Engineer', 'Data Scientist', 'Product Manager']) location: str | None = pydantic.Field(default=None, examples=['New York, NY', 'London, UK', 'Istanbul, Türkiye']) email: pydantic.EmailStr | list[pydantic.EmailStr] | None = pydantic.Field(default=None, examples=['john.doe@example.com', ['john.doe.1@example.com', 'john.doe.2@example.com']]) photo: ExistingPathRelativeToInput | pydantic.HttpUrl | None = pydantic.Field(default=None, union_mode='left_to_right', examples=['photo.jpg', 'images/profile.png', 'https://example.com/photo.jpg']) phone: pydantic_phone_numbers.PhoneNumber | list[pydantic_phone_numbers.PhoneNumber] | None = pydantic.Field(default=None, examples=['+1-234-567-8900', ['+1-234-567-8900', '+44 20 1234 5678']]) website: pydantic.HttpUrl | list[pydantic.HttpUrl] | None = pydantic.Field(default=None, examples=['https://johndoe.com', ['https://johndoe.com', 'https://www.janesmith.dev']]) social_networks: list[SocialNetwork] | None = pydantic.Field(default=None) custom_connections: list[CustomConnection] | None = pydantic.Field(default=None, examples=[[{'placeholder': 'Book a call', 'url': 'https://cal.com/johndoe', 'fontawesome_icon': 'calendar-days'}]]) sections: dict[str, Section] | None = pydantic.Field(default=None, examples=[{'Experience': '...', 'Education': '...', 'Projects': '...', 'Skills': '...'}]) ``` ```python type SocialNetworkName = Literal['LinkedIn', 'GitHub', 'GitLab', 'IMDB', 'Instagram', 'ORCID', 'Mastodon', 'StackOverflow', 'ResearchGate', 'YouTube', 'Google Scholar', 'Telegram', 'WhatsApp', 'Leetcode', 'X', 'Bluesky', 'Reddit'] available_social_networks = get_args(SocialNetworkName.__value__) class SocialNetwork(BaseModelWithoutExtraKeys): network: SocialNetworkName = pydantic.Field() username: str = pydantic.Field(examples=['john_doe', '@johndoe@mastodon.social', '12345/john-doe']) ``` ```python class CustomConnection(BaseModelWithoutExtraKeys): fontawesome_icon: str placeholder: str url: pydantic.HttpUrl | None ``` ### Entry Types `cv.sections` is a dictionary: keys are section titles (any string), values are lists of entries. Each section must use a **single** entry type — you cannot mix different entry types within the same section. The entry type is auto-detected from the fields present in each entry. **Shared fields** — these are available on entry types that support dates and complex fields (ExperienceEntry, EducationEntry, NormalEntry, PublicationEntry): | Field | Type | Default | Notes | |---|---|---|---| | `date` | `str \| int \| null` | `null` | Free-form: `"2020-09"`, `"Fall 2023"`, etc. Mutually exclusive with `start_date`/`end_date`. | | `start_date` | `str \| int \| null` | `null` | Strict format: YYYY-MM-DD, YYYY-MM, or YYYY. | | `end_date` | `str \| int \| "present" \| null` | `null` | Same formats as `start_date`, or `"present"`. Omitting defaults to `"present"` when `start_date` is set. | | `location` | `str \| null` | `null` | | | `summary` | `str \| null` | `null` | | | `highlights` | `list[str] \| null` | `null` | Bullet points. | **9 entry types:** | Entry Type | Required Fields | Optional Fields | Typical Use | |---|---|---|---| | **ExperienceEntry** | `company`, `position` | all shared fields | Jobs, positions | | **EducationEntry** | `institution`, `area` | `degree` + all shared fields | Degrees, schools | | **PublicationEntry** | `title`, `authors` | `doi`, `url`, `journal`, `summary`, `date` | Papers, articles | | **NormalEntry** | `name` | all shared fields | Projects, awards | | **OneLineEntry** | `label`, `details` | — | Skills, languages | | **BulletEntry** | `bullet` | — | Simple bullet points | | **NumberedEntry** | `number` | — | Numbered list items | | **ReversedNumberedEntry** | `reversed_number` | — | Reverse-numbered items (5, 4, 3...) | | **TextEntry** | *(plain string)* | — | Free-form paragraphs | Example: ```yaml cv: sections: experience: # list of ExperienceEntry (detected by company + position) - company: Google position: Engineer start_date: 2020-01 highlights: - Did something impactful skills: # list of OneLineEntry (detected by label + details) - label: Languages details: Python, C++ about_me: # list of TextEntry (plain strings) - This is a free-form paragraph about me. ``` Entries also accept arbitrary extra keys (silently ignored during rendering). A typo in a field name will NOT cause an error. ### Design (`design`) All built-in themes share the same structure — they only differ in default values. See the sample designs below for every available field and its default. Set `design.theme` to pick a theme, then override any field. ### Locale (`locale`) Built-in locales: `english`, `arabic`, `danish`, `dutch`, `french`, `german`, `hebrew`, `hindi`, `hungarian`, `indonesian`, `italian`, `japanese`, `korean`, `mandarin_chinese`, `norwegian_bokmål`, `norwegian_nynorsk`, `persian`, `portuguese`, `russian`, `spanish`, `turkish`, `vietnamese` Set `locale.language` to a built-in locale name to use it. Override any field to customize translations. Set `language` to any string and provide all translations for a fully custom locale. ### Settings (`settings`) Key fields: `bold_keywords` (list of strings to auto-bold), `current_date` (override today's date), `render_command.*` (output paths, generation flags). ## Important Patterns ### YAML quoting **ALWAYS quote string values that contain a colon (`:`).** This is the most common cause of invalid YAML. Highlights, titles, summaries, and any free-form text often contain colons: ```yaml # WRONG — colon breaks YAML parsing: - title: Catalytic Mechanisms: A New Approach highlights: - Relevant coursework: Distributed Systems, ML # RIGHT — wrap in double quotes: - title: "Catalytic Mechanisms: A New Approach" highlights: - "Relevant coursework: Distributed Systems, ML" ``` Rule: if a string value contains `:`, it MUST be quoted. When in doubt, quote it. ### Bullet characters The `design.highlights.bullet` field only accepts these exact characters: `●`, `•`, `◦`, `-`, `◆`, `★`, `■`, `—`, `○`. Do not use en-dash (`–`), `>`, `*`, or any other character. When in doubt, omit `bullet` to use the theme default. ### Phone numbers Phone numbers MUST be in international format with country code (E.164). Never invent a phone number — only include one if the user provides it. ```yaml # WRONG: phone: "(555) 123-4567" phone: "555-123-4567" # RIGHT: phone: "+15551234567" ``` If the user provides a local number without country code, ask which country, or omit the phone field. ### Text formatting All text fields support inline Markdown: `**bold**`, `*italic*`, `[link text](url)`. Block-level Markdown (headers, lists, blockquotes, code blocks) is not supported. Raw Typst commands and math (`$$f(x)$$`) also pass through. ### Date handling - `date` and `start_date`/`end_date` are mutually exclusive. If `date` is provided, `start_date` and `end_date` are ignored. - If only `start_date` is given, `end_date` defaults to `"present"`. - `start_date`/`end_date` require strict formats: YYYY-MM-DD, YYYY-MM, or YYYY. - `date` is flexible: accepts any string ("Fall 2023") in addition to date formats. ### Section titles - `snake_case` keys auto-capitalize: `work_experience` → "Work Experience" - Keys with spaces or uppercase are used as-is. ### Publication authors Use `*Name*` (single asterisks, italic) to highlight the CV owner in author lists. ### Nested highlights (sub-bullets) ```yaml highlights: - Main bullet point - Sub-bullet 1 - Sub-bullet 2 ``` ## CLI Reference ### `rendercv new "Full Name"` Generate a starter YAML file. | Option | Short | What it does | |---|---|---| | `--theme THEME` | | Theme to use (default: `classic`) | | `--locale LOCALE` | | Locale to use (default: `english`) | | `--create-typst-templates` | | Also create editable Typst template files for full design control | ### `rendercv render ` Generate PDF, Typst, Markdown, HTML, and PNG from a YAML file. | Option | Short | What it does | |---|---|---| | `--watch` | `-w` | Re-render automatically when the YAML file changes | | `--quiet` | `-q` | Suppress all output messages | | `--design FILE` | `-d` | Load design section from a separate YAML file | | `--locale-catalog FILE` | `-lc` | Load locale section from a separate YAML file | | `--settings FILE` | `-s` | Load settings section from a separate YAML file | | `--output-folder DIR` | `-o` | Custom output directory | Per-format controls: `--{format}-path PATH` sets custom output path, `--dont-generate-{format}` skips generation. Formats: `pdf`, `typst`, `markdown`, `html`, `png`. **Override any YAML field from the CLI** using dot notation (overrides without editing the file): ```bash rendercv render CV.yaml --cv.name "Jane Doe" --design.theme "moderncv" rendercv render CV.yaml --cv.sections.education.0.institution "MIT" ``` ### `rendercv create-theme "theme-name"` Scaffold a custom theme directory with editable Typst templates for complete design control. ## JSON Schema For YAML editor autocompletion and validation: ```yaml # yaml-language-server: $schema=https://raw.githubusercontent.com/rendercv/rendercv/refs/tags/v2.8/schema.json ``` ## Complete Example ### Sample CV ```yaml cv: name: John Doe headline: location: San Francisco, CA email: john.doe@email.com photo: phone: website: https://rendercv.com/ social_networks: - network: LinkedIn username: rendercv - network: GitHub username: rendercv custom_connections: sections: Welcome to RenderCV: - RenderCV reads a CV written in a YAML file, and generates a PDF with professional typography. - Each section title is arbitrary. education: - institution: Princeton University area: Computer Science degree: PhD date: start_date: 2018-09 end_date: 2023-05 location: Princeton, NJ summary: highlights: - 'Thesis: Efficient Neural Architecture Search for Resource-Constrained Deployment' - 'Advisor: Prof. Sanjeev Arora' - NSF Graduate Research Fellowship, Siebel Scholar (Class of 2022) - institution: Boğaziçi University area: Computer Engineering degree: BS date: start_date: 2014-09 end_date: 2018-06 location: Istanbul, Türkiye summary: highlights: - 'GPA: 3.97/4.00, Valedictorian' - Fulbright Scholarship recipient for Graduate Studies experience: - company: Nexus AI position: Co-Founder & CTO date: start_date: 2023-06 end_date: present location: San Francisco, CA summary: highlights: - Built foundation model infrastructure serving 2M+ monthly API requests with 99.97% uptime - Raised $18M Series A led by Sequoia Capital, with participation from a16z and Founders Fund - Scaled engineering team from 3 to 28 across ML research, platform, and applied AI divisions - Developed proprietary inference optimization reducing latency by 73% compared to baseline - company: NVIDIA Research position: Research Intern date: start_date: 2022-05 end_date: 2022-08 location: Santa Clara, CA summary: highlights: - Designed sparse attention mechanism reducing transformer memory footprint by 4.2x - Co-authored paper accepted at NeurIPS 2022 (spotlight presentation, top 5% of submissions) projects: - name: '[FlashInfer](https://github.com/)' date: start_date: 2023-01 end_date: present location: summary: Open-source library for high-performance LLM inference kernels highlights: - Achieved 2.8x speedup over baseline attention implementations on A100 GPUs - Adopted by 3 major AI labs, 8,500+ GitHub stars, 200+ contributors - name: '[NeuralPrune](https://github.com/)' date: '2021' start_date: end_date: location: summary: Automated neural network pruning toolkit with differentiable masks highlights: - Reduced model size by 90% with less than 1% accuracy degradation on ImageNet - Featured in PyTorch ecosystem tools, 4,200+ GitHub stars publications: - title: 'Sparse Mixture-of-Experts at Scale: Efficient Routing for Trillion-Parameter Models' authors: - '*John Doe*' - Sarah Williams - David Park summary: doi: 10.1234/neurips.2023.1234 url: journal: NeurIPS 2023 date: 2023-07 - title: Neural Architecture Search via Differentiable Pruning authors: - James Liu - '*John Doe*' summary: doi: 10.1234/neurips.2022.5678 url: journal: NeurIPS 2022, Spotlight date: 2022-12 selected_honors: - bullet: MIT Technology Review 35 Under 35 Innovators (2024) - bullet: Forbes 30 Under 30 in Enterprise Technology (2024) skills: - label: Languages details: Python, C++, CUDA, Rust, Julia - label: ML Frameworks details: PyTorch, JAX, TensorFlow, Triton, ONNX patents: - number: Adaptive Quantization for Neural Network Inference on Edge Devices (US Patent 11,234,567) - number: Dynamic Sparsity Patterns for Efficient Transformer Attention (US Patent 11,345,678) invited_talks: - reversed_number: Scaling Laws for Efficient Inference — Stanford HAI Symposium (2024) - reversed_number: Building AI Infrastructure for the Next Decade — TechCrunch Disrupt (2024) ``` ### Sample Design (classic — complete reference) This shows every available design field with its default value. All themes share the same structure. ```yaml design: theme: classic page: size: us-letter top_margin: 0.7in bottom_margin: 0.7in left_margin: 0.7in right_margin: 0.7in show_footer: true show_top_note: true colors: body: rgb(0, 0, 0) name: rgb(0, 79, 144) headline: rgb(0, 79, 144) connections: rgb(0, 79, 144) section_titles: rgb(0, 79, 144) links: rgb(0, 79, 144) footer: rgb(128, 128, 128) top_note: rgb(128, 128, 128) typography: line_spacing: 0.6em alignment: justified date_and_location_column_alignment: right font_family: body: Source Sans 3 name: Source Sans 3 headline: Source Sans 3 connections: Source Sans 3 section_titles: Source Sans 3 font_size: body: 10pt name: 30pt headline: 10pt connections: 10pt section_titles: 1.4em small_caps: name: false headline: false connections: false section_titles: false bold: name: true headline: false connections: false section_titles: true links: underline: false show_external_link_icon: false header: alignment: center photo_width: 3.5cm photo_position: left photo_space_left: 0.4cm photo_space_right: 0.4cm space_below_name: 0.7cm space_below_headline: 0.7cm space_below_connections: 0.7cm connections: phone_number_format: national hyperlink: true show_icons: true display_urls_instead_of_usernames: false separator: '' space_between_connections: 0.5cm section_titles: type: with_partial_line line_thickness: 0.5pt space_above: 0.5cm space_below: 0.3cm sections: allow_page_break: true space_between_regular_entries: 1.2em space_between_text_based_entries: 0.3em show_time_spans_in: - experience entries: date_and_location_width: 4.15cm side_space: 0.2cm space_between_columns: 0.1cm allow_page_break: false short_second_row: true degree_width: 1cm summary: space_above: 0cm space_left: 0cm highlights: bullet: • nested_bullet: • space_left: 0.15cm space_above: 0cm space_between_items: 0cm space_between_bullet_and_text: 0.5em templates: footer: '*NAME -- PAGE_NUMBER/TOTAL_PAGES*' top_note: '*LAST_UPDATED CURRENT_DATE*' single_date: MONTH_ABBREVIATION YEAR date_range: START_DATE – END_DATE time_span: HOW_MANY_YEARS YEARS HOW_MANY_MONTHS MONTHS one_line_entry: main_column: '**LABEL:** DETAILS' education_entry: main_column: |- **INSTITUTION**, AREA SUMMARY HIGHLIGHTS degree_column: '**DEGREE**' date_and_location_column: |- LOCATION DATE normal_entry: main_column: |- **NAME** SUMMARY HIGHLIGHTS date_and_location_column: |- LOCATION DATE experience_entry: main_column: |- **COMPANY**, POSITION SUMMARY HIGHLIGHTS date_and_location_column: |- LOCATION DATE publication_entry: main_column: |- **TITLE** SUMMARY AUTHORS URL (JOURNAL) date_and_location_column: DATE ``` ### Other Theme Overrides Other themes only override specific fields from the classic defaults above. To use a theme, set `design.theme` and optionally override any field. Each theme also customizes `design.templates` (entry layout patterns) — see the classic sample above for the full template structure. The override YAMLs below omit templates for brevity. #### harvard ```yaml # yaml-language-server: $schema=../../../../../../schema.json design: theme: harvard page: top_margin: 0.5in bottom_margin: 0.5in left_margin: 0.5in right_margin: 0.5in show_top_note: false colors: name: rgb(0,0,0) headline: rgb(0,0,0) connections: rgb(0,0,0) section_titles: rgb(0,0,0) links: rgb(0,0,0) typography: font_family: body: XCharter name: XCharter headline: XCharter connections: XCharter section_titles: XCharter font_size: name: 25pt connections: 9pt section_titles: 1.3em header: space_below_name: 0.5cm space_below_headline: 0.5cm space_below_connections: 0.5cm connections: show_icons: false separator: • space_between_connections: 0.4cm section_titles: type: centered_with_centered_partial_line space_below: 0.2cm sections: space_between_regular_entries: 1em show_time_spans_in: [] entries: short_second_row: false ``` #### engineeringresumes ```yaml # yaml-language-server: $schema=../../../../../../schema.json design: theme: engineeringresumes page: show_footer: false typography: font_family: body: XCharter name: XCharter headline: XCharter connections: XCharter section_titles: XCharter font_size: name: 25pt section_titles: 1.2em bold: name: false header: connections: separator: '|' show_icons: false display_urls_instead_of_usernames: true colors: name: rgb(0,0,0) connections: rgb(0,0,0) headline: rgb(0,0,0) section_titles: rgb(0,0,0) links: rgb(0,0,0) links: underline: true show_external_link_icon: false section_titles: type: with_full_line space_above: 0.5cm space_below: 0.3cm sections: space_between_regular_entries: 0.42cm space_between_text_based_entries: 0.15cm show_time_spans_in: [] entries: short_second_row: false summary: space_above: 0.08cm side_space: 0cm highlights: bullet: ● nested_bullet: ● space_left: 0cm space_above: 0.08cm space_between_items: 0.08cm space_between_bullet_and_text: 0.3em ``` #### engineeringclassic ```yaml # yaml-language-server: $schema=../../../../../../schema.json design: theme: engineeringclassic typography: font_family: body: Raleway name: Raleway headline: Raleway connections: Raleway section_titles: Raleway bold: name: false section_titles: false header: alignment: left links: show_external_link_icon: false section_titles: type: with_full_line sections: show_time_spans_in: [] entries: short_second_row: false summary: space_above: 0.12cm highlights: space_left: 0cm space_above: 0.12cm space_between_items: 0.12cm ``` #### sb2nov ```yaml # yaml-language-server: $schema=../../../../../../schema.json design: theme: sb2nov typography: font_family: body: New Computer Modern name: New Computer Modern headline: New Computer Modern connections: New Computer Modern section_titles: New Computer Modern colors: name: rgb(0,0,0) connections: rgb(0,0,0) section_titles: rgb(0,0,0) headline: rgb(0,0,0) links: rgb(0,0,0) links: underline: true show_external_link_icon: false section_titles: type: with_full_line sections: show_time_spans_in: [] header: connections: hyperlink: true show_icons: false display_urls_instead_of_usernames: true separator: • entries: short_second_row: false highlights: bullet: ◦ nested_bullet: ◦ ``` #### moderncv ```yaml # yaml-language-server: $schema=../../../../../../schema.json design: theme: moderncv typography: line_spacing: 0.6em font_family: body: Fontin name: Fontin headline: Fontin connections: Fontin section_titles: Fontin font_size: name: 25pt section_titles: 1.4em bold: name: false section_titles: false header: alignment: left photo_width: 4.15cm photo_space_left: 0cm photo_space_right: 0.3cm links: underline: true show_external_link_icon: false section_titles: type: moderncv space_above: 0.55cm space_below: 0.3cm line_thickness: 0.15cm sections: show_time_spans_in: [] entries: short_second_row: false side_space: 0cm space_between_columns: 0.3cm summary: space_above: 0.1cm highlights: space_left: 0cm space_above: 0.15cm space_between_items: 0.1cm space_between_bullet_and_text: 0.3em ```