Configuration
PikaCSS configuration has two layers, and confusing them is one of the easiest ways to misread the system.
- Engine config controls how styles are understood and rendered.
- Build plugin options control how the integration finds, transforms, and generates files.
Engine config
Use engine config for things that change styling behavior:
- plugins
- autocomplete
- selectors
- shortcuts
- variables
- keyframes
- layers
- cssImports
- preflights
- prefix and selector defaults
// pika.config.ts
import { defineEngineConfig } from '@pikacss/core'
export default defineEngineConfig({
prefix: 'pika-',
defaultSelector: '.%',
preflights: [
':root { --app-radius: 12px; }',
],
plugins: [],
})// pika.config.ts
import { defineEngineConfig } from '@pikacss/core'
import { fonts } from '@pikacss/plugin-fonts'
import { icons } from '@pikacss/plugin-icons'
import { reset } from '@pikacss/plugin-reset'
export default defineEngineConfig({
plugins: [
reset(),
fonts(),
icons(),
],
prefix: 'pk-',
defaultSelector: '.%',
autocomplete: {
styleItemStrings: ['btn-primary'],
properties: {
variant: ['"solid"', '"ghost"'],
},
patterns: {
selectors: ['screen-${number}'],
},
},
cssImports: [
'@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap");',
],
preflights: [
'*, *::before, *::after { box-sizing: border-box; }',
],
fonts: {
fonts: {
sans: 'Roboto:400,700',
},
},
important: {
default: false,
},
variables: {
variables: {
'--color-bg': '#ffffff',
'--color-text': '#1a1a1a',
'[data-theme="dark"]': {
'--color-bg': '#1a1a1a',
'--color-text': '#ffffff',
},
},
pruneUnused: true,
safeList: ['--color-bg', '--color-text'],
},
keyframes: {
keyframes: [
['fade-in', {
from: { opacity: '0' },
to: { opacity: '1' },
}, ['fade-in 0.3s ease']],
],
pruneUnused: true,
},
selectors: {
selectors: [
['hover', '$:hover'],
['focus', '$:focus'],
['dark', '[data-theme="dark"] $'],
],
},
shortcuts: {
shortcuts: [
['flex-center', {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}],
],
},
})Custom autocomplete
Use autocomplete when your app or design system has stable custom style tokens that do not come from a plugin.
These entries are merged with built-in and external plugin autocomplete, then written into the generated TypeScript types.
// pika.config.ts
import { defineEngineConfig } from '@pikacss/core'
export default defineEngineConfig({
autocomplete: {
styleItemStrings: ['btn-primary', 'btn-secondary'],
extraProperties: ['variant'],
properties: {
variant: ['"solid"', '"ghost"'],
},
patterns: {
selectors: ['screen-${number}'],
styleItemStrings: ['icon-${string}'],
},
},
})Semantic variable autocomplete
Use variables.*.semanticType when a CSS variable represents a stable value family and you want PikaCSS to attach var(--token) only to matching CSS property autocomplete.
Current built-in semantic families with runtime expansion are:
colorlengthtimenumbereasingfont-family
semanticType expands to the built-in property set first, then unions with any explicit autocomplete.asValueOf entries you add for project-specific outliers.
import { defineEngineConfig } from '@pikacss/core'
export default defineEngineConfig({
variables: {
variables: {
// Built-in semantic families scope autocomplete to matching CSS properties.
'--color-primary': {
value: '#3b82f6',
semanticType: 'color',
},
'--space-md': {
value: '16px',
semanticType: 'length',
},
'--motion-fast': {
value: '120ms',
semanticType: 'time',
},
'--layer-popover': {
value: '20',
semanticType: 'number',
},
'--ease-standard': {
value: 'ease-in-out',
semanticType: 'easing',
},
'--font-ui': {
value: 'Inter, sans-serif',
semanticType: 'font-family',
},
// Explicit autocomplete targets still union with semanticType expansion.
'--brand-accent': {
value: '#0ea5e9',
semanticType: 'color',
autocomplete: {
asValueOf: 'scrollbar-color',
},
},
},
pruneUnused: false,
},
})Built-in plugins are configured by top-level keys
This is important because built-in plugin configuration does not live inside plugins.
import { defineEngineConfig } from '@pikacss/core'
export default defineEngineConfig({
important: { default: false },
variables: { variables: {} },
keyframes: { keyframes: [] },
selectors: { selectors: [] },
shortcuts: { shortcuts: [] },
})| Built-in capability | Where to configure it |
|---|---|
| variables | variables |
| keyframes | keyframes |
| selectors | selectors |
| shortcuts | shortcuts |
| important | important |
External plugins go in plugins
import { defineEngineConfig } from '@pikacss/core'
import { fonts } from '@pikacss/plugin-fonts'
import { icons } from '@pikacss/plugin-icons'
import { reset } from '@pikacss/plugin-reset'
import { typography } from '@pikacss/plugin-typography'
export default defineEngineConfig({
plugins: [
reset(),
fonts(),
icons(),
typography(),
],
fonts: {
fonts: {
sans: 'Roboto:400,700',
},
},
})Common misunderstanding
If you put official external plugins such as reset, fonts, icons, or typography under built-in config keys, nothing useful happens. Built-in plugin config and external plugin registration are two different mechanisms.
Build plugin options
Use build plugin options for integration behavior such as scanning, config path resolution, generated file locations, and function name detection.
import type { PluginOptions } from '@pikacss/unplugin-pikacss'
// All options are optional — sensible defaults are provided
const options: PluginOptions = {
// File patterns to scan for pika() calls
scan: {
include: ['**/*.{js,ts,jsx,tsx,vue}'], // default
exclude: ['node_modules/**', 'dist/**'], // default
},
// Engine config: inline object or path to config file
config: './pika.config.ts',
// Auto-create a config file if none exists
autoCreateConfig: true, // default
// The function name to detect in source code
fnName: 'pika', // default
// Output format of generated class names
// - 'string': "pk-a pk-b pk-c"
// - 'array': ['pk-a', 'pk-b', 'pk-c']
transformedFormat: 'string', // default
// TypeScript codegen file for autocomplete support
// - true: generates 'pika.gen.ts'
// - string: custom file path
// - false: disable
tsCodegen: true, // default → 'pika.gen.ts'
// CSS codegen file containing all atomic styles
// - true: generates 'pika.gen.css'
// - string: custom file path
cssCodegen: true, // default → 'pika.gen.css'
}Layers, CSS imports, preflights, and ordering
For larger systems, layer control matters because it makes output order intentional instead of accidental.
Use cssImports when you need top-level @import rules to stay ahead of layered preflights and generated utilities. This is the config-level equivalent of engine.appendCssImport().
import { defineEngineConfig } from '@pikacss/core'
export default defineEngineConfig({
// Add a 'components' layer between preflights and utilities
layers: {
base: 0,
components: 5,
utilities: 10,
},
// Unlayered preflights go into 'base' instead of the default 'preflights'
defaultPreflightsLayer: 'base',
// Unlayered atomic styles go into 'utilities' (this is the default)
defaultUtilitiesLayer: 'utilities',
})import { defineEngineConfig } from '@pikacss/core'
export default defineEngineConfig({
cssImports: [
'@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap");',
'@import url("https://cdn.example.com/theme.css");',
],
preflights: [
':root { font-family: "Inter", system-ui, sans-serif; }',
],
})import { defineEngineConfig } from '@pikacss/core'
export default defineEngineConfig({
layers: {
reset: 0,
base: 1,
utilities: 10,
},
preflights: [
// WithLayer + CSS string
{
layer: 'reset',
preflight: '*, *::before, *::after { box-sizing: border-box; }',
},
// WithLayer + preflight definition object
{
layer: 'base',
preflight: {
':root': {
fontSize: '16px',
lineHeight: '1.5',
},
},
},
// WithLayer + dynamic function
{
layer: 'base',
preflight: (engine) => {
const prefix = engine.config.prefix
return `/* Engine prefix: ${prefix} */`
},
},
],
})Type helpers
PikaCSS exports identity helpers that improve autocomplete and document intent.
defineEngineConfig()defineStyleDefinition()defineSelector()defineShortcut()defineKeyframes()defineVariables()defineEnginePlugin()
import { defineStyleDefinition } from '@pikacss/core'
// defineStyleDefinition() is a type-safe identity helper for style definition objects.
// Use it when you want to define a reusable style object outside of a pika() call,
// with full TypeScript autocomplete and type checking.
const buttonBase = defineStyleDefinition({
padding: '0.5rem 1rem',
borderRadius: '0.25rem',
cursor: 'pointer',
border: 'none',
fontSize: '1rem',
})
// Pass the typed definition directly to pika()
const cls = pika(buttonBase)What most teams should standardize
- shared selectors
- token variables
- shortcut naming
- plugin usage
- layer strategy
- ESLint enforcement for static inputs