Skip to content

Getting Started

This guide walks you through setting up ECSS in a Vite project. The examples use React, but ECSS works with any supported framework — you just need to add the corresponding adapter.

Installation

You'll need three packages: the bundler plugin, the shared config, and the adapter for your framework.

sh
npm i -D @ecss/vite-plugin @ecss/config @ecss/react-adapter
sh
pnpm add -D @ecss/vite-plugin @ecss/config @ecss/react-adapter
sh
yarn add -D @ecss/vite-plugin @ecss/config @ecss/react-adapter

Setting up the plugin

Add the ECSS plugin to vite.config.ts — before the framework plugin:

ts
// vite.config.ts
import ecss from '@ecss/vite-plugin';
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [ecss(), react()],
});

Setting up the adapter

Adapters are defined in ecss.config.ts via defineConfig from @ecss/config. defaultAdapter specifies which adapter is applied to .ecss files by default:

ts
// ecss.config.ts
import { defineConfig } from '@ecss/config';
import { reactAdapter } from '@ecss/react-adapter';

export default defineConfig({
  adapters: [reactAdapter()],
  defaultAdapter: 'react',
});

Setting up TypeScript

During the build, ECSS generates types for each .ecss file in the .ecss/types directory. So that TypeScript picks them up when you import *.ecss, add this directory to rootDirs:

json
// tsconfig.json (or tsconfig.app.json)
{
  "compilerOptions": {
    "rootDirs": [".", "./.ecss/types"]
  }
}

The .ecss/ directory is recreated on every build — add it to .gitignore:

sh
# .gitignore
.ecss

Your first .ecss file

Create src/Button.ecss. Declare an enum of variants, a block with a parameter, and conditional styles:

ecss
/* src/Button.ecss */
@enum Variant {
  values: "primary", "ghost";
}

@block Button {
  @param --variant Variant;

  display: inline-flex;
  padding: 10px 20px;
  border-radius: 6px;
  border: none;
  cursor: pointer;

  @if (--variant == "primary") {
    background: #646cff;
    color: #fff;
  }

  @if (--variant == "ghost") {
    background: transparent;
    color: #646cff;
    border: 1px solid currentColor;
  }
}

Using the component

Import the generated EButton component directly from the .ecss file and pass parameters:

tsx
// src/App.tsx
import { EButton } from './Button.ecss';

export function App() {
  return (
    <EButton as="button" params={{ variant: 'primary' }}>
      Button
    </EButton>
  );
}

Start the dev server — ECSS will compile the .ecss files into static CSS and generate the typed component:

sh
npm run dev
sh
pnpm dev
sh
yarn dev

TypeScript knows the allowed values of variant from the @enum — autocompletion and type checking work right away, and you can't pass a nonexistent variant.

Next steps