Library / SDK
reworkcss/css avatar
reworkcss/css

reworkcss/css: A Node.js CSS parser and stringifier

CSS parser / stringifier for Node.js

1,647 stars274 forksCSSMIT

At a glance

What is it?
reworkcss/css converts CSS text into a mutable AST and can serialize that AST back to CSS. It is useful for Node.js build tools, but its README states that material changes are not planned and directs new projects to @adobe/css-tools.
Who is it for?
Adopt reworkcss/css only when an existing Node.js toolchain specifically depends on its AST shape or must preserve compatibility with it. Do not choose it for a new parser project when the README's lack of planned fixes and recommendation of @adobe/css-tools make maintenance risk unacceptable.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 141 days ago.
What is it written in?
Mainly CSS, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Where reworkcss/css fits in a Node.js stylesheet toolchain

reworkcss/css solves a narrow transformation problem: it accepts CSS text, exposes a JavaScript object model, and can turn that object model back into CSS. The intended users are Node.js developers building stylesheet-processing tools, plugins, or transformations that need structured access to rules, declarations, comments, and at-rules. It is not a browser CSS engine, minifier with its own optimization policy, or general utility for interpreting the computed appearance of a page.

Its most useful property is the shared object accepted by `css.parse()` and `css.stringify()`. A tool can parse a stylesheet, inspect or modify its AST, and serialize it again. The package description calls it a "CSS parser / stringifier," and the README describes the root result as an AST object. This makes the library relevant when string-only regular expressions would make structural CSS changes unreliable.

The adoption boundary is already stated by the project. The README says there have been no material changes in 10 years, new changes and bug fixes are not planned, and users should consider a more modern alternative. It specifically recommends `@adobe/css-tools`. The repository is not archived and the last push was on 2026-06-04, but that repository fact does not erase the maintenance warning in the project documentation. For a new integration without a compatibility requirement, `@adobe/css-tools` is the documented direction.

Parsing CSS into reworkcss/css nodes and source positions

Parsing begins with `css.parse(code, [options])`. It returns a stylesheet node containing a `rules` array. Ordinary style rules are represented with selector strings and declaration nodes, while supported at-rules receive dedicated node shapes. For example, an `@import` node stores the text after `@import`, a `@media` node stores its media condition and nested rules, and a `@keyframes` node stores the name, optional vendor prefix, and keyframe children.

Every node has a `type` and `position` metadata. The position data contains start and end coordinates, an optional `source`, and the full input content. Lines and columns are 1-based. The optional `source` passed to the parser is copied into this metadata and also becomes the filename on parse errors, which makes diagnostics more useful when processing a named file.

The parser also has two distinct failure modes. By default, parsing errors are thrown with `message`, `reason`, `filename`, `line`, `column`, and `source` fields. With `silent: true`, errors are collected in the stylesheet node's `parsingErrors` array instead. Silent parsing is useful when a caller wants to inspect recoverable or partial results, but it also means the caller must check `parsingErrors`; successful return alone does not mean that every construct was accepted.

The model is intentionally only partially lossless. Selectors, properties, and values are stored as trimmed strings. Comments inside selectors, properties, and values are lost, while rule-level and declaration-level comments become comment nodes. This is an important constraint for tools that promise byte-for-byte round trips.

Turning a modified AST back into CSS and source maps

`css.stringify(object, [options])` performs the reverse operation. It accepts the AST shape produced by `css.parse()` and returns a CSS string. By default, indentation uses two spaces. Passing `compress: true` omits comments and extraneous whitespace, which is useful for compact output but also makes formatting irreversible through a later `stringify()` call.

Source-map generation is integrated into serialization. With `sourcemap: true`, `stringify()` returns a result object containing `code` and `map` rather than only the CSS text. Setting `sourcemap: 'generator'` returns a `SourceMapGenerator` object instead of serializing the map. The README strongly recommends setting `source` during parsing in this workflow, because the parser can then attach the origin to node position information.

Input source maps are consumed by default. Setting `inputSourcemaps: false` disables that behavior. This matters for deployment and sandboxing because enabled input-map handling may require file system access to read referenced maps. Source-map support is therefore more than a boolean formatting switch: it introduces a path from parsed source locations to serialized output locations and can pull external map data into the operation.

Stringification preserves the documented node structure, not necessarily every byte of the input. Since the AST discards some embedded comments and normalizes property, selector, and value whitespace, callers that require exact formatting or lossless round trips need to verify that requirement separately.

Installing css and parsing a first stylesheet

The README gives a direct npm installation command. This installs the package named `css`, which should not be confused with unrelated packages that may use a similar description in registry search results.

bash
$ npm install css

A minimal CommonJS example parses a declaration and serializes the resulting AST. The call returns an object, while `css.stringify(obj, options)` returns the serialized stylesheet.

js
var css = require('css');
var obj = css.parse('body { font-size: 12px; }', options);
css.stringify(obj, options);

The README example uses `options` as a placeholder in the sample call, so it does not specify one required variable or configuration. In a direct first use, the parser can be called with the CSS string alone.

For source-aware output, pass `source` while parsing and request `sourcemap` while stringifying. The result exposes the generated CSS as `result.code` and the source map as `result.map`.

js
var ast = css.parse('body { font-size: 12px; }', { source: 'source.css' });
var css = css.stringify(ast);
var result = css.stringify(ast, { sourcemap: true });

After the first call, `css` contains the default stringified output. In the second result, `result.code` is the CSS string and `result.map` is the source map object.

CSS syntax that the documented AST does not fully preserve

The clearest limitation is information loss inside CSS constructs. The README explicitly says that comments inside selectors, properties, values, and similar locations are lost. A transformation that only needs semantic declarations may tolerate this, but a format-preserving tool may not. Even standard formatting such as spacing around punctuation can change when a string is normalized and serialized again.

The AST also uses plain strings for selectors, declaration values, and several at-rule parameters. This keeps the object model compact, but callers cannot assume every part of the input has a dedicated nested node. Unsupported or less detailed syntax should therefore be checked against the actual parser behavior before a tool depends on it.

Silent mode presents a second operational hazard. A caller that enables `silent` and does not inspect `stylesheet.parsingErrors` can treat damaged or unsupported input as successfully parsed. This behavior is useful for partial analysis, but it shifts validation responsibility to the application.

These constraints make reworkcss/css a poor fit for editor-quality lossless transformation, CSS syntax validation as a primary purpose, or tools that need every source comment retained. It is more appropriate for controlled pipelines that accept normalized output and operate on the documented AST fields.

License, dependencies, and the cost of staying with reworkcss/css

The package is licensed under the MIT license. The repository includes a `LICENSE` file, and `package.json` identifies the project as `css` version `3.0.0`. Its runtime dependencies are `inherits`, `source-map`, and `source-map-resolve`, as declared in `package.json`. The package entry point is `index`, and the published file list includes `index.js`, `lib`, and `Readme.md`.

The larger maintenance cost comes from project direction rather than license restrictions. The repository has no GitHub releases, so there is no release channel documented here beyond the package version visible in `package.json`. The last push was on 2026-06-04, while the README says material package changes have not occurred in 10 years and that new changes and bug fixes are not planned. That is a poor fit for requirements involving new syntax, ongoing compatibility work, or frequent fixes, except for concrete security issues according to the README.

The direct alternative named by the project is `@adobe/css-tools`. The difference in approach is not merely the package name. Existing code that relies on reworkcss/css node shapes should therefore be compared with its actual replacement requirements rather than assuming API compatibility.

Editorial conclusion

Adopt reworkcss/css only when an existing Node.js toolchain specifically depends on its AST shape or must preserve compatibility with it. Do not choose it for a new parser project when the README's lack of planned fixes and recommendation of @adobe/css-tools make maintenance risk unacceptable. Before adoption, verify that your required CSS syntax, source-map behavior, and error expectations match this package's documented model.

Frequently asked questions

How do I install reworkcss/css in a Node.js project?

The README gives the command `npm install css`. The resulting package is the `css` module documented as a CSS parser and stringifier.

How do I parse and serialize CSS with reworkcss/css?

Call `css.parse(code)` to obtain a stylesheet AST, then pass that object to `css.stringify(object)`. The README's source-map example accesses the generated CSS through `result.code` and the map through `result.map`.

Does reworkcss/css support generating source maps?

Yes. `css.stringify()` accepts `sourcemap: true` and returns `code` with a `map`; `sourcemap: 'generator'` returns a `SourceMapGenerator` object. The README recommends setting `source` during parsing.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. reworkcss/css on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/reworkcss-css.svg)](https://hysenlabs.com/projects/reworkcss-css)

Was this useful?