Configuration

CoffeeLint's behavior is controlled by a JSON configuration that sets each rule's severity level and options. This page explains where configuration can live, how CoffeeLint finds it, how your settings merge with the defaults, and how to share configuration between projects.

Configuration Format

A configuration is a JSON object whose keys are rule names. Each rule maps to an object containing a level and any rule-specific options:

{
  "indentation": {
    "level": "error",
    "value": 4
  },
  "line_endings": {
    "level": "error",
    "value": "unix"
  },
  "no_debugger": {
    "level": "warn",
    "console": true
  }
}

Levels

Every rule has one of three levels:

Level Effect
error The problem is reported and makes the command exit with status 1.
warn The problem is reported but does not affect the exit code.
ignore The rule does not run at all.

Any other value causes CoffeeLint to throw an error such as unknown level fatal for rule: indentation. Levels are case-sensitive.

Rule Options

Many rules accept options in addition to level, such as value for indentation and max_line_length, or spacing for colon_assignment_spacing. Each rule's options and defaults are documented on the rule pages: Whitespace and Formatting, Style and Syntax, Functions and Classes, and Errors and Debugging.

Comments in Configuration Files

Configuration files are passed through strip-json-comments before being parsed, so you can annotate them:

{
  // Our team uses four-space indentation everywhere.
  "indentation": {
    "level": "error",
    "value": 4
  }
}

As an alternative that also works with strict JSON tools, CoffeeLint ignores a top-level _comment key.

Where Configuration Can Live

coffeelint.json

The most common choice: a coffeelint.json file in the project root.

package.json

Add a coffeelintConfig section to your package.json. The contents are exactly the same as a coffeelint.json:

{
  "name": "your-project",
  "version": "0.0.0",
  "coffeelintConfig": {
    "indentation": {
      "level": "error",
      "value": 4
    },
    "line_endings": {
      "value": "unix",
      "level": "error"
    }
  }
}

The COFFEELINT_CONFIG Environment Variable

Point COFFEELINT_CONFIG at a configuration file to use it for every file, regardless of project files. If the variable is set but the file does not exist, it is ignored and normal discovery continues.

Your Home Directory

A coffeelint.json in your home directory acts as a personal fallback for projects that have no configuration of their own. The home directory is taken from USERPROFILE, HOME, or HOMEPATH, in that order.

How Configuration Is Discovered

When you do not pass -f or --noconfig, CoffeeLint looks up the configuration for each file separately, starting from the directory that contains the file (or the current directory for --stdin). It uses the first match:

  1. The file named by COFFEELINT_CONFIG, if that file exists.
  2. The nearest package.json found by walking up from the file's directory, if it contains a coffeelintConfig section.
  3. The nearest coffeelint.json found by walking up the directory tree.
  4. coffeelint.json in the home directory.
  5. If nothing is found, the built-in defaults.

Because discovery is per file, a monorepo can have different configurations per package. For example:

repo/
├── coffeelint.json          # used by repo/tools/*.coffee
├── tools/build.coffee
└── packages/
    └── api/
        ├── package.json     # has a coffeelintConfig section: used by api files
        └── server.coffee

Note: Only the nearest package.json is examined. If it has no coffeelintConfig section, CoffeeLint moves on to searching for coffeelint.json; it does not look for another package.json further up.

Explicit Configuration with -f

coffeelint -f <path> bypasses discovery and uses one file for everything. If the file contains a coffeelintConfig key (that is, it is a package.json), that section is used. Note two differences from discovered configuration:

  • extends is not applied to files loaded with -f. Inheritance is only processed during automatic discovery.
  • A malformed -f file makes CoffeeLint exit with a JSON parse error, whereas a malformed discovered file only prints Could not load JSON file '...' to standard error and is then treated as if no configuration had been found, so the defaults apply.

Disabling Configuration

--noconfig ignores everything above, including -f, and lints with the built-in defaults. This is useful for reproducing behavior or for quick checks.

How Your Settings Merge with the Defaults

For each built-in rule, CoffeeLint starts from the rule's defaults and overlays the keys you set. The merge is shallow:

  • Keys you set replace the default values.
  • Keys you do not set keep their default values.
  • Nested objects are replaced as a whole, not merged.

That last point matters for colon_assignment_spacing, whose spacing option is an object:

{
  "colon_assignment_spacing": {
    "level": "error",
    "spacing": {
      "left": 0,
      "right": 1
    }
  }
}

Always specify both left and right. If you only set right, left is undefined and the rule will flag every same-line colon assignment.

Rules you do not mention at all keep their default level and options. Rule names that CoffeeLint does not know are silently ignored, so a typo like max_line_lenght simply has no effect. Run coffeelint --trimconfig to see which of your settings are actually recognized.

Sharing Configuration with extends

A discovered configuration can inherit from a shared configuration published as a module:

{
  "extends": "coffeelint-config-mycompany",
  "max_line_length": {
    "level": "warn",
    "value": 120
  }
}

How it works:

  • The extends value is passed to Node's require, so it must resolve to a JSON file or a module that exports a configuration object.
  • Inheritance is per rule: if your file defines a rule, your entire rule object wins; otherwise the parent's rule object is used. Options are not merged between the two levels.
  • extends is processed only for automatically discovered configuration, not for -f.
  • require resolves the name from CoffeeLint's own installation. Install the shared configuration package in the same project (npm install --save-dev coffeelint-config-mycompany) so it sits alongside CoffeeLint in node_modules.

Loading Third-Party Rules from Configuration

Rules that are not built in are loaded by adding a module key to the rule's entry:

{
  "no_forbidden_names": {
    "module": "coffeelint-no-forbidden-names",
    "level": "error"
  }
}
  • The key (no_forbidden_names) must match the name the rule declares, or CoffeeLint throws Mismatched rule name.
  • The module value follows npm naming and may differ from the rule name.
  • For discovered configuration, the module is resolved from the directory of the file being linted, with .js, .coffee, .litcoffee, and .coffee.md extensions allowed. Otherwise it is resolved from the current directory, then globally, then as a relative path.

See Writing Custom Rules for creating such modules.

The coffeelint Section: Transforms and Compilers

A special top-level key named coffeelint configures preprocessing rather than a rule:

{
  "coffeelint": {
    "transforms": ["coffee-react-transform"],
    "coffeescript": "iced-coffee-script"
  }
}
  • transforms: a list of modules, each exporting a function that receives the source text and returns transformed source. They run before linting, for example to turn JSX-flavored CoffeeScript into plain CoffeeScript.
  • coffeescript: a module to use instead of the bundled coffeescript compiler.

Both features come with caveats. Read Transforms and CoffeeScript Flavors before using them.

A Complete Example

This is the configuration CoffeeLint's own repository uses for its source code. It is a good model of a minimal, intentional config: only deviations from the defaults are listed.

{
  "arrow_spacing": { "level": "error" },
  "line_endings": { "level": "error" },
  "indentation": { "value": 4 },
  "colon_assignment_spacing": {
    "level": "error",
    "spacing": { "left": 0, "right": 1 }
  },
  "space_operators": { "level": "error" },
  "cyclomatic_complexity": { "value": 11, "level": "warn" },
  "no_debugger": { "level": "error", "console": true },
  "spacing_after_comma": { "level": "error" },
  "no_unnecessary_double_quotes": { "level": "error" },
  "braces_spacing": { "level": "error", "spaces": 1 },
  "eol_last": { "level": "error" }
}

Best Practices

  • Commit your configuration (coffeelint.json or coffeelintConfig) so that every developer and CI run uses the same rules.
  • Keep it minimal: store only deviations from the defaults and use --trimconfig to clean up after experimenting.
  • Use warn to introduce rules gradually: enable a new rule as a warning, clean up the codebase, then promote it to error.
  • Avoid relying on the home-directory fallback for shared projects, since teammates will not have your personal file.
  • Prefer inline directives over global relaxations for one-off exceptions. See Inline Directives.