New:Microsoft Teams Notifications Are Now Available in Socket.Learn more →
Get Started

@jesscss/css-parser

Package Overview
Dependencies
Maintainers
1
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@jesscss/css-parser

Jess CSS base parser

latest
npmnpm
Version
2.0.0-alpha.7
Version published
Weekly downloads
242
-70.7%
Maintainers
1
Weekly downloads
 
Created
Source

@jesscss/css-parser

A CSS parser built on parseman. It is the base grammar of the Jess compiler and the foundation the Less, SCSS, and Jess parsers extend (compose([cssGrammar, …])).

Two ways to use it:

  • As part of Jess — the default . entry is wired into @jesscss/core and produces the core AST the Jess compiler evaluates. This is the internal, core-coupled path.
  • As a standalone CST parser — the ./cst entry has no dependency on @jesscss/core. Install just this package and parse CSS source text into a concrete syntax tree (CST). You can also plug your own builders onto the grammar to produce your own AST instead of the default CST.

Install

npm install @jesscss/css-parser

@jesscss/core is an optional peer dependency — it is only needed for the core-coupled . entry, not for ./cst or ./grammar.

Standalone usage (core-free)

import { parseCss } from '@jesscss/css-parser/cst'

const result = parseCss('.foo { color: red; }')

result.ok               // true
result.errors           // ParseError[] (empty when ok)
result.unconsumedFrom   // index of first unparsed char, or null
result.tree             // the CST root (a StyleSheet node)

parseCssCst is an alias of parseCss. Signature:

parseCss(input: string, startRule = 'Stylesheet', options?: { collapse?: boolean }): CssCstParseResult

Pass a different startRule (any capitalized rule name in the grammar, e.g. 'SelectorList', 'Declaration') to parse a fragment instead of a whole stylesheet.

Public API

EntryExportPurpose
@jesscss/css-parser/cstparseCss / parseCssCstCore-free parse of a string to a CST.
@jesscss/css-parser/cstparseCstThe generic driver — parseCst(grammar, input, startRule?, options?). Runs any grammar with the default CST build host.
@jesscss/css-parser/cstcssCstBuildHostThe BuildHost that produces the default CST shape (see below).
@jesscss/css-parser/cstCssCstNode, CssCstLeaf, CssCstError, CssCstChild, CssCstParseResult, CssCstParseOptions (types)CST type definitions.
@jesscss/css-parser/grammarcssGrammarThe compiled grammar (a rule map). Extend it with compose() or drive it directly with parseman's run.
@jesscss/css-parser (.)parseCss, cssGrammar, tokens, runFunctionalParse, …The Jess-internal barrel. Core-coupled (re-exports the core-AST driver). Prefer ./cst if you don't need @jesscss/core.
@jesscss/css-parser/jessCssParser, parseCssFn, productions, …Legacy/internal Jess-facing surface.

Default CST shape

The default host produces three kinds of node:

  • node — { _tag: 'node', type, grammarType, span: { start, end }, state, children } grammarType is the raw grammar rule name; type is a friendly public name (e.g. Ruleset → QualifiedRule, Num → Number, Call → Function, Paren → SimpleBlock).
  • leaf — { _tag: 'leaf', value: string, span } for matched terminals (.foo, {, :, ;).
  • error — { _tag: 'error', type, span, expected, children, state } embedded where recovery happened.

Spans are [start, end) byte offsets into the source. Whitespace and comments are consumed as trivia and do not appear as children (they are tracked separately in result.triviaLog).

Parsing .foo { color: red; } yields (abridged):

{
  "_tag": "node", "type": "StyleSheet", "grammarType": "Stylesheet", "span": { "start": 0, "end": 20 },
  "children": [
    { "_tag": "node", "type": "QualifiedRule", "grammarType": "Ruleset", "span": { "start": 0, "end": 20 },
      "children": [
        { "_tag": "node", "type": "SelectorList", "grammarType": "SelectorList",
          "children": [ /* ComplexSelector → CompoundSelector → BasicSelector → leaf ".foo" */ ] },
        { "_tag": "leaf", "value": "{", "span": { "start": 5, "end": 6 } },
        { "_tag": "node", "type": "Declaration", "grammarType": "Declaration", "span": { "start": 7, "end": 18 },
          "children": [
            { "_tag": "leaf", "value": "color", "span": { "start": 7, "end": 12 } },
            { "_tag": "leaf", "value": ":", "span": { "start": 12, "end": 13 } },
            { "_tag": "node", "type": "Function", "grammarType": "Call", "span": { "start": 14, "end": 17 },
              "children": [ { "_tag": "leaf", "value": "red", "span": { "start": 14, "end": 17 } } ] },
            { "_tag": "leaf", "value": ";", "span": { "start": 17, "end": 18 } }
          ] },
        { "_tag": "leaf", "value": "}", "span": { "start": 19, "end": 20 } }
      ] }
  ]
}

Note that the plain CSS grammar has no color-keyword rule, so a bare ident value like red comes through as a Function/Call (a call with no args). The Less/SCSS/Jess grammars add a NamedColor rule, so the same value parses differently there.

Pass { collapse: true } to unwrap a small set of single-child wrapper node types (Reference, NamedColor, InterpolatedSelector) into their child.

Extending with your own builders

The grammar is decoupled from the tree it builds. Every capitalized rule is a parseman node(); when you run a grammar with a build host, each node() calls your host instead of constructing the default CST. The host signature is parseman's BuildHost:

type BuildHost = (
  type: string,
  children: readonly unknown[],   // built children (whatever your host returned)
  fields: FieldMap | undefined,   // named field() captures
  span: { start: number; end: number },
  rawChildren: readonly unknown[],// children + leaves, in source order
  triviaLog: readonly number[],
  state: unknown
) => unknown                      // your node — becomes a child of the parent's build call

Drive the grammar with parseman's run, supplying your own host and the grammar's trivia rule:

import { run } from 'parseman'
import { cssGrammar } from '@jesscss/css-parser/grammar'

// Build a minimal { type, span } tree of your own.
const myHost = (type, children, fields, span) => ({ type, span, children: children.filter(Boolean) })

const result = run(cssGrammar.Stylesheet, '.foo { color: red; }', {
  build: myHost,
  trivia: cssGrammar.rw   // the grammar's trivia (whitespace + comments) rule
})

result.ok      // true
result.value   // the root node your host returned

parseCss(...) is exactly this pattern with build: cssCstBuildHost. You can read cssCstBuildHost (in src/cst.ts) as a reference host: it shows how grammarType, rawChildren, and span map into a node.

Part of Jess

This package is developed as part of Jess. The core-coupled . entry integrates with @jesscss/core; the ./cst and ./grammar entries are usable on their own.

FAQs

Package last updated on 12 Jul 2026

Related posts