Documentation
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
- Always import functions with the macro type declaration
- Use semantic names for variants and theme values
- Leverage the theme system for consistent styling
- Use the css function for reusable styles across different components
- Use the styled function when you need a styled React component
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'
}
})