Skip to content

rawstylecss/rawstyle

Repository files navigation

logo
A lightweight compile-time CSS-in-JS library for React apps

npm version  runtime size  license  bugs

Features  •  Quick Start  •  Setup  •  Usage  •  API  •  Ecosystem

demo

🔥 Features

  • ⚡ True Zero Runtime: styles are extracted at compile-time, no JS in production
  • 💎 Native CSS: write regular CSS with all modern features
  • 📦 Modern Bundlers: built-in support for Next.js (Turbopack) and Vite (Rolldown)
  • 🔥 Hot Reload: instant CSS updates during development
  • 🌐 Global Types: eliminate the need to import css in every module
  • 🧩 VS Code Extension: syntax highlighting, validation, autocompletion, tooltips, and more
  • 🧹 ESLint Plugin: auto-fixable formatting rules for CSS inside templates

🚀 Quick Start

No need to read further, just try it out:

pnpm create rawstyle  # scaffold a demo project for your chosen platform

⚙️ Setup

  1. Install the сore and the appropriate bundler plugin:
pnpm add -D rawstyle @rawstyle/next  # for Next.js
pnpm add -D rawstyle @rawstyle/vite  # for Vite
  1. Configure the bundler to use the plugin:

Next.js (Turbopack)

// next.config.ts
import { rawstyleTurboRule } from '@rawstyle/next'
import type { NextConfig } from 'next'

export default {
	turbopack: { rules: { ...rawstyleTurboRule } },
} satisfies NextConfig

The loader extracts CSS and injects it into the module as a base64-encoded CSS import.

Vite (Rolldown)

// vite.config.ts
import react from '@vitejs/plugin-react'
import rawstyle from '@rawstyle/vite'
import type { UserConfig } from 'rolldown-vite'

export default {
	plugins: [react(), rawstyle()],
} satisfies UserConfig

The plugin emits a virtual .css module containing extracted styles and imports it as a side effect.

🕹️ Usage

Import-based

import { css, gcss, cn } from 'rawstyle'

Global types (recommended)

You can make the css, gcss, and cn type declarations global to avoid importing them in every module:

// via tsconfig.json:
"compilerOptions": {
	"types": ["rawstyle/globals"]
}
// or add this to your global.d.ts:
import 'rawstyle/globals'
// or
/// <reference types="rawstyle/globals" />

🧩 API

Rawstyle provides three core primitives: css, gcss, and cn:

// src/module.tsx
export const Component = ({ theme }: { theme: string }) => (
	// cn - class names merging utility
	<div className={cn('common', theme === 'dark' && card)}>
		Hello, World!
	</div>
)
// css - define scoped CSS
const card = css`
	padding: 1rem;
	color: var(--primary);
	&:hover { box-shadow: 0 4px 12px black; }
`
// gcss - define global CSS
void gcss`
	:root { --primary: #303030; }
	body { margin: 0; background: #ebebeb; }
`

This code compiles to:

import '\0virtual.css'

export const Component = ({ theme }: { theme: string }) => (
	<div className={['common', theme === 'dark' && 'card_hash5'].filter(Boolean).join(' ')}>
		Hello, World!
	</div>
)

As you can see, the card variable is replaced with a hashed class name, cn is transformed into a conditional string joiner, and the CSS is extracted into a separate virtual .css file:

/* virtual.css */
:root { --primary: #303030; }
body { margin: 0; background: #ebebeb; }

.card_hash5 {
	padding: 1rem;
	color: var(--primary);
	&:hover { box-shadow: 0 4px 12px black; }
}

🧩 Ecosystem

Rawstyle provides a suite of tools to enhance your development experience:


MIT License © 2026 Rawstyle