unicorn/filename-case

Enforce one case style for file names

When userProfile.js, UserProfile.js and user-profile.js are all possible, you need to look up the spelling for every import. Capitals are also easy to get wrong without noticing. import "./userprofile.js" finds userProfile.js on macOS and Windows, where the file system usually ignores case, and fails on Linux. By default this rule requires kebab-case.

Only the file name is checked, not its directories. The extension, underscores at the start and the end of the name, index files and files that start with a dot aren't checked.

Configure#

Off by default. To turn it on:

bunfig.toml
[lint.rules]
"unicorn/filename-case" = "error" # or "warn"

Every option, set to its default. The ones that are commented out are unset by default.

bunfig.toml
[lint.rules]
"unicorn/filename-case" = ["error", {
  case = "kebabCase",
  # cases = <value>,
  ignore = [], # list of strings
  multipleFileExtensions = true,
}]

Examples#

src/userProfile.js1 problem
export function userProfile() {}
src/user_profile.js1 problem
export function userProfile() {}
src/user-profile.jsNo problems
export function userProfile() {}
src/__mocks__/_user-profile.test.jsNo problems
export function userProfile() {}

Options#

OptionDefaultWhat it does
case"kebabCase"The one style to allow: "camelCase", "kebabCase", "snakeCase", "pascalCase", "lowercase" or "screamingSnakeCase".
casesAllow several styles: an object with the names above as keys and true as values. Ignored if case is set.
ignore[]Regular expressions, as strings. A file name that matches one of them isn't checked.
multipleFileExtensionstrueTreat everything after the first dot as the extension. With false, only the part after the last dot is the extension.

A project with React components often wants two styles:

src/UserProfile.jsxwith { "cases": { "kebabCase": true, "pascalCase": true } }No problems
export const UserProfile = () => <section />;
src/user_profile.jsxwith { "cases": { "kebabCase": true, "pascalCase": true } }1 problem
export const UserProfile = () => <section />;

ignore matches against the whole file name, including its extension:

src/LICENSE_header.jswith { "ignore": ["^LICENSE"] }No problems
export const header = "MIT";

In user-profile.testUtils.js, .testUtils.js counts as the extension by default:

src/user-profile.testUtils.jsNo problems
export function render() {}
src/user-profile.testUtils.jswith { "multipleFileExtensions": false }1 problem
export function render() {}