Naming files and directories in JavaScript projects

kevanstannard

Kevan Stannard

Posted on April 30, 2022

Naming files and directories in JavaScript projects

A brief story of naming in a project

Getting started

File names start out easy:

  • app.js
  • utils.js

Directory names also often start out easy:

  • /components/
  • /utils/

Add a utility file with multiple functions

Let's add a utility file named "product utils". This is where things start to get hard.

  • product-utils.js
  • productUtils.js
  • ProductUtils.js

There is no particular guideline to follow here, so let's choose product-utils.js for now.

Add a utility file with a single function

Next we need to create a utility file that contains a single function named calculateSalary.

What to name this file?

And do we use a default export or not, since its just one function?

  • calculateSalary.js
  • calculate-salary.js

Here calculate-salary feels strange since the function is named calculateSalary, so lets go with calculateSalary.js.

import calculateSalary from "./calculateSalary";
Enter fullscreen mode Exit fullscreen mode

However, now we have calculateSalary.js and product-utils.js. Should we rename product-utils.js to productUtils.js? That also feels strange since the product utils file contains many functions? Let's leave as-is for now.

Add a React component

Next we need to add a React component named ProductCard.

Easy, that file should be named ProductCard.js and the component is the default export.

However we're starting to get a mix of naming conventions now, which feels uncomfortable, but also kind of makes sense.

And what about when new people join the team? That's OK, we'll just teach them the convention, easy.

Export a utility function from a React component file

Our React component file has the component as the default export, so let's make the utility function in that file a regular non default export.

So we'll have:

import ProductCard, { makeProductPrice } from "components/ProductCard"
Enter fullscreen mode Exit fullscreen mode

Our React component is growing

Our Product Card is getting a bit bigger, and need to be split into multiple files, so we'll need to move it to it's own directory now. What to name that directory?

How about /ProductCard/? That matches the component name and no need to change import statements, but is different from other directory names.

How about /product-card/? It's a nice generic name, but it means our imports "from ProductCard" will all need to change.

And what about /productCard/? Also a nice generic name, but no particular reason to use this for a React component.

Let's go with /ProductCard/.

Our Product utils are growing

Our product-utils.js file is growing now and need so be split into multple files, but we want to put them into a directory. What to name that directory?

How about /ProductUtils/? Nope, that's the convention for component directories.

How about /product-utils/ or /productUtils/? Time to roll some dice 🎲 🎲 🎲 and /productUtils/ is the winner 🎉.

New developer joins the team 🎉

A new person joins your team. Unfortunately nobody has time to explain the conventions. They sees variety of different naming strategies. They've used a completely different naming strategy in their previous project. They decide to apply their own conventions to the naming. Awesome 🙌.

A Possible Solution

Let's review what happened in this project.

In most cases the file or directory name was influenced by its content. We have a lot of different kinds of content, so we end up with many different kinds of names.

Ideally a good naming system should be intuitive, but most of all simple.

So maybe we can look at this from a different perspective, consider an abstraction for our files and directories:

  • Consider that all directories are the same kind of thing.
  • Consider that all files are the same kind of thing. Fortunately they are already the same kind of thing; a module.

File naming

First, if we consider that all files are modules, then we can base our naming on that.

Second, to keep things simple, consider that modules are containers and you only access the contents via the container, meaning no default exports.

You can choose any naming convention you prefer, providing all files use the same naming convention.

Directory naming

Directories are already containers.

So you may like to use the same naming convention as you did for files.

However what's important is that all directories use the same naming convention.

An Example

Considering the scenarios above, here is what your code may start to look like.

Using PascalCase for both directories and files.

import { App } from "App";

import {
  ProductCard,
  makeProductPrice
} from "Product/Components/ProductUI";

import {
  calculateSalary
} from "Payroll/SalaryCalculator";

import {
  findProductsOnSale,
  calculateProductPrice,
} from "Product/ProductUtils";
Enter fullscreen mode Exit fullscreen mode

Or using camelCase for both directories and files.

import { App } from "app";

import {
  ProductCard,
  makeProductPrice
} from "product/components/productUi";

import {
  calculateSalary
} from "payroll/salaryCalculator";

import {
  findProductsOnSale,
  calculateProductPrice,
} from "product/productUtils";
Enter fullscreen mode Exit fullscreen mode

Using kebab-case for both directories and files.

import { App } from "app";

import {
  ProductCard,
  makeProductPrice
} from "product/components/product-ui";

import {
  calculateSalary
} from "payroll/salary-calculator";

import {
  findProductsOnSale,
  calculateProductPrice,
} from "product/product-utils";
Enter fullscreen mode Exit fullscreen mode

Objectively it's a simple strategy that anyone can apply.

If you are also using ESLint or TypeScript, then you have an additional benefit where if you rename a function or component in a file, then you'll be prompted to rename your imports as well, keeping consistent naming everywhere and keeping them searchable.

This is a stylistic matter

This is not really a naming discussion per se, it's really a stylistic discussion which is subjective so it can frequently lead to bike shedding.

In matters of subjectivity if you're able to find a simple guideline, and then follow it independent of personal preferences it can eliminate a whole category of discussions, leaving time for more important matters.

💖 💪 🙅 🚩
kevanstannard
Kevan Stannard

Posted on April 30, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related