@sylphx/babel-plugin-silk
v2.0.6
Published
Babel plugin for zero-runtime Silk CSS-in-TypeScript compilation
Readme
@sylphx/babel-plugin-silk
Zero-runtime Babel plugin for Silk CSS-in-TypeScript
Compiles css() calls to static class names at build-time, achieving true zero-runtime overhead.
Features
- ✅ True Zero Runtime for static styles
- ✅ Atomic CSS generation (one class per property)
- ✅ Partial Compilation for mixed static/dynamic styles
- ✅ Production Optimization with short class names
- ✅ Framework Agnostic works with any bundler
Installation
npm install --save-dev @sylphx/babel-plugin-silk
# or
bun add --dev @sylphx/babel-plugin-silkUsage
Babel Configuration
{
"plugins": ["@sylphx/babel-plugin-silk"]
}With Options
{
"plugins": [
[
"@sylphx/babel-plugin-silk",
{
"production": true,
"classPrefix": "",
"importSources": ["@sylphx/silk"]
}
]
]
}How It Works
Static Styles (Full Compilation)
// Input
import { css } from '@sylphx/silk'
const button = css({ bg: 'red', p: 4 })
// Output (Development)
const button = 'silk_bg_red_a7f3 silk_p_4_b2e1'
// Output (Production - optimal compression)
const button = 'ka5tyn p2rk1o'
// Generated CSS (Development)
.silk_bg_red_a7f3 { background-color: red; }
.silk_p_4_b2e1 { padding: 1rem; }
// Generated CSS (Production - minified)
.ka5tyn{background-color:red}.p2rk1o{padding:1rem}Dynamic Styles (Partial Compilation)
// Input
const button = css({ bg: props.color, p: 4 })
// Output
const button = css({ bg: props.color }, 'silk_p_4_b2e1')
// Generated CSS
.silk_p_4_b2e1 { padding: 1rem; }Static properties are extracted at build-time, dynamic properties remain at runtime.
Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| production | boolean | false | Enable production optimizations (6-7 char hashes) |
| classPrefix | string | 'silk' (dev), none (prod) | Class name prefix for branding |
| importSources | string[] | ['@sylphx/silk'] | Import sources to transform |
| functions | string[] | ['css'] | Function names to transform |
Production Class Names
In production mode, class names are optimized for minimal file size using Base-36 hashes:
// No prefix (optimal compression: 6-7 chars)
{ production: true }
// Output: .hgv0lpf, .yfr0d6, .ka5tyn
// Custom prefix (branding support)
{ production: true, classPrefix: 'app' }
// Output: .apphgv0lpf, .appyfr0d6, .appka5tynCSS Identifier Compliance: Leading digits (0-9) are automatically mapped to letters (g-p) to ensure valid CSS identifiers. This maintains optimal compression while guaranteeing 100% browser compatibility.
Integration with Bundlers
Vite
// vite.config.ts
import { defineConfig } from 'vite'
import { transformSync } from '@babel/core'
import babelPluginSilk from '@sylphx/babel-plugin-silk'
export default defineConfig({
plugins: [
{
name: 'vite-plugin-silk',
transform(code, id) {
if (!id.endsWith('.tsx') && !id.endsWith('.ts')) return null
const result = transformSync(code, {
filename: id,
plugins: [babelPluginSilk],
})
// Extract CSS from metadata
const css = result?.metadata?.silk?.cssRules
.map(([_, rule]) => rule)
.join('\n')
return {
code: result?.code,
map: result?.map,
}
},
},
],
})Next.js
// next.config.js
module.exports = {
experimental: {
swcPlugins: [
['@sylphx/babel-plugin-silk', { production: true }]
]
}
}Webpack
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(ts|tsx)$/,
use: {
loader: 'babel-loader',
options: {
plugins: ['@sylphx/babel-plugin-silk']
}
}
}
]
}
}API
Metadata Format
The plugin emits metadata via result.metadata.silk:
interface SilkMetadata {
cssRules: Array<[className: string, cssRule: string]>
classNames: string[]
version: string
}Example
const result = transformSync(code, {
plugins: [babelPluginSilk]
})
// Access generated CSS
const css = result.metadata.silk.cssRules
.map(([_, rule]) => rule)
.join('\n')
// Write to file
fs.writeFileSync('output.css', css)Supported Features
- ✅ Static property values
- ✅ Spread operators (static objects)
- ✅ Property shorthands (
bg,p,m, etc.) - ✅ Spacing units (Tailwind-style:
p: 4→1rem) - ✅ Pseudo-selectors (
_hover,_focus) - ✅ Responsive values (
{ base: '100%', md: '50%' }) - ⏳ Container queries (coming soon)
- ⏳ Variants and recipes (coming soon)
Limitations
- Only transforms
css()calls from configured import sources - Renamed imports not supported (must import as
css) - Dynamic spreads not supported
- Imported style objects require inline definition
Development
# Build
bun run build
# Test
bun test
# Watch mode
bun run devLicense
MIT © SylphX Ltd
