First Pika
After installing the build plugin and importing pika.css, you can start writing styles with pika(...).
Prerequisites
Make sure you have already:
- Installed
@pikacss/unplugin-pikacssand registered the plugin in your bundler config. - Imported
pika.cssin your application entry point.
import { createApp } from 'vue'
import App from './App.vue'
// src/main.ts
import 'pika.css' // Import the generated CSS
createApp(App)
.mount('#app')A minimal first example
pika() is a global function that accepts style objects with camelCase CSS properties. It returns class name(s) that you can bind to elements.
Global Function — No Import Needed
pika() is registered as a global function by the build plugin. You do not need to import it — just use it directly in any source file. The build plugin finds all pika() calls via static analysis and replaces them with generated class names at build time. The pika.gen.ts file provides TypeScript type declarations (via declare global) for editor autocomplete, but it is not a module you import from.
<template>
<button
:class="pika({
padding: '0.5rem 1rem',
borderRadius: '0.5rem',
backgroundColor: '#0ea5e9',
color: 'white',
border: 'none',
cursor: 'pointer',
fontSize: '1rem',
})"
>
Hello PikaCSS
</button>
</template>// In vanilla JS/TS, pika() is a global function
// available after setting up the build plugin.
const className = pika({
padding: '0.5rem 1rem',
borderRadius: '0.5rem',
backgroundColor: '#0ea5e9',
color: 'white',
border: 'none',
cursor: 'pointer',
fontSize: '1rem',
})
// Use the returned class name(s) on any DOM element
document.querySelector('#my-button')!.className = classNameWhat happens at build time
PikaCSS works entirely at build time — there is zero runtime overhead. When you run your build, PikaCSS:
- Scans your source files for
pika(...)calls. - Analyzes the style objects statically (arguments must be analyzable at build time).
- Generates atomic CSS classes — each CSS property-value pair becomes its own class.
- Replaces every
pika(...)call with the resulting class name string(s). - Writes the atomic CSS rules into the generated stylesheet (
pika.gen.css).
Source vs. compiled output
Your pika() call in source code:
<template>
<button
:class="pika({
padding: '0.5rem 1rem',
borderRadius: '0.5rem',
backgroundColor: '#0ea5e9',
color: 'white',
border: 'none',
cursor: 'pointer',
fontSize: '1rem',
})"
>
Hello PikaCSS
</button>
</template>Gets compiled to static class names in the output:
<!-- After build, pika() calls are replaced with class name strings -->
<button class="a b c d e f g">
Hello PikaCSS
</button>And the generated pika.gen.css contains one atomic rule per property:
/* Each CSS property becomes its own atomic class */
.a {
padding: 0.5rem 1rem;
}
.b {
border-radius: 0.5rem;
}
.c {
background-color: #0ea5e9;
}
.d {
color: white;
}
.e {
border: none;
}
.f {
cursor: pointer;
}
.g {
font-size: 1rem;
}Why atomic CSS?
Each CSS property-value pair is extracted to a single, reusable class. If another element uses color: 'white', it will share the same .d class. This deduplication keeps the stylesheet small as your app grows.
Nested selectors
Style objects support nested selectors for pseudo-classes, media queries, and custom selectors. Nest them as keys in the style object — PikaCSS compiles each nested property to its own atomic class.
<template>
<button
:class="pika({
'padding': '0.5em 1em',
'borderRadius': '0.25em',
'border': 'none',
'backgroundColor': '#0ea5e9',
'color': 'white',
'cursor': 'pointer',
'transition': 'transform 0.2s ease',
':hover': {
transform: 'scale(1.05)',
},
':active': {
transform: 'scale(0.95)',
},
})"
>
Hover me
</button>
</template>This produces the following atomic CSS:
/* Base styles become atomic classes */
.a {
padding: 0.5em 1em;
}
.b {
border-radius: 0.25em;
}
.c {
border: none;
}
.d {
background-color: #0ea5e9;
}
.e {
color: white;
}
.f {
cursor: pointer;
}
.g {
transition: transform 0.2s ease;
}
/* Pseudo-selectors also become atomic classes */
.h:hover {
transform: scale(1.05);
}
.i:active {
transform: scale(0.95);
}Multiple arguments
pika() accepts multiple arguments (each is a StyleItem). An argument may be a style object or a string (for shortcuts defined in your config). They are merged in order:
<template>
<!-- pika() accepts multiple arguments (StyleItem[]) -->
<!-- Each argument can be a string (shortcut) or a style object -->
<div
:class="pika(
'my-shortcut',
{
fontSize: '1.5rem',
color: '#333',
},
)"
>
Combining shortcuts and inline styles
</div>
</template>Output format variants
By default, pika() returns a space-separated string of class names (e.g. "a b c"). It also exposes variants for different output formats:
// pika() - Default output format (configured by integration, usually string)
const classes = pika({ color: 'red', fontSize: '1rem' })
// => "a b" (string of space-separated class names)
// pika.str() - Force string output
const str = pika.str({ color: 'red', fontSize: '1rem' })
// => "a b"
// pika.arr() - Force array output
const arr = pika.arr({ color: 'red', fontSize: '1rem' })
// => ["a", "b"]| Variant | Return type | Use case |
|---|---|---|
pika() | Configured | Default (usually string) |
pika.str() | string | Force space-separated string |
pika.arr() | string[] | Force array of class names |
IDE preview with pikap
pikap is a preview variant of pika. It has the same API, but provides CSS preview tooltips directly in your IDE. Use pikap during development to see the generated CSS without running a build.
Configuration (optional)
PikaCSS works with zero configuration, but you can create a pika.config.ts (or .js, .mjs, .mts, .cjs, .cts) to customize behavior. Use the defineEngineConfig() helper for full TypeScript autocomplete:
// pika.config.ts
import { defineEngineConfig } from '@pikacss/unplugin-pikacss'
export default defineEngineConfig({
// Prefix for generated class names (default: '')
prefix: '',
// Selector pattern, '%' is replaced with the class ID (default: '.%')
defaultSelector: '.%',
// Plugins to extend functionality
plugins: [],
// Global CSS injected before atomic styles
preflights: [],
})The config file is auto-detected by the plugin. See Configuration for all available options.
Why this matters
You keep a CSS-in-JS authoring experience — standard CSS properties, TypeScript autocomplete, object composition — while shipping static CSS output with no runtime style generation overhead.
Next
- Build-time Compile — understand the compile strategy in detail
- Configuration — customize selectors, shortcuts, variables, and more
- Built-in Plugins — learn about the plugin system