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:
- The file named by
COFFEELINT_CONFIG, if that file exists. - The nearest
package.jsonfound by walking up from the file's directory, if it contains acoffeelintConfigsection. - The nearest
coffeelint.jsonfound by walking up the directory tree. coffeelint.jsonin the home directory.- 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.jsonis examined. If it has nocoffeelintConfigsection, CoffeeLint moves on to searching forcoffeelint.json; it does not look for anotherpackage.jsonfurther 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:
extendsis not applied to files loaded with-f. Inheritance is only processed during automatic discovery.- A malformed
-ffile makes CoffeeLint exit with a JSON parse error, whereas a malformed discovered file only printsCould 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
extendsvalue is passed to Node'srequire, 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.
extendsis processed only for automatically discovered configuration, not for-f.requireresolves 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 innode_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 thenamethe rule declares, or CoffeeLint throwsMismatched rule name. - The
modulevalue 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.mdextensions 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 bundledcoffeescriptcompiler.
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.jsonorcoffeelintConfig) so that every developer and CI run uses the same rules. - Keep it minimal: store only deviations from the defaults and use
--trimconfigto clean up after experimenting. - Use
warnto introduce rules gradually: enable a new rule as a warning, clean up the codebase, then promote it toerror. - 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.