Version 0.2.0 released! Check out the release notes from GitHub Releases

Install @salty-css/react Plus the Vite or Webpack Plugin — Ten Minutes From Empty Repo to First Style

Install Salty CSS in a Vite or Webpack React App

The fastest way to start in any framework:

npx salty-css init

The init command detects your framework, installs the right packages, creates salty.config.ts, and wires the build plugin into your existing bundler config. For most projects that's all you need.

For a manual install on React, run:

npm i @salty-css/react

React + Vite

  1. In your existing Vite repository you can run npx salty-css init to automatically configure Salty CSS.
  2. Create your first Salty CSS component with npx salty-css generate [filePath] (e.g. src/custom-wrapper).
  3. Import your component for example to main.tsx and see it working!

Manual configuration — Vite

  1. Install the Vite plugin and the core package:
    npm i @salty-css/vite @salty-css/core
  2. In vite.config.ts import the plugin and register it:
    import { saltyPlugin } from "@salty-css/vite";
    
    export default defineConfig({
      plugins: [saltyPlugin(__dirname)],
    });
  3. Make sure that salty.config.ts and vite.config.ts are in the same folder.
  4. Build the saltygen directory by running your app once or via the CLI: npx salty-css build [directory].
  5. Import global styles from saltygen/index.css in your app entry: @import 'insert_path_to_index_css';.

Manual configuration — Webpack

If you have a hand-rolled React + Webpack project (CRA eject, custom config, Rspack via the webpack-compatible API, etc.), wire Salty CSS in directly. If you're on Next.js, use the Next.js setup instead — withSaltyCss already wraps Webpack for you.

  1. Install the Webpack plugin and the runtime packages:
    npm i @salty-css/webpack @salty-css/core @salty-css/react
  2. In webpack.config.js import the plugin and apply it to your config object:
    const { saltyPlugin } = require("@salty-css/webpack");
    
    const config = {
      // your existing webpack config
    };
    
    saltyPlugin(config, __dirname);
    
    module.exports = config;
    saltyPlugin mutates the config object in place — it pushes the Salty loader rule for *.css.ts / *.salty.ts / *.styled.ts / *.styles.ts files and registers the compiler hook that generates saltygen/ on build start.
  3. Create salty.config.ts in the same folder as webpack.config.js:
    import { defineConfig } from "@salty-css/core/config";
    
    export const config = defineConfig({
      // Add variables, templates, modifiers as you grow.
    });
  4. Build the saltygen directory by running your app once or via the CLI: npx salty-css build [directory].
  5. Import global styles from saltygen/index.css in a global CSS file that's loaded at your app entry: @import 'insert_path_to_index_css';.

Manual setup

If salty-css init picks the wrong framework, can't find your bundler config, or you'd rather wire things up by hand, follow the manual setup for your stack. The framework-specific snippet above includes the precise commands and config edits; the steps below are the universal shape.

  1. Install the packages. Each framework needs its runtime plus the core compiler:

    • Next.js: npm i @salty-css/next @salty-css/core @salty-css/react
    • React + Vite: npm i @salty-css/vite @salty-css/core @salty-css/react
    • React + Webpack: npm i @salty-css/webpack @salty-css/core @salty-css/react
    • Astro: npm i @salty-css/astro @salty-css/core
  2. Wire the bundler plugin. withSaltyCss(nextConfig) for Next.js, saltyPlugin(__dirname) for Vite, saltyPlugin(config, __dirname) in webpack.config.js for Webpack, the integration for Astro.

  3. Create salty.config.ts in the same directory as your bundler config (e.g. next to next.config.ts or vite.config.ts):

    import { defineConfig } from "@salty-css/react/config";
    
    export const config = defineConfig({
      // Add variables, templates, modifiers as you grow.
    });
  4. Import the generated stylesheet. With the default importStrategy: 'root', Salty CSS expects one stylesheet to be imported at your app root. Most framework plugins do this for you on first run; if not, add @import "../saltygen/index.css"; (or the appropriate path) to your global CSS.

  5. Build once. Run your dev server (or npx salty-css build) so saltygen/ exists before the first render.

Peer dependencies

You'll need:

PackageVersionNotes
node18 or newerRequired for the build pipeline (esbuild + ESM).
typescript5.xNeeded because .css.ts files are evaluated through TypeScript.
react18 or 19 (when using React/Next)The @salty-css/react runtime targets modern React.
next13 (App Router) or newer; tested through 16.2For @salty-css/next. Webpack and Turbopack both work via withSaltyCss.
vite5 or newerFor @salty-css/vite.
astro4 or newerFor @salty-css/astro.

The exact ranges live in each package's peerDependencies — check package.json if you're on a fringe version.

Verify your install

After running the dev server (or npx salty-css build), confirm:

  1. saltygen/ exists at the root of the package you initialised. It should contain at least index.css and a salty.config.js snapshot.
  2. saltygen/index.css is non-empty. A few @layer declarations and your reset should be there even before you write any components.
  3. A test component renders styled. Create a *.css.ts file with a tiny styled component, use it on a page, and inspect the element in DevTools — you should see a class like s_xxxx and a matching rule in the Styles panel.
  4. No build warnings about missing plugin. Salty CSS logs a warning at build time if the plugin didn't load — search your terminal output for salty-css.

If any step fails, jump to Troubleshooting.

The compiler can't warn you about two common structural mistakes: unexported styled calls, and variants accidentally nested inside base instead of alongside it. The ESLint plugin catches both — worth setting up once.