A Case For Kebab-Casing
Let's talk about naming files and directories in JavaScript. If you do a search for official naming conventions in JavaScript, you'll notice a few things:
- There aren't any official naming conventions.
- So many opinions.
This has led to a lot of confusion in the industry where the only conventions that seem to stick tend to be from whichever's library or code base gets the most traction and makes the most noise. I'm going to add to that noise (just a little bit 😜).
History & Prior Art
Permalink to History & Prior ArtIf you're more interested in a tl;dr or already have enough context, skip down to My Take below. Otherwise, read on!
The Web
Permalink to The WebMuch of JavaScript's naming conventions have been influenced by the web itself. While they are more flexible than you'd think, with URLs, the predominant style is kebab case:
https://www.my-dope-site.com/some-page
This means that the related files and directories are often cased the same:
/my-dope-site
/some-page
index.html
my-functions.js
index.css
/my-other-page
index.html
banner.jpg
To make things murky, there are cases where camel-case is found and actually encouraged: query strings:
https://www.my-dope-site.com/search?searchPhrase=wowsers
Regardless, the majority of things are kebab case.
JavaScript Naming Conventions
Permalink to JavaScript Naming ConventionsFortunately, JavaScript itself has effectively standardized on camel-case for variables and function names (with exceptions for class names). But unfortunately, this adds to the confusion of "how should I name my files?"
Node.js & NPM
Permalink to Node.js & NPMNode.js is great but only added to the confusion for file-naming conventions. All the built-in modules are snake-cased.
You'd think that this would be the standard but NPM (the default package manager) came along and standardized on kebab-casing! You literally can't include uppercase letters in an NPM package name. It makes sense since the package name was going to be used in the URL for the package page, but because you're more likely to pull in an NPM package than raw Node, you will see kebab casing much more often.
React, linting, & AirBnB
Permalink to React, linting, & AirBnBWhen React came out, there really wasn't a standard for file names. Since the files needed to be transpiled, it sort of made sense to follow whatever standard you followed for your Node.js files, but others followed common naming standards from the web. Even the React team itself was inconsistent with their file naming conventions.
AirBnB was an early adopter of React and open-sourced an opinionated style standard. One of those opinions is to align the name and casing of the file to its default export. This means that files that are just functions should be camel-cased (because of JS function conventions), and React files should be Pascal cased (because React requires Pascal casing for components).
AirBnB's style standard gained so much traction that the React team itself started following it. This is probably the biggest reason to follow the camel/Pascal casing standard, but new challengers have started to go against it.
Next.js & other libraries
Permalink to Next.js & other librariesWhile there are many popular libraries that still adhere to AirBnB's style guide, some other popular libraries are shifting back to kebab casing, the biggest example being Next.js. Others include Tailwind, ShadCN, & Chakra UI. They don't say why they followed this standard in their contributing guidelines, but I have some guesses as to why.
My Take
Permalink to My TakeAs you can see, because of how fragmented the JavaScript community is on file naming, there really isn't any one true standard. In a professional setting, it comes down to what the team wants and aligning to that standard.
But given a choice, I prefer kebab-casing. Here's why:
- There's enough prior art through NPM packages alone to align to it.
- Both Windows and MacOS are case-insensitive (by default). If you've ever renamed a file with Git and got into a weird situation where it still thinks the prior spelling exists, you'll know what I mean.
- Files with acronyms become a non-issue. How do you name a file for a function that has a name like
getUSATheme
? Even the name of the function is controversial (I prefergetUsaTheme
), but the file name becomes simple:get-usa-theme.js
. - More consistent since there isn't a question as to what the casing should be (it's a React component so Pascal case, it's not so camel-case, it's a directory so... what do I do here?)
- The community seems to be heading this way.
- It's more "webby" 🤓.
- I personally think it reads better (see below).
Here's a contrived project that aligns to what you might see in a project that aligns to AirBnB's standard:
/my-project
/src
/components
/MyComplexComponent
AnotherPart.tsx
index.ts
MyComplexComponent.tsx
SomeComponent.tsx
useComplexHook.ts
App.tsx
SideNav.tsx
styles.css
/util
someUtil.ts
formatCustomJSON.ts
index.ts
package.json
Now with kebab-casing:
/my-project
/src
/components
/my-complex-component
another-part.tsx
index.ts
my-complex-component.tsx
some-component.tsx
use-complex-hook.ts
app.tsx
side-nav.tsx
styles.css
/util
some-util.ts
format-custom-json.ts
index.ts
package.json
Yes, I know a few of those points are completely subjective. But I've lived in both styles of code bases, and I've seen much more naming confusion from AirBnB-style naming than simple kebab-casing.
Have you experienced this differently? Is there something I haven't considered? Hit me up on the socials and let me know! If you haven't tried kebab-casing in a project, I recommend giving it a shot. You might actually like it.