Claude Skills Guide

Claude Code Vanilla Extract Type Safe CSS

Type-safe CSS has become essential for maintainable frontend development, especially when building complex Claude skills that require reliable styling. Vanilla Extract provides a zero-runtime approach to CSS-in-TypeScript that integrates smoothly with modern build tools and Claude Code workflows.

What Makes Vanilla Extract Different

Unlike traditional CSS-in-JS solutions that inject styles at runtime, Vanilla Extract generates static CSS files at build time. This approach eliminates runtime overhead and provides complete type safety through TypeScript’s type system. When you use Vanilla Extract, every class name, variable, and theme value gets validated during development, catching errors before they reach production.

The library works by defining styles in .css.ts files using typed JavaScript objects. These definitions then compile to atomic CSS classes that you apply to your components. The compilation process happens during your build step, making it compatible with any framework or vanilla JavaScript project.

Setting Up Vanilla Extract

To get started with Vanilla Extract in a Claude Code project, install the necessary dependencies:

npm install @vanilla-extract/css @vanilla-extract/vite-plugin

Configure the Vite plugin in your vite.config.ts:

import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [vanillaExtractPlugin()]
});

This setup enables TypeScript to understand your Vanilla Extract style definitions while generating optimized CSS output.

Creating Type-Safe Styles

Define your styles using the style function from Vanilla Extract:

import { style } from '@vanilla-extract/css';

export const container = style({
  padding: '24px',
  backgroundColor: '#f5f5f5',
  borderRadius: '8px',
  maxWidth: '800px',
  margin: '0 auto'
});

export const heading = style({
  fontSize: '2rem',
  fontWeight: '600',
  color: '#333',
  marginBottom: '16px'
});

export const button = style({
  padding: '12px 24px',
  backgroundColor: '#0070f3',
  color: 'white',
  border: 'none',
  borderRadius: '6px',
  cursor: 'pointer',
  fontSize: '1rem',
  transition: 'background-color 0.2s ease',
  ':hover': {
    backgroundColor: '#0051a2'
  }
});

Every property in these style objects gets full TypeScript support. Mistyping a CSS property or using an invalid value triggers immediate type errors in your editor.

Using Themes for Consistent Design

Vanilla Extract’s theme system helps maintain design consistency across your skill’s interface. Define themes in a dedicated file:

import { createTheme, style } from '@vanilla-extract/css';

export const [themeClass, vars] = createTheme({
  color: {
    primary: '#0070f3',
    secondary: '#5856d6',
    background: '#ffffff',
    text: '#1d1d1f'
  },
  spacing: {
    small: '8px',
    medium: '16px',
    large: '24px'
  },
  font: {
    body: '-apple-system, BlinkMacSystemFont, sans-serif',
    mono: 'Monaco, monospace'
  }
});

Apply the theme class to your container and reference theme variables in your styles:

import { style } from '@vanilla-extract/css';
import { vars } from './theme.css';

export const themedContainer = style({
  backgroundColor: vars.color.background,
  color: vars.color.text,
  fontFamily: vars.font.body,
  padding: vars.spacing.large
});

When you need multiple themes, such as light and dark mode, create variant themes:

import { createThemeContract } from '@vanilla-extract/css';

export const contract = createThemeContract({
  color: {
    background: null,
    text: null
  }
});

export const lightTheme = createTheme(contract, {
  color: {
    background: '#ffffff',
    text: '#1d1d1f'
  }
});

export const darkTheme = createTheme(contract, {
  color: {
    background: '#1d1d1f',
    text: '#ffffff'
  }
});

Integrating with Claude Skills

When building Claude skills that include frontend components, using Vanilla Extract provides confidence in your styling code. The type checking catches mistakes immediately, which proves valuable when iterating quickly on skill prototypes. Combined with the frontend-design skill for layout assistance and the pdf skill for generating styled documentation, you can maintain consistency across all output formats.

For skills that require responsive design, define breakpoints as theme variables:

import { style, globalStyle } from '@vanilla-extract/css';
import { vars } from './theme.css';

export const responsiveContainer = style({
  padding: vars.spacing.medium,
  '@media': {
    'screen and (min-width: 768px)': {
      padding: vars.spacing.large,
      maxWidth: '960px'
    }
  }
});

Global styles work similarly for reset rules and base typography:

import { globalStyle } from '@vanilla-extract/css';

globalStyle('body', {
  margin: 0,
  padding: 0,
  fontFamily: vars.font.body,
  lineHeight: 1.5
});

globalStyle('*, *::before, *::after', {
  boxSizing: 'border-box'
});

Advanced Patterns

Vanilla Extract supports complex patterns like recipe systems for compound component styles. The recipe system helps when building interactive components with multiple states:

import { recipe } from '@vanilla-extract/recipes';

export const buttonRecipe = recipe({
  base: {
    padding: '12px 24px',
    borderRadius: '6px',
    fontSize: '1rem',
    cursor: 'pointer'
  },
  variants: {
    variant: {
      primary: { backgroundColor: vars.color.primary, color: 'white' },
      secondary: { backgroundColor: 'transparent', border: '1px solid #ccc' }
    },
    size: {
      small: { padding: '8px 16px', fontSize: '0.875rem' },
      large: { padding: '16px 32px', fontSize: '1.125rem' }
    }
  },
  defaultVariants: {
    variant: 'primary',
    size: 'small'
  }
});

Apply these recipes with variant props:

// Generates appropriate class names for primary small button
const className = buttonRecipe({ variant: 'primary', size: 'small' });

Performance Benefits

Vanilla Extract generates minimal, deduplicated CSS. Unlike runtime CSS-in-JS libraries that add JavaScript bundle size, Vanilla Extract produces plain CSS files that browsers optimize efficiently. Your skill loads faster because there’s no runtime style injection overhead.

The static output also means better caching. Users downloading your skill’s styles benefit from browser cache hits on unchanged CSS files.

Debugging and Development

During development, enable debug class names to understand generated styles:

import { setGlobalMode } from '@vanilla-extract/css';

setGlobalMode('debug');

This adds readable suffixes to generated class names, making browser DevTools inspection straightforward. When you’re ready for production, remove this setting for compressed output.

Vanilla Extract integrates with standard debugging workflows. The supermemory skill can help track styling decisions across skill iterations, while the tdd skill assists in writing tests for component behavior that depends on your styled elements.

Getting Started

Begin by adding Vanilla Extract to an existing project or creating a fresh skill with the library from the start. The type safety immediately shows value when refactoring components or updating design tokens across your codebase.

The initial setup requires minimal configuration, and the learning curve stays low if you already know TypeScript. Start with simple component styles, then gradually adopt themes and recipes as your skill grows in complexity.

Built by theluckystrike — More at zovo.one