npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jsonresume/core

v0.1.0

Published

Framework-agnostic resume component core - design tokens, primitives, and validators

Readme

@jsonresume/core

React component library for building ATS-friendly, print-optimized resume themes

A comprehensive collection of 200+ React components, design tokens, and utilities that enable rapid development of professional resume themes. Built with styled-components for maximum flexibility and SSR support.

Features

  • 200+ React Components - Comprehensive primitives across 20 categories
  • Design Tokens System - Typography, colors, spacing, layout, radius, shadows
  • Security Utilities - URL validation, HTML sanitization, external link detection
  • Calculation Helpers - 20+ functions for resume metrics and statistics
  • SSR Support - Full server-side rendering with styled-components
  • Print Optimization - Perfect PDF exports with @media print styles
  • ATS-Friendly - Semantic HTML, proper heading hierarchy, accessibility features
  • Theme Support - ThemeProvider with customizable design tokens

Installation

npm install @jsonresume/core
# or
yarn add @jsonresume/core
# or
pnpm add @jsonresume/core

Peer Dependencies:

This package requires React 18 or 19 and styled-components:

npm install react react-dom styled-components

Quick Start

import React from 'react';
import {
  ThemeProvider,
  Section,
  SectionTitle,
  ListItem,
  DateRange,
  Badge,
  BadgeList,
} from '@jsonresume/core';

function Resume({ resume }) {
  return (
    <ThemeProvider>
      <Section id="work">
        <SectionTitle>Work Experience</SectionTitle>
        {resume.work.map((job) => (
          <ListItem
            key={job.name}
            title={job.position}
            subtitle={job.name}
            dateRange={<DateRange start={job.startDate} end={job.endDate} />}
            location={job.location}
            highlights={job.highlights}
          />
        ))}
      </Section>

      <Section id="skills">
        <SectionTitle>Skills</SectionTitle>
        {resume.skills.map((skill) => (
          <div key={skill.name}>
            <h3>{skill.name}</h3>
            <BadgeList items={skill.keywords} />
          </div>
        ))}
      </Section>
    </ThemeProvider>
  );
}

export default Resume;

Component Categories

Core Primitives (7 components)

Basic building blocks for resume sections:

  • Section - Semantic section wrapper with print optimization
  • SectionTitle - Styled section headings
  • ListItem - Experience/education entries with metadata
  • DateRange - Smart date formatting with "Present" support
  • Badge - Skill tags and keywords
  • BadgeList - Multiple badges with consistent styling
  • ContactInfo - Contact details with icons
  • Link - Safe external links with security validation

Layout Components (6 components)

Structure and organization:

  • GridLayout - Multi-column responsive grids
  • SidebarLayout - Two-column layout with sidebar
  • StackLayout - Vertical stacking with spacing
  • CardLayout - Card-based content containers
  • FlexLayout - Flexible box layouts
  • TwoColumnMicroGrid - Compact two-column grids

Skills Components (6 components)

Visual skill representations:

  • SkillBar - Progress bar visualization
  • SkillPill - Pill-shaped skill badges
  • SkillRating - Star or dot rating display
  • SkillGroup - Grouped skill categories
  • SkillCloud - Tag cloud visualization
  • SkillCategory - Categorized skill lists

Profile Components (4 components)

Header and contact sections:

  • Avatar - Profile image with fallback
  • ProfileCard - Complete profile header
  • ContactGrid - Grid of contact methods
  • SocialLinks - Social media icon links

Typography Components (6 components)

Text styling and formatting:

  • Heading - Semantic headings (h1-h6)
  • Text - Body text with variants
  • Label - Small labels and captions
  • SectionIntroParagraph - Section introductions
  • QuoteStripe - Pull quotes
  • HyphenationSafeParagraph - Print-safe paragraphs

Data Display Components (10 components)

Metrics and statistics:

  • ProgressCircle - Circular progress indicators
  • StatCard - Statistic cards
  • MetricBar - Horizontal metric bars
  • MetricInline - Inline metric display
  • MetricBullet - Bullet-style metrics
  • MetricBulletList - List of bullet metrics
  • KPIChipLine - Key performance indicator chips
  • KPIChip - Single KPI chip
  • KeyValueInline - Inline key-value pairs
  • KeyValue - Block key-value pairs

Experience Components (4 components)

Work history layouts:

  • ExperienceCard - Card-based job entries
  • ExperienceTimeline - Timeline visualization
  • ExperienceGrid - Grid layout for multiple jobs
  • ExperienceCompact - Condensed job listings

Header/Footer Components (11 components)

Page headers and footers:

  • HeaderCentered - Centered header layout
  • HeaderSplit - Two-column header
  • HeaderMinimal - Minimal header design
  • CornerInitials - Initials in corner
  • Footer - Page footer
  • PageBreak - Explicit page breaks
  • HeroNameBlock - Large name display
  • ContactRowLine - Single-line contact row
  • SectionRuleTitle - Title with horizontal rule
  • SectionFlagTitle - Title with accent flag
  • NameStackElegant - Elegant name stack

Timeline Components (4 components)

Chronological displays:

  • TimelineSection - Full timeline section
  • TimelineItem - Individual timeline entry
  • TimelineRuleMinimal - Minimal timeline rule
  • TimelineInline - Inline timeline display

Quote/Testimonial Components (3 components)

Highlighted quotes:

  • PullQuote - Sidebar pull quotes
  • Testimonial - Testimonial cards
  • BlockQuote - Block quote styling

Certification/Award Components (4 components)

Credentials and honors:

  • CertificationBadge - Certification badges
  • CertificationRow - Row-based cert display
  • AwardCard - Award cards
  • HonorsList - List of honors

Language Components (4 components)

Language proficiency:

  • LanguageBar - Progress bar for proficiency
  • LanguageLevelBarLite - Compact proficiency bar
  • LanguageGrid - Grid of languages
  • ProficiencyScale - Visual proficiency scale

Publication/Portfolio Components (4 components)

Academic and creative work:

  • PublicationItem - Publication entries
  • PublicationEntryPlain - Plain publication format
  • PortfolioGrid - Portfolio item grid
  • ProjectCard - Project showcase cards

Table Components (3 components)

Structured data:

  • SkillMatrix - Skills matrix table
  • ComparisonTable - Comparison tables
  • DataTable - Generic data tables

List Components (11 components)

Various list styles:

  • CheckList - Checkmark lists
  • IconList - Lists with icons
  • NumberedList - Numbered lists
  • BulletList - Bullet point lists
  • CompactList - Condensed lists
  • AchievementListTight - Tight achievement lists
  • AchievementListSpacious - Spacious achievements
  • HangingBulletList - Hanging indent bullets
  • ListDashCompact - Dash-separated lists
  • MiniDotLeaderList - Dot leader lists
  • DefinitionKeyline - Definition lists

Callout Components (3 components)

Highlighted content:

  • Callout - Callout boxes
  • InfoBox - Information boxes
  • HighlightCard - Highlighted cards

Visual Components (4 components)

Decorative elements:

  • BackgroundPattern - Background patterns
  • ColorBlock - Colored blocks
  • DividerVariants - Various divider styles
  • BorderAccent - Border accents

Date Components (2 components)

Date formatting:

  • DateBadge - Date badges
  • RelativeDate - Relative date formatting

Print Utilities (8 components)

Print optimization:

  • KeepTogether - Prevent page breaks
  • ColumnBreak - Force column breaks
  • PrintOnly - Show only in print
  • ScreenOnly - Show only on screen
  • PageHeaderLine - Print headers
  • PageFooterLine - Print footers
  • LetterheadBar - Letterhead styling
  • SoftShadowEmulation - Print-safe shadows

Metadata Components (5 components)

Supplementary information:

  • InlineKicker - Inline kickers
  • MetaRow - Metadata rows
  • SubsectionLabel - Subsection labels
  • GreyLabelCaps - Small caps labels
  • SmallCapsHeading - Small caps headings

Container Components (4 components)

Content containers:

  • MutedPanel - Muted background panels
  • AccentCalloutPanel - Accent panels
  • SoftCardOutline - Soft card outlines
  • RoleBlockFramed - Framed role blocks

Tag/Badge Components (2 components)

Tags and badges:

  • ToolTagRibbon - Tool tag ribbons
  • BadgeRowOutline - Outlined badge rows

Design Tokens

Access design tokens for consistent theming:

import { typography, colors, spacing, layout, radius, shadows } from '@jsonresume/core';

console.log(colors.primary); // 'var(--resume-color-primary)'
console.log(typography.fonts.sans); // 'var(--resume-font-sans)'

Available token categories:

  • typography - Font families, sizes, weights, line heights
  • colors - Primary, secondary, accent, muted, background colors
  • spacing - Margins, padding, gaps
  • layout - Max widths, container sizes
  • radius - Border radius values
  • shadows - Box shadow definitions

Raw tokens (for SSR/PDF generation):

import { rawTokens } from '@jsonresume/core';

console.log(rawTokens.typography.fonts.sans);
// '"Helvetica Neue", Helvetica, Arial, sans-serif'

Security Utilities

Protect against XSS and malicious URLs:

import { safeUrl, sanitizeHtml, isExternalUrl, getLinkRel } from '@jsonresume/core';

// Validate URLs before rendering
const url = safeUrl(userProvidedUrl); // Returns safe URL or '#'

// Sanitize HTML content
const clean = sanitizeHtml(userHTML); // Strips dangerous tags/attributes

// Check if URL is external
if (isExternalUrl(url)) {
  // Add external link indicators
}

// Get appropriate rel attribute
const rel = getLinkRel(url); // Returns 'noopener noreferrer' for external

Best practices:

  • Always use safeUrl() for user-provided URLs
  • Use sanitizeHtml() for any user HTML content
  • Apply getLinkRel() to external links

Calculation Helpers

Calculate resume metrics and statistics:

import {
  calculateTotalExperience,
  countCompanies,
  getHighestDegree,
  isCurrentlyEmployed,
} from '@jsonresume/core';

const resume = { work: [...], education: [...] };

const experience = calculateTotalExperience(resume.work); // Years of experience
const companies = countCompanies(resume.work); // Number of companies
const degree = getHighestDegree(resume.education); // Highest degree
const employed = isCurrentlyEmployed(resume.work); // Boolean

Available calculations:

  • calculateTotalExperience(work) - Total years of experience
  • calculateCurrentRoleExperience(work) - Current role duration
  • countCompanies(work) - Number of companies worked at
  • countProjects(projects) - Number of projects
  • countPublications(publications) - Number of publications
  • countAwards(awards) - Number of awards
  • countTotalSkills(skills) - Total skill count
  • countSkillCategories(skills) - Number of skill categories
  • countLanguages(languages) - Number of languages
  • calculateVolunteerYears(volunteer) - Years of volunteer work
  • calculateEducationYears(education) - Years of education
  • getHighestDegree(education) - Highest degree earned
  • countCareerPositions(work) - Total positions held
  • getCareerProgressionRate(work) - Career progression rate
  • countTotalHighlights(work) - Total highlights across jobs
  • getUniqueIndustries(work) - Unique industries worked in
  • getCurrentEmployer(work) - Current employer name
  • isCurrentlyEmployed(work) - Employment status
  • calculateKeyMetrics(resume) - All metrics in one object

Server-Side Rendering (SSR)

Full SSR support with styled-components:

import { renderToString } from 'react-dom/server';
import { ServerStyleSheet } from 'styled-components';
import Resume from './Resume';

export function render(resume) {
  const sheet = new ServerStyleSheet();

  try {
    const html = renderToString(sheet.collectStyles(<Resume resume={resume} />));
    const styleTags = sheet.getStyleTags();

    return `
      <!DOCTYPE html>
      <html>
        <head>
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width, initial-scale=1">
          <title>${resume.basics.name} - Resume</title>
          ${styleTags}
        </head>
        <body>
          ${html}
        </body>
      </html>
    `;
  } finally {
    sheet.seal();
  }
}

IMPORTANT: Without ServerStyleSheet, styled-components won't inject CSS and your theme will have no styles!

Theme Building Tutorial

Step 1: Create Theme Package

mkdir packages/jsonresume-theme-myname
cd packages/jsonresume-theme-myname
pnpm init

Step 2: Configure package.json

{
  "name": "jsonresume-theme-myname",
  "version": "1.0.0",
  "main": "./src/index.js",
  "peerDependencies": {
    "react": "^18.0.0 || ^19.0.0",
    "react-dom": "^18.0.0 || ^19.0.0"
  },
  "dependencies": {
    "@jsonresume/core": "workspace:*",
    "styled-components": "workspace:*"
  }
}

Step 3: Create Resume Component

// src/Resume.jsx
import React from 'react';
import {
  ThemeProvider,
  Section,
  SectionTitle,
  ProfileCard,
  ExperienceTimeline,
  BadgeList,
} from '@jsonresume/core';

export default function Resume({ resume }) {
  const { basics, work, education, skills } = resume;

  return (
    <ThemeProvider>
      <ProfileCard
        name={basics.name}
        label={basics.label}
        email={basics.email}
        phone={basics.phone}
        url={basics.url}
        summary={basics.summary}
      />

      <Section id="work">
        <SectionTitle>Experience</SectionTitle>
        <ExperienceTimeline items={work} />
      </Section>

      <Section id="education">
        <SectionTitle>Education</SectionTitle>
        {education.map((edu) => (
          <div key={edu.institution}>
            <h3>{edu.institution}</h3>
            <p>
              {edu.studyType} in {edu.area}
            </p>
          </div>
        ))}
      </Section>

      <Section id="skills">
        <SectionTitle>Skills</SectionTitle>
        {skills.map((skill) => (
          <div key={skill.name}>
            <h4>{skill.name}</h4>
            <BadgeList items={skill.keywords} />
          </div>
        ))}
      </Section>
    </ThemeProvider>
  );
}

Step 4: Create Render Function

// src/index.js
import { renderToString } from 'react-dom/server';
import { ServerStyleSheet } from 'styled-components';
import Resume from './Resume.jsx';

export function render(resume) {
  const sheet = new ServerStyleSheet();

  try {
    const html = renderToString(sheet.collectStyles(<Resume resume={resume} />));
    const styles = sheet.getStyleTags();

    return `
      <!DOCTYPE html>
      <html>
        <head>
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width, initial-scale=1">
          <title>${resume.basics.name} - Resume</title>
          ${styles}
        </head>
        <body>
          ${html}
        </body>
      </html>
    `;
  } finally {
    sheet.seal();
  }
}

Step 5: Register Theme

Add to apps/registry/lib/formatters/template/themeConfig.js:

import * as myTheme from 'jsonresume-theme-myname';

export const THEMES = {
  // ...
  myname: {
    name: 'My Theme',
    theme: myTheme,
    description: 'A beautiful custom theme',
  },
};

Examples

Complete Resume

import Resume from 'jsonresume-theme-myname';

const resumeData = {
  basics: {
    name: 'John Doe',
    label: 'Software Engineer',
    email: '[email protected]',
    // ...
  },
  work: [
    {
      name: 'TechCorp',
      position: 'Senior Engineer',
      startDate: '2020-01',
      endDate: null,
      highlights: ['Led team of 6', 'Reduced costs by $200k'],
    },
  ],
  // ...
};

const html = Resume.render(resumeData);

Custom Styling

import styled from 'styled-components';
import { Section as BaseSection } from '@jsonresume/core';

const CustomSection = styled(BaseSection)`
  background: linear-gradient(to right, #f0f0f0, #ffffff);
  padding: 2rem;
  border-radius: 8px;
`;

TypeScript Support

TypeScript definitions are included:

import { Section, SectionTitle, ListItem } from '@jsonresume/core';
import type { Resume } from '@jsonresume/core';

function MyResume({ resume }: { resume: Resume }) {
  // Full type safety
}

Browser Support

  • Chrome 90+
  • Firefox 88+
  • Safari 14+
  • Edge 90+

Requirements:

  • CSS Custom Properties support
  • ES6+ JavaScript

Performance

  • Bundle Size: ~15KB minified + gzipped (core components only)
  • Tree-Shakeable: Import only what you need
  • SSR Optimized: Fast server-side rendering
  • Print Optimized: Perfect PDF generation

Contributing

Contributions welcome! Please follow these guidelines:

  1. Add Tests: All new components must have tests
  2. Follow Conventions: Use existing naming patterns
  3. Document: Add JSDoc comments and examples
  4. Keep Components Small: Under 200 lines per file
  5. Use Styled Components: Consistent with existing code

Related Packages

Support

License

MIT


Part of the JSON Resume ecosystem - Open source resume standard used by thousands of developers worldwide.