Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To load CSS that is already in a JavaScript string in Node.js, pass it to a CSS parser. With PostCSS, postcss.parse(css) creates an in-memory syntax tree you can inspect or edit; use PostCSS’s processor API instead when you want plugins to transform the CSS. Neither approach applies styles to a rendered page—that is a separate browser or CSSOM task.

Choose whether you need to parse, transform, or render the CSS

“Load CSS” can refer to different jobs. Decide which one you mean before choosing an API:

Goal Approach What you get
Inspect rules or edit declarations postcss.parse(cssString) A PostCSS Root tree representing the CSS syntax. PostCSS API
Run PostCSS plugins on CSS held in memory postcss(plugins).process(cssString, options) A processing result, including the output CSS. Processing can be asynchronous. PostCSS API
Parse and serialize with a smaller parse/stringify-style API css.parse() and css.stringify() An AST object and a way to serialize it. Check whether the package’s maintenance and Node.js compatibility suit your project. npm css package
Apply styles to a rendered document Use a browser stylesheet API or a DOM/CSSOM implementation A stylesheet operation, not merely a server-side parse. MDN: CSSStyleSheet.replaceSync()

For most Node.js tasks involving inspection, validation, or transformation, PostCSS is the straightforward choice. Its parser creates a tree without writing the input to disk. The parser and processor are related but distinct: parsing gives you a tree to work with; processing runs the plugin pipeline and returns output.

Install PostCSS and parse a CSS string

Install PostCSS in your project:

npm install postcss

For the following ES module example, save the code in a .mjs file, or configure the project to use ES modules. The import and parser call follow the PostCSS API:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import postcss from 'postcss'

const css = 'h1 { color: rebeccapurple; }'
const root = postcss.parse(css)

console.log(root.first.selector) // h1

root is the parsed tree. In this example, root.first is the first node and its selector is h1. The CSS string remains in memory; the parser does not require a file path.

For a reusable helper, keep the parsing boundary explicit and let callers handle malformed input:

import postcss from 'postcss'

export function parseCss(css) {
  return postcss.parse(css)
}

const root = parseCss('main { color: teal; }')
console.log(root.first.selector) // main

Parsing produces a syntax tree; it does not automatically validate that the styles will have the visual effect you expect in a browser. If your application needs a particular semantic check, perform that check against the parsed nodes or in the environment where the styles are applied.

Inspect or edit the parsed tree

Once parsed, use the tree rather than splitting CSS text yourself. A parser can distinguish structural syntax such as rules, declarations, comments, nested rules, and at-rules. PostCSS documents tokenization and tree construction in its syntax documentation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For example, you can visit declarations and adjust a value before serializing the root:

import postcss from 'postcss'

const css = 'h1 { color: rebeccapurple; margin: 0; }'
const root = postcss.parse(css)

root.walkDecls('color', declaration => {
  declaration.value = 'navy'
})

console.log(root.toString())

This example demonstrates the general pattern: parse into a tree, make a deliberate change to nodes, then serialize the tree. If your goal is only to read or modify CSS syntax, you do not need to run a plugin processor just to get an AST.

Run PostCSS plugins on an in-memory string

When transformation is the goal, use the processor API. Its .process() method accepts the CSS string and options, and the resulting object exposes processed CSS as result.css. With no plugins, this minimal example shows the in-memory processing path:

import postcss from 'postcss'

const css = 'h1 { color: rebeccapurple; }'
const result = await postcss([]).process(css, { from: undefined })

console.log(result.css)

Replace the empty plugin list with the plugins your project needs. Because processing may be asynchronous, await it in an async function or use a top-level await environment. The from: undefined option is useful when there is no source file to identify; when a filename is meaningful to your workflow, pass suitable source options instead. PostCSS documents postcss.parse(css, options) and .process(css, options) in its API reference.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose the API based on the output you need: inspect or edit the tree directly with parse(), or run configured transformations with process() and consume the result. Processing is not required merely because the source is a string.

Use source information and handle parsing errors

If source locations or source maps matter, provide appropriate options, such as a source filename, rather than treating an anonymous string as if it came from a known file. The exact options depend on what your application needs; consult the PostCSS API for the supported parser and processor options.

Parsing can fail when the CSS has invalid syntax. Catch errors at the boundary where untrusted or user-generated CSS enters your program so your application can report the problem or reject that input cleanly:

import postcss from 'postcss'

function parseCss(css) {
  try {
    return { root: postcss.parse(css) }
  } catch (error) {
    return { error }
  }
}

const parsed = parseCss('h1 { color: rebeccapurple; }')
if (parsed.error) {
  console.error(parsed.error.message)
} else {
  console.log(parsed.root.first.selector)
}

PostCSS exposes syntax errors through its parser/input APIs. The alternative css package documents error fields including filename, line, column, and source. Its npm page lists version 3.0.0 as published six years before the source capture on September 29, 2026; verify current maintenance, compatibility, and behavior before adopting it. npm package page

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Alternative: parse and stringify with the css package

The npm package named css provides a direct string-to-AST API and a stringifier. A minimal example is:

const css = require('css')

const source = 'h1 { color: rebeccapurple; }'
const ast = css.parse(source)

console.log(ast.stylesheet.rules[0].selectors[0])
console.log(css.stringify(ast))

Use this option only after checking whether its current maintenance status, behavior, and Node.js compatibility fit your project. The package page’s version history is the relevant place to check before choosing it: css on npm. For a project already built around PostCSS plugins, the PostCSS parser and processor keep parsing and transformation in the same API family.

Parsing CSS is not applying it to a page

A Node.js parser creates or transforms a representation of CSS. It does not create a rendered document, attach styles to a browser page, or show the visual result. Browser APIs such as CSSStyleSheet.replaceSync() replace the rules of a stylesheet object; that operation belongs to a browser CSSOM context. MDN documentation

Plain Node.js does not provide browser globals such as CSSStyleSheet. If your real objective is to render a page or apply styles to a document, run the operation in a browser or use an explicitly selected DOM/CSSOM implementation. Do not expect postcss.parse() to apply styles.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Why not use a regular expression or node:vm?

A regular expression can match simple text patterns, but it is not a reliable general-purpose CSS parser. Nested rules, comments, strings, escapes, and at-rules make structural handling more involved than splitting on braces. Use a parser when correctness across real CSS syntax matters; PostCSS’s syntax documentation describes its tokenization and tree construction.

node:vm is also the wrong tool: it compiles and runs JavaScript in V8 contexts, rather than parsing CSS. Node.js explicitly warns that vm is not a security mechanism for executing untrusted code. Keep CSS parsing separate from JavaScript execution, and do not use a VM as a supposed CSS parser or security boundary. Node.js VM documentation, v26.10.0

Troubleshoot common problems

  • You have a string but no file. That is fine: pass the string directly to postcss.parse() or to .process(). A source file is not required for in-memory parsing.
  • You expected CSS to appear on a page. Parsing creates a tree; it does not attach or render styles. Use a browser stylesheet operation or a DOM/CSSOM implementation for that separate task.
  • You need plugin output but only called parse(). Parsing returns a tree; configure the plugins and call postcss(plugins).process(css, options), then read result.css.
  • Processing is asynchronous in your code. Await the processing result, or otherwise handle its promise before reading the output.
  • Parsing throws an error. The input may contain malformed CSS. Catch the error at the input boundary and report or reject it; if source identification is useful, supply an appropriate filename in the options.
  • Your regex misses valid CSS structures. Replace brace-splitting or a broad regular expression with a CSS parser that constructs a syntax tree.
  • You tried to use CSSStyleSheet in plain Node.js. Browser globals are not automatically available in a Node process. Move the stylesheet operation to a browser or choose a DOM/CSSOM implementation.
  • You are considering node:vm for input safety. It is not a CSS parser or a security mechanism for untrusted JavaScript. Parse CSS as CSS and do not execute untrusted code on that assumption.

Or skip the browser setup

If your aim is not to parse a CSS string but to capture a rendered website, ScreenshotNeo is a website screenshot API and MCP server for developers. A single GET request can return a PNG, JPEG, WebP, or PDF. It is not a replacement for parsing CSS in Node.js; it is the separate route for capturing a page after it renders. The API and options are documented at ScreenshotNeo docs.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
  • It accepts cookie or consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off.
  • Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed. Responses identify the page verdict and billing status in X-Page-Verdict and X-Billed headers.
  • An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
  • The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Every feature is available on every plan.

Sign up for ScreenshotNeo’s free plan to get 1,000 screenshots a month with no card.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Can I pass CSS received from an HTTP request directly to PostCSS?

Yes. Once you have the response body as a JavaScript string, pass that string to postcss.parse() or the processor API. Decide separately whether the source is trusted and whether your application should accept it.

Does parsing CSS prove it will render the same in every browser?

No. Parsing handles CSS syntax into a tree; rendering depends on a browser or other rendering environment and is outside the parser’s job.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.