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 🙏

© 2025 – Pkg Stats / Ryan Hefner

css-modules-dts-loader

v1.5.0

Published

A Webpack loader that generates TypeScript declaration files (.d.ts) for CSS modules.

Downloads

715

Readme

css-modules-dts-loader

npm npm license

A Rspack and Webpack loader for generating TypeScript declaration files (.d.ts) for CSS Modules.

Overview

css-modules-dts-loader automatically generates (or verifies) .d.ts files from your CSS Modules. By parsing the CSS module output, it extracts class names, applies optional transformations (matching css-loader's behavior), and produces corresponding TypeScript declaration files. This enhances type safety and improves the developer experience when using CSS Modules in TypeScript projects.

Features

  • Automatic Declaration Generation: Creates .d.ts files alongside your CSS files.
  • css-loader v7 Compatible: Fully supports css-loader's exportLocalsConvention option.
  • Named Exports Support: Generates named exports or interface-based exports.
  • JavaScript Keywords Handling: Properly handles reserved keywords as class names using aliased exports for full type safety.
  • Verification Mode: Checks if existing declaration files are up-to-date (perfect for CI/CD).
  • Customizable Formatting: Choose quote style, indentation (tabs or spaces), and sorting.
  • Seamless Integration: Works with Webpack 5+ and Rspack.

Installation

Install via npm:

npm install --save-dev css-modules-dts-loader

Or with pnpm:

pnpm add -D css-modules-dts-loader

Usage

Webpack Configuration

Important: The loader options should match your css-loader configuration for consistent behavior.

const isProduction = process.env.NODE_ENV === "production";
const useNamedExports = true; // Should match css-loader setting

module.exports = {
  module: {
    rules: [
      {
        test: /\.module\.(css|postcss|pcss|scss|sass|less|styl|sss)$/i,
        use: [
          "style-loader",
          {
            loader: "css-modules-dts-loader",
            options: {
              // Export format (should match css-loader)
              namedExport: useNamedExports,
              exportLocalsConvention: "camel-case-only",

              // File generation mode
              mode: isProduction ? "verify" : "emit",

              // Formatting options
              quote: "double",
              indentStyle: "space",
              indentSize: 2,
              sort: true,

              // Custom banner
              banner: "// This file is automatically generated.\n// Please do not change this file!"
            }
          },
          {
            loader: "css-loader",
            options: {
              modules: {
                // These should match the dts-loader options above
                namedExport: useNamedExports,
                exportLocalsConvention: "camel-case-only"
              }
            }
          }
        ]
      }
    ]
  }
};

Loader Options

| Option | Type | Default | Description | | ------------------------ | --------------------------------------------------------------------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | exportLocalsConvention | "as-is" | "camel-case" | "camel-case-only" | "dashes" | "dashes-only" | See description | How to transform class names. Defaults based on namedExport: "as-is" if true, "camel-case-only" if false. Matches css-loader's option. | | namedExport | boolean | true | When true, generates named exports (export const foo: string;). When false, generates an interface with default export. Should match css-loader's setting. | | keywordPrefix | string | "__dts_" | Prefix used for aliased exports of JavaScript reserved keywords (e.g., class, export). Must be a valid JavaScript identifier. Only applies when namedExport is true. | | quote | "single" | "double" | "double" | Quote style used for interface properties when namedExport is false. | | indentStyle | "tab" | "space" | "space" | Indentation style for interface properties. | | indentSize | number | 2 | Number of spaces for indentation when indentStyle is "space". | | mode | "emit" | "verify" | "emit" | In "emit" mode, writes/overwrites .d.ts files. In "verify" mode, checks files are up-to-date (useful for CI/CD). | | sort | boolean | false | When true, sorts class names alphabetically in the generated file. | | banner | string | Auto-generated | Custom banner comment at the top of generated files. Default: "// This file is automatically generated.\n// Please do not change this file!" | | camelCase | boolean | undefined | Deprecated (will be removed in v2.0.0): Use exportLocalsConvention instead. When true, maps to "camel-case-only". When false, maps to "as-is". |

exportLocalsConvention Values

This option matches css-loader's behavior:

| Value | Description | Example: .foo-bar | | ------------------ | ----------------------------------------------------------------- | ---------------------------------- | | "as-is" | Class names exported exactly as written | fooBar → exports "foo-bar" | | "camel-case" | Exports both original and camelCase versions | fooBar → exports both | | "camel-case-only"| Exports only camelCase version | fooBar → exports fooBar only | | "dashes" | Converts dashes to camelCase, exports both | Same as "camel-case" | | "dashes-only" | Converts dashes to camelCase, exports only camelCase | Same as "camel-case-only" |

JavaScript Keywords Handling

When using namedExport: true, JavaScript reserved keywords (like class, export, import, etc.) cannot be exported as named exports because they're invalid JavaScript syntax.

Behavior:

  • Keywords are exported using aliased exports to provide full type safety
  • Non-keyword classes are exported normally as named exports
  • Keywords are accessible via namespace import with full type safety
  • The prefix for aliased exports can be customized using the keywordPrefix option

Example:

/* styles.module.css */
.class { color: blue; }
.container { padding: 10px; }

Generated with namedExport: true and default keywordPrefix:

// styles.module.css.d.ts
export const container: string;

declare const __dts_class: string;
export { __dts_class as "class" };

Generated with namedExport: true and keywordPrefix: "dts":

// styles.module.css.d.ts
export const container: string;

declare const dtsclass: string;
export { dtsclass as "class" };

Usage in TypeScript:

import * as styles from './styles.module.css';

// Both are fully type-safe:
styles.container;  // ✅ Type-safe
styles.class;      // ✅ Type-safe via aliased export

Why customize keywordPrefix?

  • Linter compatibility: Some ESLint configurations flag identifiers starting with __ (double underscore)
  • Naming conventions: Match your project's naming standards
  • Readability: Use a prefix that's clearer in your codebase (e.g., dts, css_, module_)

Note: With namedExport: false, all classes (including keywords) are included in the interface, so there's no difference in behavior for keywords.

Example Output

With namedExport: true (default)

// This file is automatically generated.
// Please do not change this file!
export const button: string;
export const container: string;

Usage:

import { button, container } from './styles.module.css';
// or
import * as styles from './styles.module.css';

If your CSS contains keywords:

// This file is automatically generated.
// Please do not change this file!
export const button: string;
export const container: string;

declare const __dts_class: string;
export { __dts_class as "class" };

Usage with keywords:

import * as styles from './styles.module.css';

styles.button;
styles.container;
styles.class; // Type-safe via aliased export

// Or

import {
	button,
	container,
	class as notReservedJsKeyword
} from './styles.module.css';

<div className={notReservedJsKeyword}>
	No conflicts with JS keywords!
</div>

With namedExport: false

// This file is automatically generated.
// Please do not change this file!
interface CssExports {
  "button": string;
  "container": string;
  "class": string;
}

export const cssExports: CssExports;
export default cssExports;

Usage:

import styles from './styles.module.css';

styles.button;
styles.container;
styles.class;

Configuration Tips

  1. Match css-loader options: Your namedExport and exportLocalsConvention options should match css-loader's configuration to avoid runtime/type mismatches.

  2. Use verify mode in CI: Set mode: "verify" in production/CI to ensure .d.ts files are always up-to-date.

How It Works

  1. Runs after css-loader: The loader processes the JavaScript output from css-loader, not the raw CSS.

  2. Extracts class names: Parses the module exports to find all CSS class names (supports both object and named export formats).

  3. Applies transformations: Based on exportLocalsConvention, transforms class names (e.g., kebab-case → camelCase).

  4. Generates declarations: Creates TypeScript declaration files with appropriate export format.

  5. Writes or verifies: In emit mode, writes .d.ts files. In verify mode, checks they're up-to-date.

Migrating from camelCase to exportLocalsConvention

If you're using the deprecated camelCase option:

// Old (deprecated)
{
  camelCase: true
}

// New (recommended)
{
  exportLocalsConvention: "camel-case-only"
}

The camelCase option still works for backward compatibility but will be removed in v2.0.0.

Contributing

Contributions, bug reports, and feature requests are welcome! To contribute:

  1. Fork the repository
  2. Create a feature branch: git checkout -b my-new-feature
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin my-new-feature
  5. Create a new Pull Request

Before contributing, please review the CONTRIBUTING.md guidelines (if available).

License

This project is licensed under the MIT License. See the LICENSE file for details.

Changelog

See CHANGELOG.md for version history and recent changes.

Support

If you encounter any issues or have questions, please open an issue in the GitHub repository.