Frontmatter Reference
Configure rendering options directly inside your resume using YAML or TOML frontmatter. CLI flags take precedence over frontmatter values.
Syntax
YAML
---
pages: 1
output: ./dist/John_Doe-{view}
style:
font-family: 'Inter, sans-serif'
section-title-color: '#2563eb'
---TOML
+++
pages = 1
output = "./dist/John_Doe-{view}"
[style]
font-family = "Inter, sans-serif"
section-title-color = "#2563eb"
+++YAML uses --- delimiters; TOML uses +++. Both are fully supported, pick whichever you prefer.
Render Fields (Default View)
These fields form the default view, the base render configuration that applies to every render. Tag views, custom views, and ephemeral views override these values.
css
Custom CSS file path(s) or inline CSS string(s) to load in addition to the default styles. Entries ending with .css are resolved as file paths, everything else is treated as inline CSS. Inline CSS renders in a separate <style> tag after the base styles for error isolation.
| Property | Value |
|---|---|
| Type | string or string[] |
| Default | None (uses built-in default) |
| CLI flag | --css <path> |
A single string is automatically normalized to a one-element array.
Priority: CLI > frontmatter.
# Single CSS file
css: my-styles.css
# Multiple CSS files
css: [base.css, overrides.css]
# Inline CSS (no file needed)
css: |
h2 {
letter-spacing: 0.05em;
}
# Mixed: file path + inline CSS
css:
- base.css
- |
h2::after {
content: '';
flex: 1;
border-bottom: var(--section-title-border);
}CSS preprocessor files (.less, .sass, .scss, .styl) are not supported.
output
Output path for rendered files. Supports three modes depending on its value:
| Property | Value |
|---|---|
| Type | string |
| Default | Input filename stem in cwd (e.g. resume.md → resume.pdf) |
| CLI flag | -o, --output <value> |
Modes:
| Value | Mode | Behavior |
|---|---|---|
./dist/ | Directory | Ends with /, output files go into this directory using default naming rules |
John_Doe | Plain name | No {…}, used as the base filename, with automatic tag/lang suffixes |
./dist/John_Doe-{view}-{lang} | Template | Contains {view}, {lang}, and/or {format}, expanded for each combination |
Template variables:
{view}— the tag or view name (e.g.frontend,stripe-swe). Expands to empty string when rendering without--for; orphaned separators are cleaned up automatically.{lang}— the language tag (e.g.en,fr). Expands to empty string when no languages exist.{format}— the output format (e.g.pdf,html). Useful for organizing outputs into format-specific directories.
When using template mode, if the expanded paths would produce duplicate filenames, an error is raised with a suggestion.
# Plain name, produces John_Doe.pdf
output: John_Doe
# Directory, uses default name in ./dist/
output: ./dist/
# Template, produces ./dist/John_Doe-frontend.pdf, etc.
output: ./dist/John_Doe-{view}
# Template with both, produces frontend/John_Doe-en.pdf, etc.
output: "{view}/John_Doe-{lang}"
# Path with directory and name
output: ./dist/John_Doepages
Target page count. When set, Resumx automatically adjusts style options (gaps, line-height, font-size, margins) to fit your resume within the specified number of pages.
| Property | Value |
|---|---|
| Type | positive integer |
| Default | No page clamping |
| CLI flag | --pages <number> |
Behavior:
- Shrink to fit: Progressively reduces spacing, line-height, font-size, and margins through a four-phase waterfall until content fits within the target page count. Adjustments stop as soon as the target is reached — no more is changed than necessary.
- Single-page fill (
pages: 1only): If content fits on one page with room to spare, gaps are expanded (up to 1.5× their original value) to fill the page. This only applies to single-page resumes where bottom whitespace looks unintentional. - Readability minimums: Variables are never reduced below safe minimums (e.g. font-size: 9pt, line-height: 1.15, section-gap: 4px). If content cannot fit even at minimums, the resume renders as-is with a warning.
The shrinking phases apply in order of visual impact (least noticeable first):
- Gaps — row-gap, entry-gap, section-gap
- Line height — unitless line-height ratio
- Font size — in points
- Margins — page-margin-x and page-margin-y (last resort)
Priority: CLI > frontmatter.
# Fit resume to exactly 1 page (shrink + fill)
pages: 1
# Fit resume to at most 2 pages (shrink only)
pages: 2TIP
style: values are treated as starting points when pages: is set. The clamping engine may reduce them toward global minimums. If you want strict style control without any automatic adjustments, don't use pages:.
See Fit to Page for the full guide.
sections
Controls which sections appear and how they're ordered. Contains two sub-fields: hide and pin.
| Property | Value |
|---|---|
| Type | { hide?: string[], pin?: string[] } |
| Default | All sections in source order |
| CLI flags | --hide <sections>, --pin <sections> (comma-separated) |
| Values | data-section types (see table below) |
hideremoves listed sections from the output. Everything not hidden renders in source order by default. Adding a new section to your resume means it appears everywhere unless you explicitly hide it.pinmoves listed sections to the top of the document, in the specified order. Non-pinned sections follow in their original source order. The header always renders regardless.
sections:
hide: [publications, volunteer]
pin: [skills, work]Valid section types:
basics, work, volunteer, education, awards, certificates, publications, skills, languages, interests, references, projects
If you use a common synonym (e.g. experience instead of work), the error message suggests the canonical name.
A section cannot appear in both hide and pin. If it does, Resumx raises an error.
Priority: CLI > view > frontmatter. In the cascade, each sub-field replaces independently: setting sections: { pin: [skills] } in a child view replaces only pin, the parent's hide is preserved.
See Views: Sections for the full guide.
bullet-order
Controls how bullets are ordered within each section when rendering with tags or views.
| Property | Value |
|---|---|
| Type | none | tag |
| Default | none |
| CLI flag | --bullet-order <value> |
Values:
| Value | Behavior |
|---|---|
none | Document order, as written in markdown. |
tag | Tagged bullets promoted to top, sorted by selects declaration order within the group. |
Set as a base default to apply to all views, or override per-view.
bullet-order: tagSee Views: Bullet Order for the full guide.
tags
Tag composition and tag view configuration. Define composed tags as unions of constituent tags, and optionally configure their implicit tag view. When rendering for a composed tag, content tagged with any constituent is included. Use --for <name> to render a tag view.
| Property | Value |
|---|---|
| Type | Record<string, string[] | TagConfig> |
| Default | No composed tags |
Shorthand (composition only):
tags:
fullstack: [frontend, backend]
tech-lead: [backend, leadership]
startup-cto: [fullstack, leadership, architecture]Expanded (composition + tag view config):
tags:
frontend:
sections:
hide: [publications]
pin: [skills, projects]
pages: 1
fullstack:
extends: [frontend, backend]
sections:
pin: [work, skills]
pages: 2The shorthand fullstack: [frontend, backend] is sugar for fullstack: { extends: [frontend, backend] }.
Compositions can reference other composed tags (recursive expansion). Circular references produce an error. Every constituent must exist as a content tag ({.@name} in your resume) or as another composed tag. Typos produce an error with a Levenshtein suggestion.
Constituents can be hierarchical tags like backend/node. When expanded, each constituent's lineage (ancestors + self + descendants) is included:
tags:
stripe: [frontend, backend/node]
# Expands to: @frontend (+ @frontend/* descendants)
# + @backend (ancestor) + @backend/node (self)
# + untaggedSee Tags for tagging syntax, composition, hierarchical tags, and tag views. See Views for custom views and ephemeral views.
vars
Template variables that can be referenced in the resume body with {{ name }} syntax. Variables provide a way to inject per-application content (taglines, keyword lines) without editing the resume body.
| Property | Value |
|---|---|
| Type | Record<string, string> |
| Default | No variables |
| CLI flag | -v, --var <key=value> |
Variables defined here serve as base defaults. They can be overridden by view vars or CLI -v flags.
Priority: CLI > view > frontmatter.
vars:
tagline: 'Full-stack engineer with 8 years of experience'
keywords: ''In the resume body:
{{ tagline }}When a variable is undefined or empty, the {{ }} placeholder produces nothing (the line is removed from output). Variable values can contain markdown formatting, which is rendered normally.
Defining a variable with no matching placeholder in the document is an error.
See Views: Variables for the full guide.
icons
Custom icon definitions. Keys are icon slugs usable with :slug: syntax; values are SVG strings, URLs, or base64 data URIs.
| Property | Value |
|---|---|
| Type | Record<string, string> |
| Default | No custom icons |
Frontmatter icons override built-in and Iconify icons with the same slug.
icons:
mycompany: '<svg xmlns="http://www.w3.org/2000/svg"><circle r="10"/></svg>'
partner: 'https://example.com/partner-logo.svg'
badge: 'data:image/svg+xml;base64,PHN2Zz4uLi48L3N2Zz4='See Icons for details.
extra
Arbitrary user-defined data. Use this for any custom fields that aren't part of the built-in schema (e.g. name, target role, company). Values can be strings, numbers, booleans, arrays, or nested objects.
| Property | Value |
|---|---|
| Type | Record<string, unknown> |
| Default | No custom data |
Unknown top-level fields are rejected with an error. extra is the only place for custom data.
extra:
name: Jane Smith
target-role: Senior SWE
companies:
- Acme Corp
- Globex[extra]
name = "Jane Smith"
target-role = "Senior SWE"
companies = ["Acme Corp", "Globex"]style
Style overrides applied on top of the defaults. Keys map to --key in the generated CSS (e.g. font-family -> --font-family).
| Property | Value |
|---|---|
| Type | Record<string, string> |
| Default | No overrides |
| CLI flag | -s, --style <name=value> |
Priority: CLI > frontmatter
style:
font-family: 'Inter, sans-serif'
section-title-color: '#2563eb'
font-size: '10pt'See the Style Options reference for the full list.
Validate Fields
These fields configure validation (run by default before rendering, or standalone with --check). They are placed under a validate key and are separate from the render fields above.
validate.extends
Base validation preset to use.
| Property | Value |
|---|---|
| Type | string |
| Default | recommended |
| Allowed | recommended, minimal, strict, none |
Presets:
| Preset | Rules included |
|---|---|
recommended | missing-name, missing-contact, no-sections, no-entries, empty-bullet, long-bullet, single-bullet-section |
minimal | missing-name, missing-contact, no-sections, no-entries, empty-bullet |
strict | Same rules as recommended (all rules run at their default severities) |
none | No rules — validation is effectively disabled |
validate.rules
Per-rule severity overrides. Set any rule to a severity level or off to disable it.
| Property | Value |
|---|---|
| Type | Record<string, Severity | 'off'> |
| Severities | critical, warning, note, bonus, off |
validate:
extends: recommended
rules:
long-bullet: warning # Downgrade from critical
single-bullet-section: off # Disable entirelyAvailable Rules
| Rule | Default Severity | Description |
|---|---|---|
missing-name | critical | Resume must have an H1 heading (your name). |
missing-contact | critical | Resume must have contact info (email or phone) after name. |
no-sections | critical | Resume must have at least one H2 section. |
no-entries | warning | Resume should have at least one H3 entry. |
empty-bullet | critical | List items must have text content. |
long-bullet | critical/warning | Bullet exceeds character length threshold. |
single-bullet-section | bonus | Section has only one bullet point. |
unknown-fenced-div-tag | warning | Named fenced div uses an unrecognized HTML tag name. |
Full Example
---
pages: 1
output: ./out/Jane_Smith-{view}
bullet-order: tag
style:
link-color: '#0ea5e9'
tags:
fullstack: [frontend, backend]
leadership: false
vars:
tagline: 'Full-stack engineer with 8 years of experience'
validate:
extends: recommended
rules:
long-bullet: warning
single-bullet-section: off
extra:
name: Jane Smith
target-role: Senior SWE
---Custom views are defined in external .view.yaml files. Tag views are configured inline under tags:. See Views for the full guide.
Field Precedence
For fields that can be set in multiple places, the resolution order is:
| Priority | Source |
|---|---|
| 1 (highest) | Ephemeral view (CLI flags) |
| 2 | Tag view OR custom view (whichever resolves) |
| 3 | Default view (frontmatter render fields) |
| 4 (lowest) | Built-in defaults |
Unknown Fields
Any top-level frontmatter key not in the known set (css, output, pages, sections, bullet-order, style, icons, tags, vars, validate, extra) produces an error:
Unknown frontmatter field 'foo'. Use 'extra' for custom fields.If the unknown field looks like a typo of a known field, a more specific suggestion is shown:
Unknown frontmatter field 'page'. Did you mean 'pages'?To store custom data, use the extra field.