204

What are the naming conventions for files and folders in a large Node.js project?

Should I capitalize, camelCase, or under-score?

Ie. is this considered valid?

project-name
    app
        controllers
            someThings.js
            users.js
        models
                someThing.js
                user.js
        views
            some-things
                index.jade
            users
                logIn.jade
                signUp.jade
    ...
ArronPJ
  • 17
  • 6
Rudiger
  • 6,634
  • 9
  • 40
  • 57
  • 3
    Highly subjective, your directory structure is your own. Personally I like to camelCase since that is what I do in JS – Chad Sep 20 '13 at 23:32
  • 1
    @Chad - in Node.js, `require` takes the directory string as a parameter, which is why it's not *entirely* your own. ie. `require('../app/controllers/someThings');` – Rudiger Sep 20 '13 at 23:34
  • 5
    Node doesn't specify any suggestions or standards for naming modules, just as long as they're valid file/directory names and don't try to override [core module names](http://nodejs.org/api/modules.html#modules_core_modules). For its own modules, it uses a mixture of abbreviated ([`fs`](http://nodejs.org/api/fs.html)), single-word ([`events`](http://nodejs.org/api/events.html)), underscored ([`child_process`](http://nodejs.org/api/child_process.html)), and lowercase ([`querystring`](http://nodejs.org/api/querystring.html)). – Jonathan Lonowski Sep 20 '13 at 23:48
  • 1
    @Rudiger So? You can specify whatever string you want, and directory structure you want you can have (provided your names are valid file names of course). – Chad Sep 21 '13 at 00:14
  • From what I can tell from poking around the more keystone projects like [mocha](https://github.com/visionmedia/mocha/tree/master/lib/reporters) file names like captain-awesome-file.js seem to be common enough. That's what I am going to use at least! – Charles Ferentchak Jan 03 '14 at 00:29

8 Answers8

228

After some years with node, I can say that there are no conventions for the directory/file structure. However most (professional) express applications use a setup like:

/
  /bin - scripts, helpers, binaries
  /lib - your application
  /config - your configuration
  /public - your public files
  /test - your tests

An example which uses this setup is nodejs-starter.

I personally changed this setup to:

/
  /etc - contains configuration
  /app - front-end javascript files
    /config - loads config
    /models - loads models
  /bin - helper scripts
  /lib - back-end express files
    /config - loads config to app.settings
    /models - loads mongoose models
    /routes - sets up app.get('..')...
  /srv - contains public files
  /usr - contains templates
  /test - contains test files

In my opinion, the latter matches better with the Unix-style directory structure (whereas the former mixes this up a bit).

I also like this pattern to separate files:

lib/index.js

var http = require('http');
var express = require('express');

var app = express();

app.server = http.createServer(app);

require('./config')(app);

require('./models')(app);

require('./routes')(app);

app.server.listen(app.settings.port);

module.exports = app;

lib/static/index.js

var express = require('express');

module.exports = function(app) {

  app.use(express.static(app.settings.static.path));

};

This allows decoupling neatly all source code without having to bother dependencies. A really good solution for fighting nasty Javascript. A real-world example is nearby which uses this setup.

Update (filenames):

Regarding filenames most common are short, lowercase filenames. If your file can only be described with two words most JavaScript projects use an underscore as the delimiter.

Update (variables):

Regarding variables, the same "rules" apply as for filenames. Prototypes or classes, however, should use camelCase.

Update (styleguides):

nash11
  • 8,220
  • 3
  • 19
  • 55
bodokaiser
  • 15,122
  • 22
  • 97
  • 140
  • 50
    How interesting and well done is your answer, it's off topic, the topic creator specifically asked for naming convention not for directory structures. When we get to this topic, we expect to know if files are better named with dashes, underscores or camelCase. I will upvote, if this is added to this answer. – Tronix117 Aug 04 '14 at 14:51
  • 8
    @Tronix117 what is the problem? The question asks for "project naming conventions for files & folders?" and naming is not limited to the file name as it also includes the complete path name. – bodokaiser Aug 05 '14 at 06:33
  • 34
    of course, but the author specifically ask "Should I capitalize, camelCase, or under-score?". When he write his exemple, he explicitly put 'someThings' and 'some-things' just to know if it can be considered as valid. When I went to this topic I was expecting to have the answer to this specific question, and to know what is usually used as file naming. I don't say your answer is wrong, it's perfect for its purpose, but incomplete in my mind because he doesn't really answer the main question. – Tronix117 Aug 05 '14 at 10:42
  • 1
    Then don't complain at me but at the title of this question. He marked my answer as correct and did not ask for more details so I see that his question details are wrong. What you do is in my opinion just spreading hate :) - thanks for the down vote – bodokaiser Aug 06 '14 at 11:57
  • 10
    I think you misunderstood me ;). I was just looking for something that I didn't found on the accepted answer, but was specifically asked, not spreading hate in any kind, you're going a bit far on this one. I just wanted you to add some informations about that on the answer, so that people who will look for that in the future will not get in a dead-end. – Tronix117 Aug 06 '14 at 14:35
  • 4
    @Tronix117 Actually, this is specifically why I found myself on this page reading this answer. I was hoping for not only directory structure, but more importantly name conventions (dashes, underscores, camelCase, TitleCase, etc...). Unfortunately, the answer still does not contain it, and it seems `bodokaiser` is taking things too personally for me to jump in and request that his opinion regarding this be added to his answer (as the OP initially asked in their question) (*cough* *cough*). – Swivel Sep 14 '15 at 04:05
  • 2
    @Swivel is this better? – bodokaiser Sep 14 '15 at 09:31
  • @bodokaiser Yes. Thank you! – Swivel Sep 14 '15 at 20:26
  • Hi, I just want to say I found this answer very helpful and it has pushed me in the right direction. I have started my own project tonight using this format and appreciate the additional links. I am somewhat confused about the /lib/static/index.js however... Could someone please help me understand what its doing? I googled node decoupling but its putting me on to some package called broadway... Any insight appreciated and thanks again to @bodokaiser :) – jayrue Nov 25 '15 at 03:53
  • @jayrue thank you for your feedback! I place the static file serving middleware at `/lib/static/index.js` but feel free to place it somewhere else if it is just a one-lines like `app.use(static())`. – bodokaiser Nov 25 '15 at 08:50
  • Thanks so much for the response! So basically is the idea for all the middleware to live in config/index.js and then static/index.js just loads it all in? What exactly is the advantage to doing it like this, is it just for reasons of modularization? This is my first Node project ever and I would really like to follow best practices. Thanks again for your reply. Also, should I put a require in lib/index.js for static/index.js – jayrue Nov 25 '15 at 17:34
  • 1
    @jayrue Not directly. Best you checkout one of my example repositories https://github.com/bodokaiser/nearby/blob/master/lib/index.js good luck! – bodokaiser Nov 25 '15 at 18:03
  • For the lazy, quick link the AirBnB style guide section relating to naming (the file naming conventions are towards the end of the section) - https://github.com/airbnb/javascript#naming-conventions – ctrlplusb Dec 08 '15 at 10:35
  • What about jade files? Also under-score.jade ? – DiPix May 05 '16 at 07:56
  • I think the recommendation for variable names should be removed from the answer, not so much because it wasn't asked in the question, but because even the Node.js documentation uses lower camel case for variables. – Carsten Führmann Jun 18 '18 at 20:01
  • For test file names, use *.test.js (preferred), or *.spec.js or *.test.txt (if text file). I will upvote after you add the files names like this too. – Manohar Reddy Poreddy Aug 23 '20 at 12:29
  • @bodokaiser do you have any guidance on route names. Say there's a GET POST DELETE route of the same name `user` for example. How would you name those files differently? – wongz Apr 13 '21 at 02:38
  • @bodokaiser Wow, I really love this directory structure, and I've been using it in my projects. Is there anywhere you would put user-submitted data, or logs? – ban_javascript Jun 07 '21 at 08:44
199

Use kebab-case for all package, folder and file names.

Why?

You should imagine that any folder or file might be extracted to its own package some day. Packages cannot contain uppercase letters.

New packages must not have uppercase letters in the name. https://docs.npmjs.com/files/package.json#name

Therefore, camelCase should never be used. This leaves snake_case and kebab-case.

kebab-case is by far the most common convention today. The only use of underscores is for internal node packages, and this is simply a convention from the early days.

vaughan
  • 6,982
  • 6
  • 47
  • 63
83

There are no conventions. There are some logical structure.

The only one thing that I can say: Never use camelCase file and directory names. Why? It works but on Mac and Windows there are no different between someAction and some action. I met this problem, and not once. I require'd a file like this:

var isHidden = require('./lib/isHidden');

But sadly I created a file with full of lowercase: lib/ishidden.js. It worked for me on mac. It worked fine on mac of my co-worker. Tests run without errors. After deploy we got a huge error:

Error: Cannot find module './lib/isHidden'

Oh yeah. It's a linux box. So camelCase directory structure could be dangerous. It's enough for a colleague who is developing on Windows or Mac.

So use underscore (_) or dash (-) separator if you need.

yitsushi
  • 1,173
  • 7
  • 6
  • 8
    +1, add the fact that renaming case-sensitive folders in git on a non-cs system is a real hassle. – max Aug 21 '14 at 12:24
  • 11
    I don't really understand the problem with camelCase here. Wouldn't the issue be resolved by naming the file correctly in the first place (lib/isHidden.js)? – Mike Jan 17 '15 at 05:29
  • Hey Mike, the point is that camelCase is going to break on deployment on some systems. I was confused about why my directories were all getting 404s when I deployed from Mac onto a Linux box with a package named "groupPages". I had to change to group-pages to fix things. – tempranova Feb 06 '15 at 10:18
  • 8
    Worse yet: create a camelcase version of a file name and have a careless colleague create a lowercase version in the same directory. Now do a check out in a non-case-sensitive os, and try to figure out why the hell your application isn't working. And yes, this happened. – L0LN1NJ4 Jun 08 '15 at 12:36
  • I like this answer, however I want to point that dash (-) may have some problems too. For example, using Nighwatch test framework I created a page object named admin-login.js. Then I tried to access it from the test script using `const loginPage = browser.page.admin-login()`. I got error `ReferenceError: login is not defined`. Using underscore (_) for the file name solved the problem. I can also imagine that using filenames with dash character in command line can also lead to some problems. Therefore, I'd say that underscore is safest separator for file names in general. – Dragan Nikolic Oct 05 '17 at 21:50
  • As pedantic as I am, I choose to use all lowercase for file names so that I don't run into issues like these. Also, at times I waste time trying to recall if a conjunction was lowercase or camelcase, etc. In addition, it helps with larger teams. The other option is to name the file the same as the class name, but it's hard to prevent inconsistencies there. – Nick Nov 15 '17 at 23:25
  • `const loginPage = browser.page['admin-login']()` obviously for corner cases where you have to reference the filename directly as an object property – Jamie Pate Jun 21 '18 at 16:03
  • The problem isn't really camelCase by itself but rather that on Windows (and on macOS depending on how your filesystem is set up) file names are case-insensitive which means you can use either case and it will still find the file. On case-sensitive file systems like the ones commonly used for Linux distributions (and other un*x systems in general) like ext4 you have to use the _exact_ file name as it is on the file system. – xdevs23 Aug 14 '18 at 07:40
  • I had met this problem before either. Errors occured when we migrated app with folder named by camelCase from CentOS to Windows Server. After that point, I always use lowercase for folder's name. – Rong.l May 08 '20 at 06:27
40

Based on 'Google JavaScript Style Guide'

File names must be all lowercase and may include underscores (_) or dashes (-), but no additional punctuation. Follow the convention that your project uses. Filenames’ extension must be .js.

Vlad Bezden
  • 83,883
  • 25
  • 248
  • 179
2

Node.js doesn't enforce any file naming conventions (except index.js). And the Javascript language in general doesn't either. You can find dozens of threads here which suggest camelCase, hyphens and underscores, any of which work perfectly well. So its up to you. Choose one and stick with it.

Subhas
  • 14,290
  • 1
  • 29
  • 37
  • 1
    It is not actually what node 'enforces', please read this: http://nodejs.org/api/modules.html#modules_folders_as_modules – moka Jan 02 '14 at 16:21
  • index.js is not a naming convention lol. Index js, I am pretty sure, originates back from why every was server based HTML (I was a kid then) but it use to be, when I was 8 or 9 (and yes I wrote HTML at 8 or 9, I mean it was HTML, and it was simple to what we have today) anyway... and it use to be that at the root of the project was an index.html file that actually contained an index of all html files included in the website. I remember that this was an old method for doing things even back in 1995/1996, but that's how sites started out. – JΛYDΞV Oct 25 '22 at 15:50
2

According to me: For files, use lower camel case if module.exports is an object, I mean a singleton module. This is also applicable to JSON files as they are also in a way single ton. Use upper camel case if module.exports returns a constructor function where it acts like a class.

For folders use short names. If there is need to have multiple words, let it be completely lower case separated by "-" so that it works across all platforms consistently.

arunram
  • 623
  • 7
  • 11
1

Most people use camelCase in JS. If you want to open-source anything, I suggest you to use this one :-)

Mathieu Amiot
  • 1,204
  • 8
  • 16
  • 2
    Some projects, such as Locomotive.js are using `camelCase` for controller files. :-) Just depends. I tend to use `PascalCase` for class-like files. – Mathieu Amiot Jan 05 '14 at 01:24
  • @yitsushi seems to raise quite a concern with camel (and pascal) case naming, if you want to create portable modules camel case surely seems a bad idea? – gumaflux Apr 23 '14 at 12:10
  • Yea, camel case is a bad idea as many 3rd party libraries, APIs, modules, frameworks(especially frameworks) will parse your package, and it will assume that the filenames are in kebob format, and code is in camelcase. – JΛYDΞV Oct 25 '22 at 15:45
-1

Here is my idea

project-name
    app
        controllers
            somethings.controller.js
            user-story.controller.js
            users.controller.js
        models
                something.model.js
                user.model.js
        views
            some-things
                index.view.jade
            users
                login.view.jade
                signup.view.jade
Shan Biswas
  • 397
  • 2
  • 8
  • 24
  • This idea of multiple dots is worth taking a closer look at: since we do not need to specify the file ending for `require("something")`, we can create our own app- or framework-specific naming convention for what to put after the first period: in the example `const login = require("login.view")` can emphasize that the default export of that file is _probably_ a `View`-shaped object. I like this, perhaps it can save a few levels of subdirectories too. – conny Jun 25 '22 at 15:21
  • 0 reason to name files with controllers suffix while the folder already contains `controllers` word in the name. It's just absurd – Alexey Sh. Mar 20 '23 at 01:17
  • @AlexeySh. the idea is derived from Laravel where the controller names are attached to it. But your point is valid – Shan Biswas Mar 24 '23 at 11:43