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 lint/unknown-property Unknown property: 'colr'
3:10 warning lint/zero-units 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.
--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: {
'property-no-unknown': 'error',
'length-zero-no-unit': 'warn',
'jess/unsupported-sass-form': 'warn'
}
}
}

Rule severity values are off, warn, and error; null also disables a rule.

What Jess Checks Today

Jess's stable lint set is deliberately small:

Rule nameJess diagnostic codeWhat it catches
block-no-emptylint/empty-rulesEmpty rulesets
property-no-unknownlint/unknown-propertyUnknown CSS properties
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/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.

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.