Towards Perfecting Code Organization
Tags: javascript, react, webdev, productivity
Published: 2021-12-21 16:28:23

## Environment and Well-Being
Your environment impacts your well-being.

If you've ever gathered motivation to clean, organize, and decorate your workspace, opened your laptop with a fresh cup of hot coffee, and then carried on with your work for the day, you'll know that this is a proven fact.

Your environment impacts your well-being.

Your coding environment is no exception.

Just like a physical workspace, if a coding workspace is routinely kept organized and neat, it will have a positive impact on your well-being.

So, how can we organize our coding workspaces?

Again, just like with a physical workspace, organization is probably the most significant factor.

A physical workspace may not look neat and tidy, but if things are organized, and a clear pattern for staying organized, then a sense of being overwhelmed is avoided and a productive environment is maintained.

In a codebase, there may be a variety of different patterns of organization. However, the most important thing is to have it organized via a consistent pattern.

It's simple math. 1% is better than 0%.

**An organized but less-than-ideal workspace is better than an unorganized and definitely-less-than-ideal workspace.**

> _If you take away nothing else from this article, at least take away this:_ If you want to improve your developer experience, organize your workspace. It doesn't haven't to be perfect, it just has to be consistent and intelligible.

The first step to perfecting code organization is to organize your codebase. Later on, you can fine tune it to be closer to ideal.

It's a simple fact. It's much easier to reorganize an already-organized workspace.

## Perfecting Code Organization
As for the fine-tuning of a codebase, let's compare and contrast some common approached to code organization (using a React app as our example).

### Grouping Files by Type
One common approach in React applications is to group files by their types/groups:

```
/src
  /components
  /hooks
  /pages
  /functions
```

The benefit of this approach is that it's pretty clear where to look for a `Button` component (let's say) versus where to look for a `Products` page.

The difficulty with this approach is that it doesn't allow for an association between various files and a common experience in the application (sometimes called a "domain").

Or, you have nest a folder named after a domain across all the various top-level directories:

```
/src
  /components
    /product-listing
  /hooks
    /product-listing
  /pages
    /product-listing
  /functions
    /product-listing
```

Then, it can get confusing as to what is a component that it tightly coupled with a domain versus a component that is generic enough to be shared across any domain (for example).

Of course, you could nest `shared` directories to distinguish:

```
/src
  /components
    /shared
    /product-listing
  /hooks
    /shared
    /product-listing
  /pages
    /product-listing
  /functions
    /shared
    /product-listing
```

However, as you can catch with the glance of your eye, there is an obvious problem of duplication.

### Grouping Files by Domain
What if we reverse the hierarchy?

Instead of grouping first by file _type_ and then by _domain_, look what happens when we group by domain and then type:

```
/src
  /shared
    /components
    /hooks
    /functions
    /pages
  /product-listing
    /components
    /hooks
    /functions
    /pages
```

We still have repetition of directories for the various file types, but the domain concepts are centralized to one part of the code.

You can also easily see if a file is scoped to a domain or if it is shared.

There is one development off of this that we will want to make, however.

The `shared` directory is still a bit ambiguous with this domain-driven organization.

There are two main types of shared files:

1. Files that contain project-specific concepts but are used across multiple domains (i.e. `ShoppingCart`, not found in a design system, etc.).

2. Files that contain generic files that could theoretically be consumed in any application (i.e. `Button`, could be found in a design system, etc.). 

For this reason, we can distinguish between `common` (product-specific) and `shared` (generic) files:

```
/src
  /shared
    /components
    /hooks
    /functions
    /pages
  /common
    /components
    /hooks
    /functions
    /pages
  /product-listing
    /components
    /hooks
    /functions
    /pages
```

? **Note:** You can use whatever verbiage you prefer to make the distinction. The important thing is to make a distinction. Also, what constitutes `common` versus `shared` can vary based on context.

### Treating Shared Files As External Packages
A final suggestion to perfect our code organization is to treat the `shared` directory as an external package.

You can achieve this by using [an alias](https://webpack.js.org/configuration/resolve/#resolvealias):

```jsx
// some-component.js

import { Button } from '@shared/components';
```

The advantage of this is that 1) you don't have to deal with long relative imports, 2) you can clearly see the distinction between generic and project-specific files as you would if using an external library, and 3) you can find and replace if you do move the files to an external library.

Once these files are being treated as a separate package, you may want to group the directory by potential external library names as opposed to file types:

```
/src
  /shared
    /design
    /data-visualization
```

> This is a great way to keep shared, generic files in the project for convenience and experimentation before they become an external library.

You can treat this section of the codebase as a "lab" or "staging" for external libraries.

## Conclusion
Remember that 1% is better than 0%.

Your environment impacts your well-being.

Organize your codebase, and then find ways to improve the organization incremental.

The big thing is to have consistency in organization and clarity in where to put what and when.

What do you do to organize your codebase?