Skip to main content
Vitaes uses Zod for runtime type validation. All types are defined in @vitaes/types/resume.

Core Types

ResumeSchema

The main schema for a complete resume document.
packages/types/src/resume.ts
const ResumeInputSchema = z.object({
  config: ResumeConfigInputSchema,
  personalInfo: PersonalInfoSchema,
  sections: z.array(SectionSchema),
})

export const ResumeSchema = ResumeInputSchema.transform((data) => ({
  ...data,
  config: {
    ...data.config,
    footerLeft: data.config.footerLeft ?? defaultFooterOption,
    footerCenter: data.config.footerCenter ?? defaultFooterOption,
    footerRight: data.config.footerRight ?? defaultFooterRight,
  },
}))

export type IResume = z.infer<typeof ResumeSchema>

ResumeValidationSchema

Strict validation schema used for API inputs (no transforms).
packages/types/src/resume.ts
export const ResumeValidationSchema = z.object({
  config: ResumeConfigValidationSchema,
  personalInfo: PersonalInfoSchema,
  sections: z.array(SectionSchema),
})

Configuration

ResumeConfigSchema

Configuration for resume appearance and layout.
packages/types/src/resume.ts
const ResumeConfigInputSchema = z.object({
  template: TemplateSchema.optional(),
  themeColor: AwesomeColorSchema,
  headerAlign: z.enum(['left', 'center', 'right']),
  sectionColorHighlight: z.boolean(),
  fontSize: z.number().positive(),
  pageSize: z.enum(['A4', 'LETTER']),
  footerLeft: FooterOptionSchema.optional(),
  footerCenter: FooterOptionSchema.optional(),
  footerRight: FooterOptionSchema.optional(),
})

export const ResumeConfigSchema = ResumeConfigInputSchema.transform((data) => ({
  ...data,
  template: data.template ?? 'awesome',
  footerLeft: data.footerLeft ?? defaultFooterOption,
  footerCenter: data.footerCenter ?? defaultFooterOption,
  footerRight: data.footerRight ?? defaultFooterRight,
}))

export type ResumeConfig = z.infer<typeof ResumeConfigSchema>

TemplateSchema

Available resume templates.
packages/types/src/resume.ts
export const TemplateSchema = z.enum([
  'awesome',
  'modern',
  'professional',
  'bold',
])

export type Template = z.infer<typeof TemplateSchema>
Available templates:
  • awesome - Default template with colorful accents
  • modern - Clean modern design
  • professional - Traditional professional style
  • bold - Bold and eye-catching

AwesomeColorSchema

Theme colors for resumes.
packages/types/src/colors.ts
export const AwesomeColorSchema = z.enum([
  'awesome-emerald',
  'awesome-skyblue',
  'awesome-red',
  'awesome-pink',
  'awesome-orange',
  'awesome-nephritis',
  'awesome-concrete',
  'awesome-darknight',
])

export type AwesomeColor = z.infer<typeof AwesomeColorSchema>
Color values:
  • awesome-emerald - #00A388
  • awesome-skyblue - #0395DE
  • awesome-red - #DC3522
  • awesome-pink - #EF4089
  • awesome-orange - #FF6138
  • awesome-nephritis - #27AE60
  • awesome-concrete - #95A5A6
  • awesome-darknight - #131A28

FooterOptionSchema

Configuration for footer sections.
packages/types/src/resume.ts
export const FooterOptionSchema = z.object({
  text: z.string(),
  showPageNumber: z.boolean(),
})

export type FooterOption = z.infer<typeof FooterOptionSchema>

Personal Information

PersonalInfoSchema

Personal details and contact information.
packages/types/src/resume.ts
export const PersonalInfoSchema = z.object({
  firstName: z.string(),
  lastName: z.string(),
  position: z.string(),
  address: z.string(),
  socials: z.array(SocialProfileSchema),
  quote: z.string().optional(),
  photo: z
    .object({
      url: z.string().url(),
      shape: z.enum(['circle', 'rectangle']).optional(),
      edge: z.enum(['edge', 'noedge']).optional(),
      align: z.enum(['left', 'right']).optional(),
    })
    .optional(),
})

export type PersonalInfo = z.infer<typeof PersonalInfoSchema>

SocialProfileSchema

Social media profiles and contact methods.
packages/types/src/resume.ts
export const SocialPlatformSchema = z.enum([
  'mobile',
  'email',
  'homepage',
  'github',
  'gitlab',
  'linkedin',
  'twitter',
  'stackoverflow',
  'skype',
  'reddit',
  'xing',
  'medium',
  'googlescholar',
])

export const SocialProfileSchema = z.object({
  id: z.string(),
  platform: SocialPlatformSchema,
  value: z.string(),
  display: z.string().optional(),
  url: z.string().url().optional(),
})

export type SocialPlatform = z.infer<typeof SocialPlatformSchema>
export type SocialProfile = z.infer<typeof SocialProfileSchema>
Supported platforms:
  • mobile - Phone number
  • email - Email address
  • homepage - Personal website
  • github - GitHub profile
  • gitlab - GitLab profile
  • linkedin - LinkedIn profile
  • twitter - Twitter/X profile
  • stackoverflow - Stack Overflow profile
  • skype - Skype username
  • reddit - Reddit profile
  • xing - Xing profile
  • medium - Medium profile
  • googlescholar - Google Scholar profile

Section Types

Resumes are composed of sections. Each section has a type that determines its structure.

SectionSchema

Discriminated union of all section types.
packages/types/src/resume.ts
export const SectionTypeSchema = z.enum([
  'text',
  'timeline',
  'list',
  'taxonomy',
])

export const SectionSchema = z.discriminatedUnion('type', [
  TextSectionSchema,
  TimelineSectionSchema,
  ListSectionSchema,
  TaxonomySectionSchema,
])

export type SectionType = z.infer<typeof SectionTypeSchema>
export type Section = z.infer<typeof SectionSchema>

BaseSectionSchema

Common fields for all sections.
packages/types/src/resume.ts
export const BaseSectionSchema = z.object({
  id: z.string(),
  title: z.string(),
  type: SectionTypeSchema,
})

TextSectionSchema

Simple text content section.
packages/types/src/resume.ts
export const TextSectionSchema = BaseSectionSchema.extend({
  type: z.literal('text'),
  content: z.string(),
})

export type TextSection = z.infer<typeof TextSectionSchema>
Use cases:
  • Professional summary
  • About me section
  • Career objectives
  • Cover letter content

TimelineSectionSchema

Timeline-based entries (jobs, education, etc.).
packages/types/src/resume.ts
export const EntryItemSchema = BaseItemSchema.extend({
  position: z.string(),
  title: z.string(),
  location: z.string(),
  date: z.string(),
  description: z.string().optional(),
  items: z.array(z.string()).optional(),
})

export const TimelineSectionSchema = BaseSectionSchema.extend({
  type: z.literal('timeline'),
  entries: z.array(EntryItemSchema),
})

export type EntryItem = z.infer<typeof EntryItemSchema>
export type TimelineSection = z.infer<typeof TimelineSectionSchema>
Use cases:
  • Work experience
  • Education history
  • Volunteer work
  • Professional development

ListSectionSchema

Structured list section with flat or grouped items.
packages/types/src/resume.ts
export const ListItemSchema = BaseItemSchema.extend({
  date: z.string(),
  position: z.string(),
  title: z.string(),
  location: z.string(),
})

export const ListSubsectionSchema = z.object({
  id: z.string(),
  title: z.string(),
  items: z.array(ListItemSchema),
})

export const ListSectionSchema = BaseSectionSchema.extend({
  type: z.literal('list'),
  structure: z.discriminatedUnion('type', [
    z.object({
      type: z.literal('flat'),
      items: z.array(ListItemSchema),
    }),
    z.object({
      type: z.literal('grouped'),
      subsections: z.array(ListSubsectionSchema),
    }),
  ]),
})

export type ListItem = z.infer<typeof ListItemSchema>
export type ListSubsection = z.infer<typeof ListSubsectionSchema>
export type ListSection = z.infer<typeof ListSectionSchema>
Use cases:
  • Awards and honors
  • Certifications
  • Publications
  • Projects
  • Speaking engagements

TaxonomySectionSchema

Categorized items section (skills, languages, etc.).
packages/types/src/resume.ts
export const CategoryItemSchema = BaseItemSchema.extend({
  type: z.string(),
  items: z.array(z.string()),
})

export const TaxonomySectionSchema = BaseSectionSchema.extend({
  type: z.literal('taxonomy'),
  categories: z.array(CategoryItemSchema),
})

export type CategoryItem = z.infer<typeof CategoryItemSchema>
export type TaxonomySection = z.infer<typeof TaxonomySectionSchema>
Use cases:
  • Technical skills
  • Languages
  • Tools and technologies
  • Interests and hobbies

Type Guards

Helper functions to narrow section types.
packages/types/src/resume.ts
export const isTextSection = (section: Section): section is TextSection =>
  section.type === 'text'

export const isTimelineSection = (
  section: Section,
): section is TimelineSection => section.type === 'timeline'

export const isListSection = (section: Section): section is ListSection =>
  section.type === 'list'

export const isTaxonomySection = (
  section: Section,
): section is TaxonomySection => section.type === 'taxonomy'
Usage:
import { isTimelineSection } from '@vitaes/types/resume'

for (const section of resume.sections) {
  if (isTimelineSection(section)) {
    // TypeScript knows section is TimelineSection
    section.entries.forEach(entry => {
      console.log(entry.position, entry.title)
    })
  }
}

Example Data

Vitaes includes example resumes in multiple languages:
packages/types/src/resume.ts
export const exampleResumes = {
  en: kendallRoyNew,
  es: inigoMontoyaNew,
  fr: arseneLupinNew,
  de: kingSchultzNew,
  ja: golDRogerNew,
  pt: agostinhoCarraraResume,
  zh: sunTzuNew,
}
Available languages:
  • en - English
  • es - Spanish
  • fr - French
  • de - German
  • ja - Japanese
  • pt - Portuguese
  • zh - Chinese
These example resumes are used when creating new resumes via the createResume endpoint.

Build docs developers (and LLMs) love