This or that? Component Names: index.js or Component.js

I’m not sure if you’re aware, but there are sometimes different ways to do the same thing. Crazy, right? As a consultant I get to see a lot of different codebases, and I try study other projects’ architecture in order to better understand this Brave New JavaScript World we’re living in.

I threw this out here on Twitter about two different ways folks name modules:

And got a wealth of responses. There’s some good strong opinions about this stuff, so let’s break down the pros and cons of each approach.

Option 1: index.js

The spirit of this approach is that for each component, there’s a component directory and inside it lives an index file. So Button/index.js and MediaBlock/index.js and Breadcrumbs/index.js and so on.

Pros

  • Don’t have to be redundant in your import statement. So to use a Button component developers would include it like this:
    import Button from 'Button' 

    rather than like this:

    import {Button} from Button/Button.

    That makes things cleaner, which seems to make everyone pretty happy.

Cons

  • Makes IDE tabs messier. Most modern editors will differentiate between two index.js files by smartly including the parent directory of the index.js file inside the tab. However, that ends up crowding up the tabs, and if you’re anything like me you keep a lot of tabs open at any given time.
  • Makes fuzzy file searching harder. A lot of people shared that hunting down a specific file is hard when all the files are named the same thing.

Option 2: Component.js

Pros

  • Cleaner editor environment – Editor tabs are cleaner because the software doesn’t have to display the directory in, which keeps things tidier.
  • Makes searching easierCmd + T does its thing and can quickly pull up the appropriate file with less hassle.
  • Feels more natural – This is just my opinion, but for me it seems natural to do my work on the Card component in a file called Card.js. Is that crazy?

Cons

  • Have to be redundant in your import statement. We’re back at import {Button} from Button/Button, which is definitely awkward and becomes one more thing to find and replace when things get renamed.

Option 3: Both Component.js and index.js

A new challenger emerges! Lots of people pointed out that both approaches are possible. The idea of this approach is to have Component.js contain the guts of the component, while index.js merely imports that component file and exports it back out again. So Modal.js includes all the great stuff that makes a modal a modal, and then the adjacent index.js file looks like this:

export { default } from "./Modal";

And that’s it.

Pros

  • Retain cleaner imports – get the benefit of more succinct imports, so you have import Modal from 'Modal', which is nice.
  • Cleaner editor environment – The editor isn’t gunked up by a bunch of directory names and doesn’t look like index.js | index.js | index.js | index.js | index.js | index.js

Cons

  • Extra files in your project. Having both Component.js and index.js means managing and juggling additional files. If you’re copying another component, you may forget to open the index.js to rename the export to the new name.
  • Muddies up file searching – now searching for modal in our trusty Cmd + T tool doesn’t just return the component file, but also the index file as well. This can be confusing.

On my current project we opted to go this route and as of right now it’s going swimmingly. There’s something fantastically logical about having a file called Breadcrumbs.js open as I work on the breadcrumbs component. But then I also like the ergonomics of not having to write Breadcrumbs Breadcrumbs Breadcrumbs (Beetlejuice! Beetlejuice! Beetlejuice!) in order to include it somewhere else.

Takeaways

Whichever way you decide to architect these things, make sure you codify those in your frontend guidelines and make sure that everyone contributing to the codebase is following those guidelines. Better yet, make it easy for team members to spin up a new component using shared conventions by using something like a command-line tool. I’m currently using Generact, which copies an existing component and swaps out its name. I created a Boilerplate component folder that stubs out all the files any component would need, and I use that CLI tool to copy the boilerplate and rename it PageHeader or whatever I need. (If there’s a more sophisticated CLI tool or better way to do all this please let me know!)

I wouldn’t profess to be a JavaScript wizard, which is why I enjoy looking over my shoulder to see what others are doing. I don’t know why I still think I’ll stumble upon some Objective Truth, and I don’t know why I still feel that This Is Obvious To Everyone Except You, Brad feeling. I’m heartened that when I throw stuff like this out there, I witness people with strongly held opinions on either side provide thoughtful rationale for their decisions. To me, there’s some comfort in knowing there’s no One True Way.