# Introducing ls-lint (opens new window) v2.3.0

Today, we are celebrating more than 5 million ls-lint (opens new window) downloads with the v2.3.0 release.

# Prologue

Around 4 years ago, something weird happened. The coronavirus changed the world overnight. Pretty intimidated and scared, I packed my bag and left Berlin for some weeks to move to my ex-girlfriend in Kiel, in north Germany. Together, on 30 square meters, no toilet paper, and a self-constructed book desk for both of us, the next few days were very easy to predict.

At this time, I worked with a small team of around 5 to 8 devs. Our monorepo was a nightmare: everyone did what they wanted. I was pretty bored, so I decided to put an end to it. In around 3 days, I created this thing called ls-lint, a small tool to lint your project filesystem.

Within hours, this small tool received hundreds of GitHub stars and Reddit upvotes. In no more than a few hours, Evan You (opens new window) accepted my pull request to include ls-lint into Vue.js 2 — pretty sure I will never forget this feeling (thank you, Evan).

Today we are celebrating 5 million ls-lint downloads. It's beautiful to see that ls-lint is used by some of the largest open source projects and companies on our planet. With this, I am happy to announce ls-lint v2.3.0 — the by far biggest update yet.

# What the heck is ls-lint?

ls-lint is an extremely fast directory and filename linter that brings some structure to your project filesystem in an easy way

ls:
  .js: snake_case
  .ts: snake_case | camelCase
  .d.ts: PascalCase
  .html: regex:[a-z0-9]+

ignore:
  - node_modules
ls-lint src/test/Test.js failed for rules: snakecase
src/test/YouTube.js failed for rules: snakecase

# What's new in v2.3.0

ls-lint v2.3.0 comes with some of the most requested features from our community.

# Allow specifying individual files and directories and error output format

With #215 (opens new window) and #216 (opens new window) it is now possible to run ls-lint on individual files and directories and return the error output in the JSON format. This opens the world for tools like lint-staged (opens new window) and husky (opens new window). Aside from that, this closes the gap for future IDE plugins (feel free to contact me).

ls-lint --error-output-format json file-1.js file-2.js

# Wildcard extension support

By #217 (opens new window) it is now possible to use wildcard extensions for files. With this support, you are no longer forced to add any possible file extension to your .ls-lint.yml configuration file, for instance:

ls:
  .go: snake_case
  .pb.go: snake_case
  .pb.validate.go: snake_case
  .json: snake_case
  .yaml: snake_case
  .tf: snake_case
  .yml: snake_case
  .bzl: snake_case
  .sh: snake_case
  .proto: snake_case
  .js: snake_case
  .service.js: snake_case
  .vue: PascalCase
  .ts: snake_case
  .html: snake_case
  .md: SCREAMING_SNAKE_CASE

  components/**/{auth,account}:
    .js: snake_case
    .vue: PascalCase
    .ts: snake_case
    .html: snake_case  

can be now minimized to this configuration file:

ls:
  .*: snake_case
  .*.js: snake_case
  .*.*.go: snake_case # or .*.*.* or pb.*.go ... 
  .md: SCREAMING_SNAKE_CASE

  components/**/{auth,account}:
    .*: snake_case
    .vue: PascalCase

# Exists rule

#223 (opens new window) ships the exists rule. Now it's possible to allow or disallow N or N-M files for a given extension, which brings a variety of configuration options. The exists rule only applies to the directory itself, not to subdirectories.

Imagine you want to restrict all component subdirectories to only having one .ts and one .test.ts file:

ls:
  components/*:
    .dir: kebab-case
    .*: exists:0
    .ts: kebab-case | exists:1
    .test.ts: kebab-case | exists:1

exists also works for directories:

ls:
  components/{auth,account}:
    dir: exists 
    .*: ...

    '*':
      .dir: exists:0 # no subdirectories allowed

and ranges:

ls:
  .foo: exists:1-10

# Extending configurations

This feature already landed in v2.2.0, but never got documented. That being said, I'm trying to catch it up here. The --config option now provides a way to specify a custom path for your ls-lint configuration yml or yaml file:

ls-lint --config .ls-lint.(yml|yaml)

But it gets better: it is now possible to specify N --config options that can be merged together.

Imagine you want to have one global configuration for your company, but still want to have a configuration in your repository that can override or extend your base company configuration:

# company .ls-lint.yml base configuration

ls:
  .go: snake_case
  .js: kebab-case
  .ts: kebab-case

ignore:
  - node_modules
# repository .ls-lint.yml configuration

ls:
  components:
    .vue: kebab-case

A good approach for sharing your company .ls-lint.yml base configuration would be a designated GitHub repository or NPM package.

With that being said, it's now possible to run ls-lint with a combination of both of your .ls-lint.yml configuration files:

ls-lint --config node_modules/@your-company/ls-lint-global-config/.ls-lint.yml --config .ls-lint.yml

# Final Words

Thank you for reading, thank you for all the contributions, and feel free to clean up your project filesystem

image

Lucas Löffel, 16.07.2024
GitHub: ls-lint (opens new window)