# @modular-css/processor

> A streamlined reinterpretation of CSS Modules

Latest version **29.3.0** (published 2026-04-23) · MIT license · 0 weekly downloads

## Install

```sh
npm install @modular-css/processor
pnpm add @modular-css/processor
yarn add @modular-css/processor
bun add @modular-css/processor
```

## Health

**Score 55/100 (C)** — status: active.

Positive: no vulnerabilities; has provenance; high maintenance score.

Warnings: low downloads; no types; no esm support.

## Facts

| | |
|---|---|
| Version | 29.3.0 |
| Published | 2026-04-23 |
| First published | 2018-09-01 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 7 |
| Unpacked size | 151.2 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 291 |
| Author | Pat Cavit |
| Maintainers | tivac |
| Keywords | css, css-modules, modular-css, postcss |

## Links

- npm: https://www.npmjs.com/package/@modular-css/processor
- Repository: https://github.com/tivac/modular-css
- Homepage: https://m-css.com
- Issues: https://github.com/tivac/modular-css/issues
- npm.io page: https://npm.io/package/@modular-css/processor

## Dependencies (7)

- [postcss-url](https://npm.io/package/postcss-url.md) ^10.0.0
- [unique-slug](https://npm.io/package/unique-slug.md) ^4.0.0
- [resolve-from](https://npm.io/package/resolve-from.md) ^5.0.0
- [dependency-graph](https://npm.io/package/dependency-graph.md) ^1.0.0
- [escape-string-regexp](https://npm.io/package/escape-string-regexp.md) ^4.0.0
- [postcss-value-parser](https://npm.io/package/postcss-value-parser.md) ^4.0.0
- [postcss-selector-parser](https://npm.io/package/postcss-selector-parser.md) ^7.1.0

## Alternatives

- [style-dictionary](https://npm.io/package/style-dictionary.md) — 2.0M weekly downloads
- [postcss-merge-idents](https://npm.io/package/postcss-merge-idents.md) — 1.7M weekly downloads
- [@fontsource/noto-sans](https://npm.io/package/@fontsource/noto-sans.md) — 93.0K weekly downloads
- [uglifycss](https://npm.io/package/uglifycss.md) — 71.6K weekly downloads
- [mat4-interpolate](https://npm.io/package/mat4-interpolate.md) — 23.3K weekly downloads

## Recent versions

- 29.3.0 (latest) — 2026-04-23
- 27.0.2 (next) — 2021-07-18
- 29.2.0 — 2026-02-17
- 29.1.0 — 2025-09-03
- 29.0.4 — 2025-01-10
- 29.0.3 — 2023-10-26
- 29.0.2 — 2023-09-26
- 29.0.1 — 2023-08-08
- 29.0.0 — 2023-03-26
- 28.1.5 — 2022-11-28
- 28.1.4 — 2022-09-07
- 28.1.3 — 2022-06-15
- 28.0.0 — 2022-02-25
- 27.1.0 — 2022-02-03
- 27.0.3 — 2021-12-17
- … 40 more at https://npm.io/package/@modular-css/processor/versions

## README

@modular-css/processor  [![NPM Version](https://img.shields.io/npm/v/@modular-css/processor.svg)](https://www.npmjs.com/package/@modular-css/processor) [![NPM License](https://img.shields.io/npm/l/@modular-css/processor.svg)](https://www.npmjs.com/package/@modular-css/processor) [![NPM Downloads](https://img.shields.io/npm/dm/@modular-css/processor.svg)](https://www.npmjs.com/package/@modular-css/processor)
===========

The core functionality of [`modular-css`](https://npmjs.com/modular-css) exposed as a JS API.

- [Install](#install)
- [Usage](#usage)
- [API](#api)
- [Options](#options)
- [Properties](#properties)

## Install

`$ npm i @modular-css/processor`

## Usage

Instantiate a new `Processor` instance, call it's `.file(<path>)` or `.string(<name>, <contents>)` methods, and then use the returned Promise to get access to the results/output.

```js
const Processor = require("@modular-css/processor");
const processor = new Processor({
    // See "API Options" for valid options to pass to the Processor constructor
});

// Add entries, either from disk using .file() or as strings with .string()
const result = await processor.file("./entry.css");

// result contains
//  .exports - Scoped selector mappings
//  .files - metadata about the file hierarchy

await processor.string("./fake-file.css", ".class { color: red; }");

// Once all files are added, use .output() to get at the rewritten CSS
const results = await processor.output();

// Output CSS lives on the .css property
results.css;

// Source map (if requested) lives on the .map property
results.map;
```

## API

### `.string(file, css)`

Returns a promise. Add `file` to the `Processor` instance with `css` contents.

### `.file(file)`

Returns a promise. Add `file` to the `Processor` instance, reads contents from disk using `fs`.

### `.root(file, Root)`

Returns a promise. Add `file` to the `Processor` instance, re-uses a Postcss `Root` object, avoiding
unnecessarily parsing an AST again.

### `.output({ args })`

Returns a promise. Finalize processing of all added CSS and create combined CSS output file.

Passing `files` as part of `args` will result in getting back combined output CSS just for the listed files and their dependencies.

Passing `to` as part of `args` will be passed along to teh `after` and `done` hooks for proper path adjustment in maps & any plugins that use it.

**WARNING**: Calling `.output()` before any preceeding `.file(...)`/`.string(...)` calls have resolved their returned promises will return a rejected promise. See [usage](#usage) for an example of correct usage.

Includes the following keys that you probably care about:

- `.css`, the generated CSS representing the files being output
- `.map`, the (optional) source map for the files being output
- `.compositions`, the selector hierarchies for all the files being output

### `.remove([files])`

Remove files from the `Processor` instance. Accepts a single file or array of files.

### `.invalidate(file)`

Mark a file (and any files that depend on it) as invalid. If any of those files are then re-added via either `.string()` or `.file()` they will be replaced with the new values instead of using the cached results from the previous run.

### `.fileDependencies([file])`

Returns an array of file paths. Accepts a single file argument to get the dependencies for, will return entire dependency graph in order if argument is omitted.

###

## Options

### `before`

Specify an array of PostCSS plugins to be run against each file before it is processed.

```js
new Processor({
    before : [ require("postcss-import") ]
});
```

### `after`

Specify an array of PostCSS plugins to be run after files are processed, but before they are combined. Plugin will be passed a `to` and `from` option.

**By default** [`postcss-url`](https://www.npmjs.com/package/postcss-url) is used in `after` mode.

```js
new Processor({
    after : [ require("postcss-someplugin") ]
});
```

### `done`

Specify an array of PostCSS plugins to be run against the complete combined CSS.

```js
new Processor({
    done : [ require("cssnano")()]
});
```

### `map`

Enable source map generation. Can also be passed to `.output()`.

**Default**: `false`

```js
new Processor({
    map : true
});
```

### `cwd`

Specify the current working directory for this Processor instance, used when resolving `composes`/`@value` rules that reference other files.

**Default**: `process.cwd()`

```js
new Processor({
    cwd : path.join(process.cwd(), "/sub/dir")
})
```

### `namer`

Specify a function (that takes `filename` & `selector` as arguments to produce scoped selectors.

**Default**: Function that returns `"mc" + unique-slug(<file>) + "_" + selector`

```js
new Processor({
    namer : function(file, selector) {
        return file.replace(/[:\/\\ .]/g, "") + "_" + selector;
    }
});
```

### `postcss`

Specify an object that contains any of the [PostCSS `.process()` Options](http://api.postcss.org/global.html#processOptions). Note that `from` and `to` will usally **be overwritten** to match the files being processed. This feature allows for the use of custom `parser`, `stringifier`, and `syntax` settings.

### `resolvers`

If you want to provide your own file resolution logic you can pass an array of resolver functions. Each resolver function receives three arguments:

- `src`, the file that included `file`
- `file`, the file path being included by `src`
- `resolve`, the default resolver function

Resolver functions should either return an absolute path or a falsey value. They must also be synchronous.

**Default**: See [/processor/lib/resolve.js](https://github.com/tivac/modular-css/blob/main/packages/processor/lib/resolve.js#L7) for the default implementation.

```js
new Processor({
    resolvers : [
        (src, file, resolve) => ...,
        require("@modular-css/path-resolver")(
            "./some/other/path"
        )
    ]
})
```

### `exportGlobals`

Enable exporting `:global` identifiers.

**Default**: true

```js
new Processor({
    exportDefaults: false
})
```

```css
/* exportGlobals: true */
.a {}
:global(.b) {}

/* Outputs
{
    "a" : "mc12345_a",
    "b" : "b"
}
*/

/* exportGlobals: false */
.a {}
:global(.b) {}

/* Outputs
{
    "a" : "mc12345_a"
}
*/
```

## Properties

### `.files`

Returns an object keyed by absolute file paths of all known files in the `Processor` instance.

### `.options`

Returns the options object passed to the `Processor` augmented with the defaults.

---
_Source: https://npm.io/package/@modular-css/processor · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
