Skip to content

Repository files navigation

playground npm npm cov Doc NPM Downloads bundle size

css-parser

An all-in-one CSS parsing solution for Node.js and the browser, covering parsing, validation, transformation, minification, and AST-based tooling.

The library always fully parses the stylesheet into a structured AST, and token values are exposed as typed data so custom transforms, plugins, and analysis can work with reliable, semantic input instead of raw strings.

Installation

From npm

$ npm install @tbela99/css-parser

from jsr

$ deno add @tbela99/css-parser

Features

  • Zero dependencies — lightweight and easy to integrate into any project.
  • All-in-one CSS parsing solution covering parsing, validation, transformation, minification, and AST manipulation.
  • Standards-based CSS validation powered by MDN data.
  • Full CSS Modules support for modern component-based workflows.
  • Fault-tolerant parsing that follows the CSS Syntax Module Level 3 specification and always produces a complete, structured parse result.
  • Typed tokens and AST — parsed CSS is exposed as strongly typed tokens and nodes so plugins and transforms can operate on semantic structures.
  • High-performance minification with safe optimizations and no unsafe transforms.
  • Advanced color processing with support for modern color spaces and functions, including color(), lab(), lch(), oklab(), oklch(), color-mix(), light-dark(), system colors, and relative colors.
  • Color conversion engine capable of transforming colors between all supported formats.
  • Automatic CSS nesting generation from compatible selectors.
  • Source map generation for easier debugging and development workflows.
  • Shorthand property computation to reduce output size and improve optimization.
  • Transform function optimization for more compact CSS output.
  • Math function evaluation, including calc(), clamp(), min(), max(), and related expressions.
  • CSS variable inlining where values can be safely resolved.
  • Duplicate declaration removal to eliminate redundant rules.
  • @import flattening to produce self-contained stylesheets.

Vendor prefix removal

Vendor prefix cleanup to modernize generated CSS.

Syntax lowering

CSS-Parser can transform these modern CSS features into lower-level CSS syntax:

  • Nested CSS transpilation to legacy-compatible syntax.
  • if() function transpilation for broader browser compatibility.
  • color-mix() function conversion convert new color-mix() syntax to any of the supported colors.

Benchmark

Across all tested datasets, css-parser consistently produces the smallest output among the benchmarked tools, including Lightning CSS, cssnano, csso, clean-css, css-tree, and esbuild.

The benchmark evaluates minification effectiveness on a diverse set of real-world stylesheets, including Bootstrap 4, Bootstrap 5, Tailwind CSS, Animate.css, Foundation, Font Awesome, Normalize.css, and others.

A sample result:

File ligthningcss CSS Parser
tailwind.css - 2380419 bytes 1864728 bytes 1633188 bytes
bootstrap-4.css - 200078 bytes 153616 bytes 144571 bytes
bootstrap-5.css - 205481 bytes 159987 bytes 150852 bytes

On the complete benchmark suite, css-parser generated a total output size of 2,158,698 bytes, compared to 2,494,113 bytes for Lightning CSS and larger outputs for all other tested minifiers. While some tools prioritize raw execution speed, css-parser focuses on maximizing compression while preserving stylesheet semantics, resulting in consistently smaller production bundles.

Minification performance vs execution speed

css-parser is designed for maximum minification performance, but the optimal configuration depends on what matters most for your workload.

The parser provides settings that let you choose the balance between minification performance and execution speed:

  • Minification performance: prioritize the quality and efficiency of the minification process, allowing the parser to perform additional work when generating the minimized output.

  • Execution speed: minimize the amount of work performed during parsing and minification to achieve the fastest possible execution time.

However, the available settings allow you to shift the balance toward execution speed when minimizing runtime is more important than performing every available minification optimization.

The example below demonstrates a balanced configuration that improves execution speed by disabling advanced minification features.

import {transformSync} from "@tbela99/css-parser";

const css = `...`;

const result = transformSync({
                  input: css,
                  minify: false,
                  beautify: false,
                  removeEmpty: true,
                  removeComments: true,
                  convertColor: true,
                  minifyValues: true,
                });

console.debug(result.code);
console.debug(result.stats);

Performance vs execution speed comparison

File: tailwind.css Speed optimization Minification optimization
Size: 2,380,419 bytes 1,890,728 bytes 1,633,188 bytes
Time 205.91 ms 471.89 ms
Size reduction -20.6% -31.4%

Playground

Try it online

Documentation

AST

Comment

  • typ: number
  • val: string, the comment

AtRuleStyleSheet

  • typ: number
  • chi: array of children

Declaration

  • typ: number
  • nam: string, declaration name
  • val: array of tokens
  • state: EnumAstNodeStatus, validation state
  • errors: ErrorDescription[], validation errors

Rule

  • typ: number
  • sel: string, css selector
  • chi: array of children
  • state: EnumAstNodeStatus, validation state
  • errors: ErrorDescription[], validation errors

AtRule and KeyframesAtRule

  • typ: number
  • nam: string. AtRule name
  • val: rule prelude
  • state: EnumAstNodeStatus, validation state
  • errors: ErrorDescription[], validation errors

KeyframesRule

  • typ: number
  • sel: string, css selector
  • chi: array of children
  • state: EnumAstNodeStatus, validation state
  • errors: ErrorDescription[], validation errors

Sourcemap

  • Sourcemap generation
  • Input sourcemap: when the input CSS comes from another tool, you can pass the sourcemap content to link the generated CSS positions to the original files.

Computed shorthands properties

  • all
  • animation
  • background
  • border
  • border-block-end
  • border-block-start
  • border-bottom
  • border-color
  • border-image
  • border-inline-end
  • border-inline-start
  • border-left
  • border-radius
  • border-right
  • border-style
  • border-top
  • border-width
  • column-rule
  • columns
  • container
  • contain-intrinsic-size
  • flex
  • flex-flow
  • font
  • font-synthesis
  • font-variant
  • gap
  • grid
  • grid-area
  • grid-column
  • grid-row
  • grid-template
  • inset
  • list-style
  • margin
  • mask
  • offset
  • outline
  • overflow
  • padding
  • place-content
  • place-items
  • place-self
  • scroll-margin
  • scroll-padding
  • scroll-timeline
  • text-decoration
  • text-emphasis
  • transition

Performance

  • Bundle file referenced by the @import statement.

Architecture

flowchart TD
    %% --- Transform ---
    Input(["CSS input"])


    %% The Grouped Container
    subgraph Group10["Transform step"]

        transform["transform()/transformSync()"]


        %% The Grouped Container
        subgraph Group1 ["Parse step"]

            %% --- Parse step ---
            parse["parse()/parseSync()"]
            tokenize(["tokenize()"])
            parseNode(["parse and validate token stream"])
            visitors(["visitors"])
            minify(["minify AST"])
            cssModules(["generate CSS module"])
            parseResult["Parse result"]
        end

        %% The Grouped Container
        subgraph Group2 ["Render step"]

            %% --- Render step ---
            renderAst(["Render AST"])
            sourcemap([Sourcemap generation])

        end

        %% --- Result step ---
        transformResult["Transform result"]
    end 

    %% --- Routing step ---
    Input --> transform
    transform --> parse
    parse --> tokenize
    tokenize --> parseNode
    parseNode -- "Visitors set?"  --> visitors
    visitors -- "Minify AST?"  --> minify
    minify -- "CSS module?"  --> cssModules
    visitors -- "CSS module?"  --> cssModules
    cssModules --> parseResult
    parseNode -- "CSS module?" --> cssModules
    parseNode -- "Minify AST?"  --> minify
    parseNode --> parseResult
    visitors --> parseResult
    minify --> parseResult
    parseResult --> renderAst
    renderAst -- "Sourcemap?" --> sourcemap
    renderAst --> transformResult
    sourcemap --> transformResult
Loading

Releases

Packages

Used by

Contributors

Languages