Migration Guide
This guide helps you migrate from other CSS solutions to PikaCSS. We cover the most popular alternatives and provide practical examples for each.
General Migration Strategy
Regardless of which solution you're migrating from, follow this general approach:
- Install PikaCSS in your project
- Set up configuration (create
pika.config.ts) - Migrate styles incrementally (start with new components, then refactor existing ones)
- Test thoroughly after each component migration
- Remove old dependencies once migration is complete
From Tailwind CSS
Installation
# Install PikaCSS
pnpm add -D @pikacss/unplugin-pikacss
# You can keep Tailwind during migration, or remove it later
# pnpm remove tailwindcssConfiguration Setup
// pika.config.ts
/// <reference path="./src/pika.gen.ts" />
import { defineEngineConfig } from '@pikacss/unplugin-pikacss'
export default defineEngineConfig({
// You can recreate your Tailwind theme here using shortcuts
shortcuts: {
shortcuts: [
// Colors (example)
['text-primary', { color: '#3b82f6' }],
['bg-primary', { backgroundColor: '#3b82f6' }],
// Common utilities
['flex-center', {
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}]
]
}
})Migration Examples
Simple Utilities
Before (Tailwind):
<div class="flex items-center justify-center p-4 bg-blue-500 text-white rounded">
Hello
</div>After (PikaCSS):
<div className={pika({
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
padding: '1rem',
backgroundColor: '#3b82f6',
color: 'white',
borderRadius: '0.25rem'
})}>
Hello
</div>Responsive Design
Before (Tailwind):
<div class="w-full md:w-1/2 lg:w-1/3">
Content
</div>After (PikaCSS):
<div className={pika({
'width': '100%',
'@media (min-width: 768px)': {
width: '50%'
},
'@media (min-width: 1024px)': {
width: '33.333%'
}
})}>
Content
</div>Or create a shortcut:
// pika.config.ts
shortcuts: [
[/^w-full$/, () => ({ width: '100%' })],
[/^md:w-1\/2$/, () => ({ '@media (min-width: 768px)': { width: '50%' } })],
// etc.
]Hover and Focus States
Before (Tailwind):
<button class="bg-blue-500 hover:bg-blue-600 focus:ring-2 focus:ring-blue-300">
Click Me
</button>After (PikaCSS):
<button className={pika({
'backgroundColor': '#3b82f6',
'$:hover': {
backgroundColor: '#2563eb'
},
'$:focus': {
outline: '2px solid #93c5fd'
}
})}>
Click Me
</button>Dark Mode
Before (Tailwind):
<div class="bg-white dark:bg-gray-900 text-black dark:text-white">
Content
</div>After (PikaCSS):
<div className={pika({
'backgroundColor': '#ffffff',
'color': '#000000',
'@media (prefers-color-scheme: dark)': {
backgroundColor: '#111827',
color: '#ffffff'
}
})}>
Content
</div>Tailwind-to-PikaCSS Cheat Sheet
| Tailwind | PikaCSS |
|---|---|
flex | { display: 'flex' } |
items-center | { alignItems: 'center' } |
justify-between | { justifyContent: 'space-between' } |
p-4 | { padding: '1rem' } |
px-4 | { paddingLeft: '1rem', paddingRight: '1rem' } |
py-2 | { paddingTop: '0.5rem', paddingBottom: '0.5rem' } |
m-4 | { margin: '1rem' } |
w-full | { width: '100%' } |
h-screen | { height: '100vh' } |
text-center | { textAlign: 'center' } |
font-bold | { fontWeight: 'bold' } |
text-lg | { fontSize: '1.125rem' } |
rounded | { borderRadius: '0.25rem' } |
shadow | { boxShadow: '0 1px 3px rgba(0,0,0,0.12)' } |
hover:bg-blue-600 | { '$:hover': { backgroundColor: '#2563eb' } } |
From Styled-components
Installation
# Install PikaCSS
pnpm add -D @pikacss/unplugin-pikacss
# You can remove styled-components later
# pnpm remove styled-componentsMigration Examples
Basic Component
Before (Styled-components):
import styled from 'styled-components'
const Button = styled.button`
padding: 0.5rem 1rem;
background-color: #3b82f6;
color: white;
border: none;
border-radius: 0.25rem;
cursor: pointer;
&:hover {
background-color: #2563eb;
}
`
export default function App() {
return <Button>Click Me</Button>
}After (PikaCSS):
function Button({ children }) {
return (
<button className={pika({
'padding': '0.5rem 1rem',
'backgroundColor': '#3b82f6',
'color': 'white',
'border': 'none',
'borderRadius': '0.25rem',
'cursor': 'pointer',
'$:hover': {
backgroundColor: '#2563eb'
}
})}>
{children}
</button>
)
}
export default function App() {
return <Button>Click Me</Button>
}Or use shortcuts for reusability:
// pika.config.ts
shortcuts: [
['btn', {
padding: '0.5rem 1rem',
backgroundColor: '#3b82f6',
color: 'white',
border: 'none',
borderRadius: '0.25rem',
cursor: 'pointer',
'$:hover': {
backgroundColor: '#2563eb'
}
}]
]// Usage
<button className={pika('btn')}>Click Me</button>Props-based Styling
Before (Styled-components):
const Button = styled.button<{ $primary?: boolean }>`
background-color: ${props => props.$primary ? '#3b82f6' : '#6b7280'};
color: white;
`
<Button $primary>Primary</Button>
<Button>Secondary</Button>After (PikaCSS):
Use multiple shortcuts or conditional logic:
function Button({ primary, children }) {
return (
<button className={pika({
backgroundColor: primary ? '#3b82f6' : '#6b7280',
color: 'white'
})}>
{children}
</button>
)
}Wait! ❌ This won't work because PikaCSS evaluates at build time. (See Important Concepts for details)
Correct approach using shortcuts:
// pika.config.ts
shortcuts: [
['btn-base', { color: 'white', padding: '0.5rem 1rem' }],
['btn-primary', { __shortcut: 'btn-base', backgroundColor: '#3b82f6' }],
['btn-secondary', { __shortcut: 'btn-base', backgroundColor: '#6b7280' }]
]function Button({ primary, children }) {
return (
<button className={pika(primary ? 'btn-primary' : 'btn-secondary')}>
{children}
</button>
)
}Theming
Before (Styled-components):
import { ThemeProvider } from 'styled-components'
const theme = {
colors: {
primary: '#3b82f6'
}
}
const Button = styled.button`
background-color: ${props => props.theme.colors.primary};
`
<ThemeProvider theme={theme}>
<Button>Click</Button>
</ThemeProvider>After (PikaCSS with CSS Variables):
// Set CSS variables at root
document.documentElement.style.setProperty('--color-primary', '#3b82f6')
// Use in PikaCSS
<button className={pika({
backgroundColor: 'var(--color-primary)'
})}>
Click
</button>Or define in preflights:
// pika.config.ts
export default defineEngineConfig({
preflights: [
':root { --color-primary: #3b82f6; --color-secondary: #6b7280; }'
]
})From Emotion
Installation
# Install PikaCSS
pnpm add -D @pikacss/unplugin-pikacss
# You can remove Emotion later
# pnpm remove @emotion/react @emotion/styledMigration Examples
css Prop / css Function
Before (Emotion):
import { css } from '@emotion/react'
<div className={css`
display: flex;
padding: 1rem;
background-color: #3b82f6;
&:hover {
background-color: #2563eb;
}
`}>
Content
</div>After (PikaCSS):
<div className={pika({
'display': 'flex',
'padding': '1rem',
'backgroundColor': '#3b82f6',
'$:hover': {
backgroundColor: '#2563eb'
}
})}>
Content
</div>Object Styles
Before (Emotion):
import { css } from '@emotion/react'
<div className={css({
display: 'flex',
padding: '1rem',
backgroundColor: '#3b82f6',
'&:hover': {
backgroundColor: '#2563eb'
}
})}>
Content
</div>After (PikaCSS):
<div className={pika({
'display': 'flex',
'padding': '1rem',
'backgroundColor': '#3b82f6',
'$:hover': { // Use $ instead of &
backgroundColor: '#2563eb'
}
})}>
Content
</div>Key difference: Replace & with $ for selector references.
Style Composition
Before (Emotion):
const baseStyles = css`
padding: 0.5rem;
border-radius: 0.25rem;
`
const primaryStyles = css`
${baseStyles}
background-color: #3b82f6;
color: white;
`After (PikaCSS with shortcuts):
// pika.config.ts
shortcuts: [
['base-styles', {
padding: '0.5rem',
borderRadius: '0.25rem'
}],
['primary-styles', {
__shortcut: 'base-styles',
backgroundColor: '#3b82f6',
color: 'white'
}]
]<button className={pika('primary-styles')}>Click</button>From UnoCSS
Installation
# Install PikaCSS
pnpm add -D @pikacss/unplugin-pikacss
# You can remove UnoCSS later
# pnpm remove unocssMigration Examples
Basic Utilities
Before (UnoCSS):
<div class="flex items-center justify-center p-4 bg-blue-500 text-white">
Hello
</div>After (PikaCSS):
<div className={pika({
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
padding: '1rem',
backgroundColor: '#3b82f6',
color: 'white'
})}>
Hello
</div>Shortcuts
Before (UnoCSS):
// uno.config.ts
shortcuts: {
'btn': 'px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600'
}After (PikaCSS):
// pika.config.ts
shortcuts: [
['btn', {
padding: '0.5rem 1rem',
backgroundColor: '#3b82f6',
color: 'white',
borderRadius: '0.25rem',
'$:hover': {
backgroundColor: '#2563eb'
}
}]
]Dynamic Rules
Before (UnoCSS):
// uno.config.ts
rules: [
[/^m-(\d+)$/, ([, d]) => ({ margin: `${d}px` })]
]After (PikaCSS):
// pika.config.ts
shortcuts: [
[/^m-(\d+)$/, m => ({ margin: `${m[1]}px` }), ['m-4', 'm-8', 'm-16']]
]Common Pitfalls
❌ Runtime Variables
// ❌ This won't work - runtime variable
function Component({ color }) {
return <div className={pika({ color })} />
}
// ✅ Use CSS variables instead
function Component({ color }) {
return (
<div
className={pika({ color: 'var(--dynamic-color)' })}
style={{ '--dynamic-color': color }}
/>
)
}❌ Function Calls
// ❌ This won't work - function call
const getColor = () => '#3b82f6'
<div className={pika({ color: getColor() })} />
// ✅ Use static value
const COLOR = '#3b82f6'
<div className={pika({ color: COLOR })} />❌ Props Interpolation
// ❌ This won't work - props are runtime
<div className={pika({ padding: props.spacing })} />
// ✅ Use predefined shortcuts
const classes = {
small: pika({ padding: '0.5rem' }),
medium: pika({ padding: '1rem' }),
large: pika({ padding: '1.5rem' })
}
<div className={classes[props.size]} />Migration Checklist
- [ ] Install PikaCSS and configure bundler plugin
- [ ] Create
pika.config.tswith initial configuration - [ ] Import
pika.cssin your entry file - [ ] Set up TypeScript references
- [ ] Migrate theme/design tokens to shortcuts or CSS variables
- [ ] Start migrating components (new ones first)
- [ ] Test each migrated component thoroughly
- [ ] Update tests to use new class names
- [ ] Remove old CSS solution dependencies
- [ ] Clean up unused configuration files
- [ ] Update documentation and style guides
Getting Help
If you encounter issues during migration:
- Check the Troubleshooting Guide
- Review Build-Time Constraints
- Search GitHub Issues
- Ask in GitHub Discussions
Next Steps
After migrating:
- Explore Plugin System for icons, reset, typography
- Learn about Shortcuts for reusable styles
- Optimize with Performance Guide
- Share your experience with the community!