Claude
Skills
Sign in
Back

rendercv

Included with Lifetime
$97 forever

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.

Image & Video

What this skill does


## 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=['[email protected]', ['[email protected]', '[email protected]']])
    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', '@[email protected]', '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 s
Files: 1
Size: 25.8 KB
Complexity: 33/100
Category: Image & Video

Related in Image & Video