JavaScript’s naturally unstructured frame makes it possible to use it in many different ways. However, these ways usually end up being very unreadable. It’s easy to fall into the trap of a tangled, unorganized mess of JavaScript code – especially if you’re a new developer. After all, when you’re under pressure to get the job done and meet your deadlines, it’s natural to ignore the importance of the front end and just focus on “the important part of the application.”
The truth is, unorganized JavaScript can end up representing a large portion of the finished product and, before you know it, you could have a large mess on your hands to maintain or, even worse, someone else to maintain.
These javascript file organization best practices cover every angle of javascript development, including: organizing files for easy source control management, organizing files by feature, following a consistent convention for each file’s filename and more.
When organizing your Javascript files, one of the most important things to do is keep code from one type of element together. This makes it very simple to troubleshoot and update down the road because you’re not going to touch multiple parts of an application when you only need to update a single portion of the code.
JavaScript File Structure Best Practices
JavaScript is one of the most flexible languages out there, and with flexibility comes room to do things the wrong way. Frameworks, like Angular and React, can help set your javascript code structure (or Typescript compiled to JavaScript in Angular’s case). Unfortunately, frameworks can’t always be used in your folder structure. Maybe the business would like to stay away from JavaScript frameworks, or maybe they are just overkill. While frameworks are a good idea in theory, they come with a degree of overhead that can introduce other complexities of their own.
So how should you organize your code when you’re writing an application with a framework? The trick is to explore the world of ES6 JavaScript and basic code organization. Let’s take a closer look at the 5 ways to organize your JavaScript the right way.
1. Comment Your Code
When writing a new function, class, model, constant, or really anything, leave comments behind to help whoever is working on it. Notice that this style of commenting gives you great tooltips in IDE’s like VS Code.
![JSDoc](https://obiztools.com/wp-content/uploads/2022/03/Visual-A1-500x290.png)
There is a side benefit that if you’re are using JSDoc style comments, you will get comprehensive, great looking documentation free of charge!
2. Use ES6 Classes
ES6 has brought a whole host of features to JavaScript, so make use of them! One of these features is classes, which are probably the best way to organize your business logic.
![Es6](https://obiztools.com/wp-content/uploads/2022/03/Visual-A2-500x270.png)
As you can see in the above screenshot, you can structure your models’ in a way that is very easy and simple to read and is also extendable. Extendability is huge! It means you can have a class that inherits particular properties and functions from the base class. As you can see, the PropertyAddress class actually extends from the Address class. This will help you maintain that great principle DRY (Don’t Repeat Yourself).
3. Use Promises in Your Javascript Data Structures
As a junior developer, it is very easy to get into the habit of passing callback functions into other functions. For instance, say you want to fetch a list of employees from the API. Well, you could call that, and pass in a call back function.
![Callback Functions](https://obiztools.com/wp-content/uploads/2022/03/A3-500x99.png)
This, on its own, may look harmless, but what happens when you need to make another call after the employees are done? If you were using callback functions, it could look something like this:
![Callback function](https://obiztools.com/wp-content/uploads/2022/03/A4-500x152.png)
Instead, make use of what’s in your toolkit, Promises. This will allow you to chain call back functions in an organized an easy-to-read way. This also allows you to decouple the callback from the function completely, which means the list method no longer has to worry if there is a callback function or not!
![Java Toolkit](https://obiztools.com/wp-content/uploads/2022/03/A5-500x131.png)
4. Keep Things Separated
When writing JavaScript that is specifically for a “module” that could potentially be reused, put it into its own JavaScript file. Also, if you are writing JavaScript with the intent of performing some functionality that is specific to the page then put it in its own file that is included on the page. Say you’re creating an employee list page, then you could end up with two files: employee.js, and index.js.
![Keep JavaScript modules structured](https://obiztools.com/wp-content/uploads/2022/03/A6-500x105.png)
The employee.js file contains all the model-based logic having to do with an employee — that is not page-specific. The index.js file encompasses things that are specific to that page. This could be something like maintaining a list of employees or what happens when you click an employee.
5. Use Constants and Enums
If you find yourself writing the same hardcoded string again and again, you should create a constant for that. Constants are a great way to make things organized and easily changeable later.
![Enums](https://obiztools.com/wp-content/uploads/2022/03/A7-500x49.png)
If you find yourself having a group of logic that all relate, such as types, enums could be really useful for that. Although JavaScript doesn’t really have “enums,” you can create an object and annotate it using something like JSDoc to help keep things in one place and easily visible.
![JSDoc](https://obiztools.com/wp-content/uploads/2022/03/A8-500x136.png)
How to Manage Your Folder Structure in JS Project Effectively
Everybody has a different view on managing a folder structure, and this happens because of so many factors such as the choice of programming language, the framework that we are using, concepts, best practices, our own additional preferences etc etc etc. This is why there is no such thing like ‘one folder structure for all cases’.
Even it may seem trivial, I think we need to give some time to structure our folders in a project. This is because we can gain benefit from having a folder structure that works.
The benefit of having a great folder structure
Folders are not a code which can have a concept of abstraction. However, folders are still part of our code structure because every time we create a folder, we unconciously create another layer of confusion abstraction.
When we think about abstraction in programming, it generally means that we enable a simpler interface which hides the complexity of how things work behind. When we create a folder, we ‘hide’ some files inside of a folder, and the name of the folder is an ‘interface’ which we expose to the outside world. The outsiders know nothing about the folder before they open the folder and see what is inside.
Abstraction is a form of communication between engineers, and because folder is an abstraction, it is a form of communication too. A good abstraction is the one that doesn’t make us spending too much time to start using it, and a good folder structure is the one that doesn’t make us spending too much time to understand the big picture of a project. Of course, it depends on the size of the project. The larger the project, the more tendency to get more confusing than the smaller project. However, it doesn’t mean that smaller projects are always easier to digest than larger projects. In multiple occasions, I found it difficult to make sense of some folder structures which was supposed to be a simple project.
So in general, folder structure plays a significant role of building a initial communication with engineers. When we create a good communication at the beginning, people will spend less time to read our project structure and start coding.
Rule of thumbs
As I’ve mentioned before, there are many factors which shape our folder structure, thus there is no clear guideline of how to create the best structure for all situations. The best folder structure is the one that sparks joy for you, your team and the project at the moment. If your folder structure just hinder your work, probably there is something wrong with the structure.
To help you manage your folder structure effectively, I have made some rule of thumbs which I’ve gathered from my own experience. You may or may not start from exactly empty repository, but these rules are still applicable whether you are starting from scratch or not.
Keep it as flat as you can
If you ever found yourself exploring a very deep directory, it is like digging a mine. You need to open multiple folders all the way down until you find the ‘gold’, which is the code file that you’re looking for. And if you want to explore the other folder which is located in other part of the directory tree, you need to go back to the parent folders from your current position until you find the starting point which leads the way to the folder. This is why a folder structure which has a deeply nested directory is harder and time consuming to navigate compared to the one that has less.
You might argue that with a good code editor, we can easily do folders and files navigation with its built-in search feature, and I agree with that. I think majority of programmer today have used that feature intensively in their daily workflow. However, this kind of feature is only helpful if we already know what to search. If we are still learning about the project, I believe we will be ‘digging-mine’ the project folders. Therefore, keep in mind that every time we want to add a new folder, we make it harder for other people to navigate on our project.
Aside from navigation concern, a deep folder structure is also not convenient to use in our code. We usually split code into several modules, and different modules can be stored in different folders depending on our categorization. If we want to import a module which is located in a deeply nested directory, we need to write a longer reference to the module.
To flatten a folder structure, we can follow the approach at the example below.
Let’s say we have a folder which has two level of nested directory like this.
helpers/
- number/
-- format.js
-- parse.js
- time/
-- diff.js
-- format.js
- string/
-- parse.js
-- format.js
-- sanitize.js
- object/
-- transform.js
Each folder in helpers
folder has no more than three files, so it is better to just merge all files under the same folder into a single file like this.
helpers/
- number.js
- time.js
- string.js
- object.js
This way, we have reduced the complexity of the structure from two levels of nested directory to one. Now when we know a certain type from a helper function, we just have to look at one file instead of opening multiple files.
Or perhaps your code is so large that it will become ugly if we fit it into a single file. In that case, we can do something like this.
helpers/
- number.js
- time-diff.js
- time-format.js
- string.js
- object.js
Because the time
helpers are supposedly large, we can split it into two files and add suffix into each filename. This way, we can still retain a flat structure without eliminating the clarity of the filename. Pay attention that even though we have chosen to split the time
helpers, it is not necessarily required for the rest of the modules to follow this pattern especially if your helpers are small.
Create folders only when necessary
I often find several cases where people put a folder with only one file or even no file at all. This happens most likely because one of three reasons below:
- Follow other project structure
- Result of using project bootstrapper
- Need to reserve some spaces for future use
Don’t get me wrong, you can copy other people structure or use whatever bootstrapper you like. However, you need to know that you take full controls over your own folder structure. So, if you find some folders that stay empty or just contain one file for quite a long time, you should just remove them. You can add it later when you think you need that folder.
Reserving spaces is probably the most problematic thing on managing folder structure, especially when we just start creating a project. We tend to create a folder even if we aren’t quite sure whether we will use it or not, and probably because we are influenced by other project structure. I think it is much simpler to just stick with our current requirement and not making assumption.
I want to mention one case that happens to pop up frequently in my job. Below is a typical component-based project structure which you might already familiar with.
app/
- components/
- pages/
- App.vue
- index.js
All folders here have a clear structure and naming. Not only we can quickly guess on what kind of files stored inside those folders, we can also figure roughly the libraries that we are using in this project. If look at the structure, it has a pages
folder which is likely to have multiple files in there. Therefore, we can assume that this project has multiple pages and uses a router library. However when we open the folder, it only shows one file.
app/
- components/
- pages/
-- Landing.vue
- App.vue
- index.js
This structure suddenly becomes quite confusing because we didn’t expect for pages
folder to just have a single file, and our previous assumption can be a mistake. When I’m in this situation, I usually open the index.js
to check whether the project uses a router or not. If it doesn’t, then the pages
folder become misleading (and if it does, why??). To improve the structure, we can just put the Landing.vue
file into components
folder, or merge it into App.vue
file.
As you can see that by creating a folder, we can affect other people’s perception when learning our project. Therefore, avoid creating a folder if not necessary.
Create a meaningful name to your folders
I believe that there is nobody that intentionally want to confuse others with a false named folder in a project. However, this can still happen because naming is hard.
Honestly, I can’t give you a straightforward tips for naming a folder, but I always stick to this whenever I’m giving a name to anything related to code:
A name should represent the functionality of the code.
which is for this case, we can say that a folder name should represent a general functionality of the files inside it.
A flat folder structure can be useless if we don’t properly name the folders. So please give a meaningful name to your folders.
If it doesn’t spark joy, restructure early
Folders restructuring is perhaps one of most daunting tasks for engineers, especially if the project has grown quite complex. A lot of errors can happen when we make changes to the folder structure because it will affect on import references when using modules. Because the risk is quite high, many engineers tend to avoid doing refactoring and restructuring.
If we have a flat folder structure, even in a relatively large project, restructuring will be much easier because we have many spaces to move things around (and hence, the first rule of thumbs was made). However if we are working with a deep structure in comparable-sized project and involves a few contributors, a careful planning and clear communication with our peers are necessary in order to keep code conflicts low when restructuring. Even so, we can’t just leave the problem behind just because the process can be quite a hassle.
The best time to restructure folders is when you just start feeling uncomfortable with your own project. You shouldn’t keep this structure any longer because the project will keep growing. And over the time, it will become harder to restructure.
If possible, restructure your folder earlier before it can affect negatively to your work. If it requires a large changes, you don’t have to make a total revamp of your folder structure in one go. You can make a plan to split them into multiple stages so that your peers’ work will be less affected and still keep the restructuring in progress. Plus, it can be easier to revert if there is a faulty in your changes.
With your engineer’s intuition, you can feel it when something is wrong with your project structure. And when that time has come, you should definitely consider to restructure your folder as earlier as possible.
Best Practices
Regardless of the project type, there are several best practices that apply to JavaScript file and directory structure:One object per file
Each JavaScript file should contain code for just one JavaScript object. This pattern is common to other programming languages and generally makes maintenance easier. Having multiple files with single objects reduces the risk of multiple people working on the same file at the same time. Even though today’s source control systems are incredibly good at merging changes from two different people, merge conflicts do still occur. The fewer files you have, the greater the likelihood of merge conflicts. Keeping one JavaScript object per file minimizes this risk.Group related files in directories
If you have multiple objects that are related, put all of those files into a single directory. You might, for instance, have multiple files with code to make a single module. It makes sense to have a directory just for that module containing all of the files. Grouping related files helps developers locate functionality easily.Keep third-party code separate
Conclusion
Javascript best practices are important. They save time. They improve your efficiency. They will turn you into a javascript professional. Even more important than being a good javascript coder is being a good javascript coder who cares about his file organization.
Javascript best practices can be a bit overwhelming for any new developer. First of all, there are so many rules about best practices that it’s hard to know exactly where to get started. Secondly, best practices change over time, so it’s easy to wonder which guidelines still apply today.