Skip to main content

CLI and linting

Jess ships one CLI with separate compile and lint workflows:

jess input.less output.css
jess lint "src/**/*.{css,less,scss,jess}"

The default command compiles one input file to CSS. The lint subcommand reports diagnostics without writing CSS.

Compile​

Compile a stylesheet by passing the input file first:

jess input.less

Jess writes input.css next to the source file. Pass an output file or output directory when you want to control the destination:

jess input.less dist/input.css
jess input.less -o dist

The default command is intentionally short because it mirrors familiar tools: sass input.scss output.css, lessc input.less output.css, and tsc all keep the primary build workflow close to the command name. Linting is explicit because it is a different operation with a different exit policy.

Lint​

Run lint with no arguments to use lint.files from styles.config.js. If no lint file patterns are configured, Jess scans **/*.{css,less,scss,jess}.

jess lint

Pass files or glob patterns to lint a specific set:

jess lint "src/**/*.{css,less,scss,jess}"
jess lint src/app.scss

Text output is compact: one file heading, one line per diagnostic, then a summary.

src/app.css
2:3 warning property-no-unknown Unknown property: 'colr'
3:10 warning length-zero-no-unit The unit "px" is unnecessary for a zero value
Linted 1 file(s): 0 error(s), 2 warning(s)

Lint Options​

OptionWhat it does
--format textPrint compact human-readable output. This is the default.
--format jsonPrint the full structured lint result as JSON, including lint ruleName and shared diagnostic code.
--max-warnings <n>Exit non-zero when warnings exceed n. Use --max-warnings 0 in CI.
--syntax-onlyReport parser diagnostics only.
--quietSuppress warnings in text output.
--config <path>Load a specific styles.config.js file.
--no-colorDisable ANSI color and terminal hyperlinks.

Configure Lint​

Configure linting in styles.config.js:

export default {
lint: {
files: ['src/**/*.{css,less,scss,jess}'],
ignoreFiles: ['dist/**'],
reportSyntax: true,
rules: {
'block-no-empty': ['warn', { include: ['mixins'] }],
'property-no-unknown': 'error',
'declaration-block-no-duplicate-properties': ['warn', { ignore: ['consecutive-duplicates'] }],
'length-zero-no-unit': 'warn',
'jess/no-unused-variable': 'off',
'jess/no-unused-mixin': 'off',
'jess/no-unused-function': 'off',
'jess/no-duplicate-module-load': 'warn',
'jess/no-unbounded-extend': 'warn',
'jess/no-dead-extend': 'warn',
'jess/no-suspicious-map-key-access': 'warn',
'vendor-prefix': 'warn',
'compatible-vendor-prefixes': 'off',
'unknown-vendor-specific-properties': 'off',
'value-no-vendor-prefix': 'off',
'selector-class-pattern': ['off', { pattern: '^[a-z][a-z0-9-]*$' }],
'custom-property-pattern': ['off', { pattern: '^--[a-z][a-z0-9-]*$' }],
'keyframes-name-pattern': ['off', { pattern: '^[a-z][a-z0-9-]*$' }],
'color-function-notation': ['off', { notation: 'modern' }],
'alpha-value-notation': ['off', { notation: 'percentage' }],
'hue-degree-notation': ['off', { notation: 'angle' }],
'float': 'off',
'jess/no-shadowed-token': 'off',
'jess/unsupported-sass-form': 'warn'
}
}
}

Rule severity values are off, warn, and error; null also disables a rule. Rules that support secondary options can use a Stylelint-like tuple: ['warn', { ...options }].

block-no-empty reports empty rulesets by default. Use ['warn', { include: ['mixins'] }] to also report empty Less, SCSS, and Jess mixin bodies.

Naming convention rules such as selector-class-pattern, custom-property-pattern, and keyframes-name-pattern are opt-in and require a secondary pattern option.

Notation convention rules such as color-function-notation, alpha-value-notation, and hue-degree-notation are opt-in and require a secondary notation option. Their lint rule names match Stylelint for migration familiarity; their diagnostic codes remain Jess-owned shared identities.

CSS validity rules use VSCode web custom data where possible, including property names, at-rule descriptors, and simple static descriptor/property values.

What Jess Checks Today​

Jess's stable lint set is deliberately small:

Rule nameJess diagnostic codeWhat it catches
block-no-emptylint/empty-rulesEmpty rulesets; empty mixin bodies with include: ['mixins']
property-no-unknownlint/unknown-propertyUnknown CSS properties
property-no-deprecatedlint/property-no-deprecatedDeprecated or obsolete CSS properties from web custom data
at-rule-no-unknownlint/unknown-at-ruleUnknown CSS at-rules
declaration-block-no-duplicate-propertieslint/duplicate-propertyDuplicate declarations in one block
color-no-invalid-hexlint/hex-color-lengthInvalid hex color lengths
length-zero-no-unitlint/zero-unitsZero length values that do not need a unit
jess/no-unused-variablelint/no-unused-variableOpt-in same-file unused Less, SCSS, and Jess variables
jess/no-unused-mixinlint/no-unused-mixinOpt-in same-file unused Less, SCSS, and Jess mixins
jess/no-unused-functionlint/no-unused-functionOpt-in same-file unused SCSS and Jess functions
jess/no-duplicate-module-loadlint/no-duplicate-module-loadRepeated same-file static SCSS/Jess module-load directives
jess/no-unbounded-extendlint/no-unbounded-extendStatic Less/SCSS/Jess extend targets with no bounded selector anchor
jess/no-dead-extendlint/no-dead-extendExact static extend targets with no same-file selector match
jess/no-suspicious-map-key-accesslint/no-suspicious-map-key-accessNumeric key access against same-file Less maps, SCSS maps, and Jess collections
vendor-prefixlint/vendor-prefixCSS vendor-prefixed declarations/keyframes without the standard form
property-no-vendor-prefixlint/property-no-vendor-prefixOpt-in authored CSS vendor-prefixed property names
at-rule-no-vendor-prefixlint/at-rule-no-vendor-prefixOpt-in authored CSS vendor-prefixed keyframe at-rules
value-no-vendor-prefixlint/value-no-vendor-prefixOpt-in authored CSS vendor-prefixed value keywords and functions
custom-property-patternlint/custom-property-patternOpt-in static custom property naming convention
keyframes-name-patternlint/keyframes-name-patternOpt-in static keyframes naming convention
color-function-notationlint/color-function-notationOpt-in modern CSS color function notation
alpha-value-notationlint/alpha-value-notationOpt-in alpha channel and opacity notation convention
hue-degree-notationlint/hue-degree-notationOpt-in HSL hue unit notation convention
compatible-vendor-prefixeslint/compatible-vendor-prefixesOpt-in incomplete CSS vendor-prefixed declaration/keyframe sets
unknown-vendor-specific-propertieslint/unknown-vendor-specific-propertyOpt-in unknown CSS vendor-prefixed declarations
import-statementlint/import-statementOpt-in CSS @import loading warnings
floatlint/floatOpt-in CSS float layout warnings
jess/no-shadowed-tokenlint/no-shadowed-tokenOpt-in same-file nested variable shadowing
selector-max-idlint/selector-max-idOpt-in CSS ID selector warnings
selector-max-universallint/selector-max-universalOpt-in CSS universal selector warnings
selector-no-vendor-prefixlint/selector-no-vendor-prefixOpt-in authored CSS vendor-prefixed pseudo selectors
selector-class-patternlint/selector-class-patternOpt-in static class selector naming convention
media-feature-name-no-vendor-prefixlint/media-feature-name-no-vendor-prefixOpt-in authored CSS vendor-prefixed media feature names
jess/unsupported-sass-formunsupported/sass-formSCSS forms Jess recognizes but does not support yet

The lint package owns policy and reporting. Detection lives in the shared Jess diagnostics layer so CLI linting and editor diagnostics improve together. Rule names are the user-facing lint configuration and compact-output labels. Diagnostic codes are the shared identities used by diagnostics-core, the language service, JSON output, and compatibility aliases.

Parser syntax failures are diagnostics, not lint rules. jess lint reports them when reportSyntax is enabled and keeps them out of rule configuration.

Jess Lint and Stylelint​

Stylelint is the established CSS linter. It has a much broader rule catalog than Jess lint today, plus plugins, shareable configs, autofix, custom syntaxes, custom formatters, and mature ecosystem presets. Keep using it for broad CSS convention policy while you rely on Jess lint for diagnostics that need Jess's own parser and language facts.

Jess lint is not a Stylelint adapter. It does not flatten Jess, Less, or SCSS into a PostCSS-shaped tree, and it does not lint rendered CSS. It reports diagnostics from Jess's source model so findings can line up with compile behavior and editor diagnostics.

Use this split when migrating:

NeedBest fit today
Large existing Stylelint configKeep Stylelint
Unknown CSS property or at-rule checks in Jess-parsed filesJess lint
Syntax diagnostics shared with editor toolingJess lint
SCSS support-boundary warningsJess lint
Autofix-heavy style policyStylelint
CI budget for Jess diagnosticsjess lint --max-warnings 0

The @jesscss/lint API exports a Stylelint-comparison policy for tool authors who want to measure the overlapping rule subset:

import {
STYLELINT_COMPARISON_LINT_CONFIG,
stylelintComparisonRules
} from '@jesscss/lint'

That comparison set is intentionally narrower than the recommended Jess lint config. It includes only rules with close Stylelint equivalents and leaves out Jess-only parser/support diagnostics.

Diagnostics Story​

Jess lint is a policy layer over shared diagnostics:

  1. Parsers and diagnostics-core detect problems from the authored source.
  2. @jesscss/lint decides whether each diagnostic is off, a warning, or an error.
  3. jess lint renders compact text or JSON and applies the exit policy.
  4. The language service can consume the same lower-level diagnostics for IDE feedback.

That means improvements to shared diagnostics should improve both CLI linting and editor feedback. CLI-only detectors are intentionally not the long-term shape.

The product order is diagnostics first:

  1. Add useful native diagnostics with stable codes and source spans.
  2. Share them between jess lint and the language service.
  3. Make severity and CI policy easy to configure.
  4. Expand Stylelint-comparable coverage where Jess can detect the same issue from its own source model.

Formatting polish, custom formatter compatibility, and autofix are later layers. Jess will not expose jess lint --fix until fixes can be composed safely against authored source.

API​

Tool authors can use @jesscss/lint directly:

import { lintFiles, formatStyledLintResult } from '@jesscss/lint'

const result = await lintFiles(['src/**/*.less'], {
maxWarnings: 0
})

console.log(formatStyledLintResult(result))

For application projects, prefer the jess lint CLI unless you need a custom Node integration.

Coordinates and Performance​

Line and column information is useful for diagnostics, linting, and language services. Jess keeps that as an opt-in tooling concern: compile-facing parser paths do not enable line tracking just because lint exists.