Release Date: 2024-11-08 Breaking Changes: Yes (Migration guide included)
Silk v2.0 introduces true zero-runtime CSS-in-TypeScript compilation. CSS is now extracted at build-time via Babel plugin, eliminating all runtime overhead.
Before (v1.x - Runtime):
import { createStyleSystem } from '@sylphx/silk'
const { css } = createStyleSystem(config)
const button = css({ bg: 'blue', px: 4 }) // Runtime CSS generation
// JS Bundle: 152.45 KB
// CSS: Inline or runtime-generatedAfter (v2.0 - Build-time):
import { css } from '@sylphx/silk'
const button = css({ bg: 'blue', px: 4 }) // Transformed to "silk_bg_blue_xxxx silk_px_4_xxxx"
// JS Bundle: 145.98 KB (-6.5KB, -4.3%)
// CSS: 1KB separate file (389B Brotli, -61%)
// Runtime: 0ms (zero overhead!)| Metric | v1.x (Runtime) | v2.0 (Build-time) | Improvement |
|---|---|---|---|
| JS Bundle | 152.45 KB | 145.98 KB | -6.5KB (-4.3%) |
| CSS Size | Inline | 1.00 KB | Extracted |
| CSS (Brotli) | N/A | 389B | -61% compression |
| CSS (Gzip) | N/A | 472B | -53% compression |
| Runtime Cost | 2-3ms per call | 0ms | Zero overhead! |
| Build Time | N/A | ~300ms | Fast compilation |
All framework integrations now use unplugin for cross-bundler support:
- ✅ Vite - Native support via unplugin.vite
- ✅ Webpack - Native support via unplugin.webpack (Next.js)
- ✅ Rollup - Native support via unplugin.rollup
- ✅ esbuild - Native support via unplugin.esbuild
Benefits:
- Single plugin implementation
- Consistent behavior across bundlers
- Better maintainability
- Future-proof architecture
Before (v1.x):
import { createStyleSystem } from '@sylphx/silk'
const { css } = createStyleSystem(config) // Runtime creationAfter (v2.0):
import { css } from '@sylphx/silk' // Direct import (build-time)
const button = css({ bg: 'blue' }) // Transformed by Babelv2.0 requires a build plugin for zero-runtime compilation:
// vite.config.ts
import { defineConfig } from 'vite'
import silk from '@sylphx/silk-vite-plugin'
export default defineConfig({
plugins: [
silk(), // Add Silk plugin
react(),
],
})All framework packages now export Vite plugins:
Before (v1.x):
// No build-time pluginAfter (v2.0):
// packages/{framework}/vite.ts
import { silkPlugin } from '@sylphx/silk-solid/vite'
export default defineConfig({
plugins: [silkPlugin(), solid()]
})New:
- ✅ Build-time
css()export for Babel transformation - ✅ Throws error if called at runtime (enforces build-time usage)
- ✅ All existing APIs maintained
Breaking:
- None (fully backward compatible for runtime usage)
Brand new package for zero-runtime compilation:
bun add @sylphx/silk-vite-pluginFeatures:
- ✅ unplugin-based (Vite, Webpack, Rollup, esbuild)
- ✅ Babel plugin integration
- ✅ CSS extraction
- ✅ Pre-compression (Brotli, Gzip)
- ✅ HMR with state preservation
- ✅ TypeScript support
Babel plugin for build-time CSS transformation:
bun add @sylphx/babel-plugin-silkFeatures:
- ✅ Transforms
css()calls to static class names - ✅ Extracts CSS rules
- ✅ Generates unique hashed class names
- ✅ Pseudo-selector support
- ✅ Production optimizations
All 9 framework packages updated:
| Package | Version | Changes |
|---|---|---|
| @sylphx/silk-react | 1.0.3 → 2.0.0 |
Added zero-runtime documentation |
| @sylphx/silk-nextjs | 2.0.2 → 2.0.3 |
Replaced webpack loader → unplugin |
| @sylphx/silk-remix | 2.0.2 → 2.0.3 |
Added vite.ts export |
| @sylphx/silk-astro | 2.0.2 → 2.0.3 |
Updated to use unplugin |
| @sylphx/silk-solid | 2.0.2 → 2.0.3 |
Added vite.ts export |
| @sylphx/silk-vue | 2.0.2 → 2.0.3 |
Added vite.ts export |
| @sylphx/silk-svelte | 2.0.2 → 2.0.3 |
Added vite.ts export |
| @sylphx/silk-qwik | 2.0.2 → 2.0.3 |
Added vite.ts export |
| @sylphx/silk-preact | 2.0.2 → 2.0.3 |
Added vite.ts export |
# For Vite projects
bun add @sylphx/silk-vite-plugin
# For webpack projects (Next.js uses this automatically)
# No action neededVite:
// vite.config.ts
import { defineConfig } from 'vite'
import silk from '@sylphx/silk-vite-plugin'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [
silk(), // Add BEFORE framework plugin
react(),
],
})Next.js:
// next.config.js
import { withSilk } from '@sylphx/silk-nextjs'
export default withSilk({
// Next.js config
}, {
// Silk options
outputFile: 'silk.css',
babelOptions: {
production: true
}
})Remix:
// vite.config.ts
import { defineConfig } from 'vite'
import { vitePlugin as remix } from '@remix-run/dev'
import { silkPlugin } from '@sylphx/silk-remix/vite'
export default defineConfig({
plugins: [
silkPlugin(), // Add BEFORE Remix
remix(),
],
})Astro:
// astro.config.mjs
import { defineConfig } from 'astro/config'
import silk from '@sylphx/silk-astro'
export default defineConfig({
integrations: [
silk({
outputFile: 'silk.css',
babelOptions: { production: true }
})
]
})Option A: Zero-Runtime (Recommended)
// ✅ v2.0 - Direct import (build-time)
import { css } from '@sylphx/silk'
const button = css({ bg: 'blue', px: 4 })
function Button() {
return <button className={button}>Click</button>
}Option B: Keep Runtime (No changes needed)
// ✅ Still works in v2.0 (runtime)
import { createStyleSystem } from '@sylphx/silk'
const { css } = createStyleSystem(config)
const button = css({ bg: 'blue', px: 4 })Note: Only the direct import { css } pattern benefits from zero-runtime compilation.
Add CSS import to your app entry:
// app/layout.tsx (Next.js App Router)
import './silk.css' // Generated by build plugin
export default function RootLayout({ children }) {
return <html><body>{children}</body></html>
}// app/root.tsx (Remix)
import type { LinksFunction } from '@remix-run/node'
export const links: LinksFunction = () => [
{ rel: 'stylesheet', href: '/silk.css' }
]CSS is now extracted to a separate file during build:
dist/
├── silk.css # 1.00 KB
├── silk.css.br # 389B (Brotli)
├── silk.css.gz # 472B (Gzip)
└── assets/
└── index.js # -6.5KB smallerAutomatic Brotli and Gzip compression:
// vite.config.ts
silk({
compression: {
brotli: true, // Generate .css.br
brotliQuality: 11, // Max quality
gzip: true, // Generate .css.gz
gzipLevel: 9
}
})Hot Module Replacement preserves component state:
# Edit styles
const button = css({ bg: 'green' }) // Changed from 'blue'
# Result:
✅ Button color updates instantly
✅ Component state preserved
✅ No page reloadEvery CSS rule gets a unique hashed class name:
css({ bg: 'blue', p: 4 })
// Generates:
// .silk_bg_blue_ey45 { background-color: blue; }
// .silk_p_4_dozm { padding: 1rem; }Minification:
/* Before */
.silk_bg_blue_ey45 {
background-color: blue;
}
/* After */
.silk_bg_blue_ey45{background-color:blue}Deduplication:
// Multiple calls with same styles
css({ bg: 'blue' }) // → silk_bg_blue_ey45
css({ bg: 'blue' }) // → silk_bg_blue_ey45 (reused!)All frameworks now export dedicated Vite plugins:
// Solid.js
import { silkPlugin } from '@sylphx/silk-solid/vite'
// Vue
import { silkPlugin } from '@sylphx/silk-vue/vite'
// Svelte
import { silkPlugin } from '@sylphx/silk-svelte/vite'
// Qwik
import { silkPlugin } from '@sylphx/silk-qwik/vite'
// Preact
import { silkPlugin } from '@sylphx/silk-preact/vite'interface SilkPluginOptions {
// Output CSS file path
outputFile?: string // default: 'silk.css'
// Minify CSS output
minify?: boolean // default: true in production
// Compression options
compression?: {
brotli?: boolean // default: true
brotliQuality?: number // default: 11 (0-11)
gzip?: boolean // default: true
gzipLevel?: number // default: 9 (0-9)
}
// Babel plugin options
babelOptions?: {
production?: boolean // default: NODE_ENV === 'production'
classPrefix?: string // default: 'silk'
importSources?: string[] // default: ['@sylphx/silk']
}
}import silk from '@sylphx/silk-vite-plugin'
silk({
outputFile: 'styles/silk.css',
minify: true,
compression: {
brotli: true,
brotliQuality: 11
},
babelOptions: {
production: true,
classPrefix: 'app'
}
})- Zero-Runtime Setup - How to configure build-time compilation
- Migration Guide - Step-by-step v1.x → v2.0 migration
- Framework Integration - Updated guides for all 9 frameworks
- Performance Benefits - Detailed benchmarks and metrics
All framework packages have updated documentation:
- @sylphx/silk-react
- @sylphx/silk-nextjs
- @sylphx/silk-remix
- @sylphx/silk-astro
- @sylphx/silk-solid
- @sylphx/silk-vue
- @sylphx/silk-svelte
- @sylphx/silk-qwik
- @sylphx/silk-preact
- Fixed Babel preset loading in production builds
- Fixed lightningcss bundling for browser
- Fixed TypeScript types for unplugin context
- Fixed HMR state preservation
- Fixed CSS extraction timing
None! All issues from Phase 2B testing resolved.
- Webpack standalone plugin (for non-Next.js projects)
- Rollup standalone plugin
- esbuild standalone plugin
- Example apps for all frameworks
- Performance benchmarking suite
- CSS Modules support
- Theme switching at build-time
- Critical CSS extraction improvements
- ESLint plugin for best practices
- VS Code extension
- GitHub Issues: github.com/SylphxAI/silk/issues
- Discussions: github.com/SylphxAI/silk/discussions
- Discord: Coming soon
- Twitter: @sylphx
Special thanks to:
- Meta StyleX - Inspiration for atomic CSS approach
- Panda CSS - Design system patterns
- unplugin - Universal plugin framework
- Babel - Powerful AST transformation
- All contributors - Community feedback and testing
See CHANGELOG.md for detailed changes.
Silk v2.0 - True Zero-Runtime CSS-in-TypeScript 🎨
Faster builds • Smaller bundles • Zero overhead