npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

css-typed-vars

v0.4.2

Published

Generate TypeScript typed constants from CSS custom properties

Readme



var(--color-primary) is just a string. Rename the variable — the error shows up only in the browser.

css-typed-vars scans your CSS files and gives you typed constants. Use cssVars.colorPrimary instead — TypeScript catches missing variables at compile time.

Installation

npm install -D css-typed-vars

Two approaches

| | CLI | Plugin | |---|---|---| | How it works | Generates cssVars.ts in your project | Virtual module, no file generated | | Import | import { cssVars } from './cssVars' | import { cssVars } from 'css-typed-vars/vars' | | Watch | --watch flag | vite dev, browser reloads automatically | | Works with | Everything | Vite, webpack, Rollup, esbuild (not Turbopack) |


CLI

Create a config file in your project root:

// css-typed-vars.config.js
export default {
  input: 'src/styles/**/*.{css,scss}',
  output: 'src/cssVars.ts',
};

Then run:

npx css-typed-vars         # generate once
npx css-typed-vars --watch # watch for changes

Add to your package.json scripts:

{
  "scripts": {
    "generate:vars": "css-typed-vars",
    "generate:vars:watch": "css-typed-vars --watch"
  }
}

Given this CSS:

:root {
  --color-primary: #3b82f6;
  --spacing-md: 8px;
}

Generates src/cssVars.ts:

// generated — do not edit
export const cssVars = {
  colorPrimary: 'var(--color-primary)',
  spacingMd: 'var(--spacing-md)',
} as const;

export type CssVarName = keyof typeof cssVars;

CLI flags

npx css-typed-vars --input "src/styles/**/*.css" --output src/cssVars.ts
npx css-typed-vars --input "src/styles/**/*.{css,scss}" --output src/cssVars.ts --watch
npx css-typed-vars --input "src/**/*.css" --output src/cssVars.ts --exclude "**/vendor/**"
npx css-typed-vars --input "src/**/*.css" --output src/cssVars.ts --prefix theme --naming snake
npx css-typed-vars --input "src/**/*.css" --output src/cssVars.js  # generates .js + .d.ts
npx css-typed-vars --input "src/**/*.css" --output src/cssVars.ts --selector ".dark"

| Flag | Description | |------|-------------| | --input | Glob pattern for CSS/SCSS/Less files | | --output | Output file. .ts → TypeScript, .js → JavaScript + .d.ts alongside | | --exclude | Glob pattern for files to exclude (single value; use config file for multiple) | | --prefix | Prefix for generated keys: --prefix themethemeColorPrimary | | --naming | Key naming: camelCase (default), snake, kebab | | --selector | Extra CSS selector to scan for variables (single value; use config file for multiple) | | --watch | Watch for file changes and regenerate | | --version, -v | Print the version number and exit |

CLI flags override values from the config file.

Config file

The CLI looks for a config file in the current working directory (in order):

  1. css-typed-vars.config.js
  2. css-typed-vars.config.mjs
  3. css-typed-vars.config.json

All options are supported in the config file:

// css-typed-vars.config.js
export default {
  input: 'src/styles/**/*.{css,scss}',
  output: 'src/cssVars.ts',
  exclude: ['**/vendor/**', '**/node_modules/**'],
  prefix: 'theme',
  naming: 'snake', // 'camelCase' | 'snake' | 'kebab'
  selectors: ['.dark', '[data-theme="dark"]'],
};

Plugin

No file is generated — CSS variables are served as a virtual module directly by your bundler. Import from css-typed-vars/vars in your source code.

TypeScript types are written to node_modules/css-typed-vars/dist/generated.d.ts automatically on each build or dev server start.

Vite

// vite.config.ts
import { defineConfig } from 'vite';
import cssTypedVars from 'css-typed-vars/vite';

export default defineConfig({
  plugins: [
    cssTypedVars({ input: 'src/styles/**/*.{css,scss}' }),
  ],
});
// src/index.ts
import { cssVars } from 'css-typed-vars/vars';

webpack

// webpack.config.js
import cssTypedVars from 'css-typed-vars/webpack';

export default {
  plugins: [cssTypedVars({ input: 'src/styles/**/*.{css,scss}' })],
};

Rollup

// rollup.config.js
import cssTypedVars from 'css-typed-vars/rollup';

export default {
  plugins: [cssTypedVars({ input: 'src/styles/**/*.{css,scss}' })],
};

esbuild

import cssTypedVars from 'css-typed-vars/esbuild';

await esbuild.build({
  plugins: [cssTypedVars({ input: 'src/styles/**/*.{css,scss}' })],
});

Next.js (webpack)

// next.config.js
const cssTypedVars = require('css-typed-vars/webpack');

module.exports = {
  webpack(config) {
    config.plugins.push(cssTypedVars({ input: 'styles/**/*.{css,scss}' }));
    return config;
  },
};

Turbopack

Turbopack does not yet have a public plugin API for virtual modules. Use the CLI instead:

{
  "scripts": {
    "dev": "css-typed-vars && next dev --turbo",
    "build": "css-typed-vars && next build"
  }
}

Plugin options

| Option | Type | Default | Description | |--------|------|---------|-------------| | input | string \| string[] | — | Glob pattern for CSS/SCSS/Less files | | exclude | string \| string[] | — | Glob pattern(s) for files to exclude | | prefix | string | — | Prefix for generated keys: 'theme'themeColorPrimary | | naming | 'camelCase' \| 'snake' \| 'kebab' | 'camelCase' | Key naming convention | | selectors | string[] | — | Extra CSS selectors to scan, e.g. ['.dark', '[data-theme="dark"]'] | | dts | string \| false | inside node_modules | Path to write type declarations. false to skip |


Usage

React:

import { cssVars } from './cssVars'; // CLI
// or
import { cssVars } from 'css-typed-vars/vars'; // plugin

<div style={{ color: cssVars.colorPrimary, padding: cssVars.spacingMd }} />

styled-components / emotion:

const Button = styled.button`
  color: ${cssVars.colorPrimary};
  padding: ${cssVars.spacingMd};
`;

Vue:

<div :style="{ color: cssVars.colorPrimary }" />

Svelte:

<div style:color={cssVars.colorPrimary} />

Tailwind arbitrary values:

<div className={`text-[${cssVars.colorPrimary}]`} />

Programmatic API

import { generate } from 'css-typed-vars';

await generate({
  input: 'src/styles/**/*.{css,scss}',
  output: 'src/cssVars.ts',  // or 'src/cssVars.js' → generates .js + .d.ts
  exclude: ['**/vendor/**'],
  prefix: 'theme',
  naming: 'snake',           // 'camelCase' | 'snake' | 'kebab'
  selectors: ['.dark', '[data-theme="dark"]'],
});

Lower-level exports:

import { parseVarNames, generateCode, scanVarNames } from 'css-typed-vars';

Supported formats

| Format | Extension | |--------|-----------| | CSS | .css | | SCSS | .scss | | Less | .less |

By default, variables are scanned from :root {} blocks (including attribute selectors like :root[data-theme="dark"]). Use the selectors option to also pick up variables from other selectors such as .dark or [data-theme="dark"].

Contributing

Contributions are welcome. Please open an issue before submitting a pull request.

git clone https://github.com/StanislavKozachenko/css-typed-vars.git
cd css-typed-vars
npm install
npm test

License

MIT