Documentation

⚠️ Alpha Version Notice:

BoomerCSS is currently in alpha stage and has some important limitations:

  • Not compatible with Turbopack - please use webpack for nextjs or other supported bundlers
  • Macros don't play well with build cache in vercel deployments, you might need to disable it or redeploy manually sometimes
  • Macro functions cannot be used across files - theme, animation, and query values must be defined in the same file as css/styled functions
  • API may change without notice
  • Some features are still experimental

Use with caution in production environments.

Core Concepts

boomerCSS is a zero-runtime CSS-in-TS solution that generates all styles at build time using Parcel macros. It provides a type-safe way to write CSS with support for themes, variants, and responsive designs.

Best Practices

The css Function

The css function is the core building block of boomerCSS. It generates class names for your styles at build time.

Basic Usage

import { css } from '@/libs/boomer' with { type: 'macro' }

const buttonClass = css({
  base: {
    padding: '0.5rem 1rem',
    backgroundColor: 'blue',
    color: 'white',
    borderRadius: '0.25rem'
  }
})

// Usage:
// <button className={buttonClass()}>Click me</button>

With Variants

const buttonWithVariants = css({
  base: {
    padding: '0.5rem 1rem',
    borderRadius: '0.25rem'
  },
  variants: {
    intent: {
      primary: {
        backgroundColor: v('colors.primary'),
        color: 'white'
      },
      secondary: {
        backgroundColor: 'transparent',
        border: `1px solid ${v('colors.primary')}`,
        color: v('colors.primary')
      }
    },
    size: {
      small: { fontSize: '0.875rem' },
      large: { fontSize: '1.125rem' }
    }
  }
})

// Usage:
// <button className={buttonWithVariants({ intent: 'primary', size: 'small' })}>
//   Click me
// </button>

With Media Queries

const responsiveBox = css({
  base: {
    padding: '1rem',
    query: {
      [q('tablet/media (min-width: 768px)')]: {
        padding: '2rem'
      },
      [q('desktop/media (min-width: 1024px)')]: {
        padding: '3rem'
      }
    }
  }
})

The styled Function

The styled function creates React components with built-in styles. It's similar to the css function but returns a component instead of a class name.

const Button = styled('button', {
  base: {
    padding: '0.5rem 1rem',
    borderRadius: '0.25rem',
    backgroundColor: v('colors.primary'),
    color: 'white'
  },
  variants: {
    size: {
      small: { fontSize: '0.875rem' },
      large: { fontSize: '1.125rem' }
    }
  }
})

// Usage:
// <Button $size="small">Click me</Button>

Naming Styles

Both css and styled functions accept an optional name parameter that helps with debugging and DevTools identification.

const buttonClass = css({
  base: {
    padding: '0.5rem 1rem',
    backgroundColor: v('colors.primary'),
    color: 'white'
  }
}, { name: 'Button' }) // This name will appear in the generated class

const StyledButton = styled('button', {
  base: {
    padding: '0.5rem 1rem',
    backgroundColor: v('colors.primary'),
    color: 'white'
  }
}, { name: 'StyledButton' }) // This name will appear in the DOM

Animations with keyframes

Use the keyframes function to create CSS animations. Like other boomerCSS functions, it generates the CSS at build time.

import { keyframes, styled } from '@/libs/boomer' with { type: 'macro' }

const fadeIn = keyframes({
  '0%': {
    opacity: 0
  },
  '100%': {
    opacity: 1
  }
}, 'fadeIn') // Optional name for the animation, if set it will be used in the generated CSS as is. So you can reference it in other files by name.

const FadeInDiv = styled('div', {
  base: {
    animation: `${fadeIn} 0.3s ease-in`,
    query: {
      [q('noAnimation/prefers-reduced-motion: reduce')]: {
        animation: 'none'
      }
    }
  }
})

// More complex example
const flicker = keyframes({
  '0%, 18%, 22%, 25%, 53%, 57%, 100%': {
    textShadow: `
      0 0 7px #3b82f6,
      0 0 10px #3b82f6,
      0 0 21px #3b82f6,
      0 0 42px #8b5cf6,
      0 0 82px #8b5cf6
    `
  },
  '20%, 24%, 55%': {
    textShadow: 'none'
  }
}, 'flicker')

const NeonText = styled('span', {
  base: {
    color: 'white',
    animation: `${flicker} 1.5s infinite alternate`
  }
})

Theme Configuration

Themes are configured using the createConfig function. This sets up your design tokens and media queries.

import { createConfig } from '@/libs/boomer' with { type: 'macro' }

export const { queries, themeTypeForV } = createConfig({
  queries: {
    desktop: 'media (min-width: 1024px)',
    tablet: 'media (min-width: 768px)',
    dark: 'media (prefers-color-scheme: dark)'
  },
  theme: {
    base: {
      colors: {
        primary: '#3b82f6',
        text: '#1a1a1a'
      },
      spacing: {
        sm: '0.5rem',
        md: '1rem'
      }
    },
    dark: {
      colors: {
        text: '#ffffff'
      }
    }
  }
})

Using Theme Values

The v() function accesses theme values, while q() accesses media queries.

While it's not required, it's recommended to use v() and q() functions to access theme values and media queries. Those are statically typed and will be checked at build time for missing declaration.

// Using theme values
const Box = styled('div', {
  base: {
    color: v('colors.text'),
    padding: v('spacing.md'),
    query: {
      [q('dark/media (prefers-color-scheme: dark)')]: {
        backgroundColor: '#000'
      }
    }
  }
})

Global Styles

Use globalCSS to define global styles for your application.

globalCSS({
  '*': {
    margin: 0,
    padding: 0,
    boxSizing: 'border-box'
  },
  'body': {
    backgroundColor: v('colors.background'),
    color: v('colors.text'),
    fontFamily: 'system-ui'
  }
})