Generate and files from directory structures

Usage no npm install needed!

<script type="module">
  import neptuneNamespaces from '';


Neptune-Namespaces Build Status

Purpose: DRY CommonJS Modules

Are you working with dozens or hundreds of JavaScript, CoffeeScript or CaffeineScript files? Wouldn't you like some way to easily organize them into modules? Are you already organizing your files into directories? If so, aren't you duplicating all the information encoded in your directory structure in your code's require statements?

Make your directory structures work for you, and Don't Repeat Yourself!

What does NN do? An Example

Suppose you have this directory structure:


The files look something like this:

# geometry/shapes/
module.exports = class Circle

Then run:

# in bash
npm install neptune-namespaces
neptune-namespaces --root geometry

# in the CoffeeScript node.js shell
Geometry = require "./geometry"

# Tada! All your classes are loaded and accessible as:

What is it?

Given a directory structure of source files, Neptune-Namespaces generates runtime namespaces for your source-code. It outputs one pair of and files per directory.

Neptune-Namespaces is an

  • opinionated
  • convention-over-configuration
  • CommonJS
  • directory-structure-based
  • namespace-generator
  • for JavaScript, CoffeeScript and CaffeineScript
    • more could easily be supported - ask!

What does it do?

  • Inputs: a directory structure with source files
  • Outputs: a pair of CommonJS modules for each directory in your source structure
    • - exports the namespace object for that directory
    • - exports the namespace object and loads, via require, all nested namespaces and modules.


  • Clear, standard way to organize complex source-file structures
  • Require one directory and automatically load every source file in its sub-structure
  • Automatic runtime namespacing based on directory names.
  • Write less code! Most requiring is handled for you.
  • Easier Refactoring
    • Adding files/dirs is easier: they are automatically 'required' and available for use.
    • Removing files/dirs is easier: no need to manually remove related 'require' statements
    • Renaming files/dirs is easier: no need to update 'require' statements
    • Moving files/dirs is easier: after all, a move is just a remove + add

Core Design Goals

  • convention-over-configuration (CoC)
  • simple, powerful and automatic module namespacing
  • treat directories as modules (require a directory, get everything inside)
  • reduce human-written-source-code size


Neptune-Namespaces has an opinion about how you should organize your source files. It is:

  • Directories are modules
  • Directory and file names define their module names
    • they can be: snake_case, lowerCamelCase, UpperCamelCase, dash-case, or "space case"
    • and their module names will be: UpperCamelCase
  • Subdirectories define subnamespaces
  • requiring a directory requires everything inside it
    • with user-controlled exceptions
  • requiring a directory's namespace binds that namespace, with its full namespace path, to the global, root namespace: global.Neptune
  • all namespaces extend the global.Neptune.Base class

Neptune-Namespace modules consist of file pairs:

  • MyDirectory/
    • automatically requires ./
    • automatically requires all source files in that directory
      • each is added to the namespace under the UpperCamelCase version of its filename without extension.
    • automatically requires all sub-directories which are namespace modules
      • each is added to the namespace under the UpperCamelCase version of its directory without extension.
    • See Convention Over Configuration for details on how loading-order is resolved and other useful special-cases.
  • MyDirectory/
    • Defines the namespace using the directory's name:
    class MyDirectory extends Neptune.Base
    • if the namespace already exists, reuses the existing one.
    • automatically requires and binds to the parent namespace:
      • require '../namespace'
      • if there is no parent namespace, it binds to the global, runtime namespace:
        • global.Neptune
      • Note: implicitly requires all ancestor namespaces

Convention Over Configuration

NN uses the CoC design pattern. Instead of config files, your directory structure determines how NN creates and files.

Loading order Convention:

  • files are required before directories
  • files and directories are required in alphanumeric order
  • certain naming-conventions can override the basic load-order. See below.

Prefix Naming Conventions:

  • Dash (-): First-loaded Files

    • required but not added to namespace
    • required before all other files
    • Use case: Fully control the load-order of your files by making a single-dash-file which, by definition will be loaded first, which in turn includes files in your custom order.
    # file: root/MyNamespace/
    global.Foo = class DashFoo
    # file: root/
    MyNamespace = require './MyNamespace'
    # MyNamespace.Foo? == false
    # == "DashFoo"
  • Underscore-prefixed Files and Directories (/^_.+/) Are Private

    • Undrescore-Directories

      • Are not auto-required when you require their parent folder.
      • *Use case: Say you have two deploy targes with a lot of shared code, but each target has some specialized code. For example, if you make these sub-directories: _Client and _Server, you can included their parent from either and not automatically require the other's private code.
      • If manually required, will link itself into the parent namespace as-if it were a normal, non-dot namespace.
      • Example: MyNamespace/_Client/ is NOT required when you: require './MyNamespace'; you can always load it explicitly: require './MyNamespace/_Client'
      • not required by parent namespace
      • Use case: When you want a sub-part of your library to be optional but you want it in the same namespace if it is required.
      • Example:
      # file: root/MyNamespace/.Foo/
      module.exports = class Bar
      # file: root/
      MyNamespace = require './MyNamespace'
      # MyNamespace.Foo? == false
      require './MyNamespace/.Foo'
      # MyNamespace.Foo.Bar? == true
    • Underscore-Files: Ignored

      • not required by parent namespace
      • Use case: These files are completely ignored by NN. Useful if you need to completely escape the NN system.
      • Example:
      # file: root/MyNamespace/
      module.exports = class DotFoo
      # file: root/
      MyNamespace = require './MyNamespace'
      # MyNamespace.Foo? == false
      Foo = require './MyNamespace/.Foo'
      # MyNamespace.Foo? == false
      # == "DotFoo"
    • DEPRICATED: Directories & Files starting with . (Dot) have this same behavior, but due to too many semantic conflicts with existing tools, they are now DEPRICATED. Use "_" starts instead.

Same-Names Conventions:

Special rules apply when a file-name is the same as a Parent or Sibling directory-name.

File-names and directory-names are the same if they are equal (==) after normalizing them with upperCamelCase().

  • Same as Parent: included first; merged into namespace

    • instead of the normal way files are added to the namespace, this file is merged into the namespace class via: namespace.includeInNamespace require './normalizedFileName'
    • See the method Neptune.Base#includeInNamespace for more details.
    • Use case: Handy for adding other things to the namespace class.
    • Use case: Manually control load order with custom requires in this file.
    # file: root/MyNamespace/
    global.loadedLast = "Zoo"
    # file: root/MyNamespace/
    global.loadedLast = "Animal"
    # file: root/MyNamespace/
    require './Zoo' # load Zoo before Animal
    module.exports = foo: "bar"
    # file: root/
    MyNamespace = require './MyNamespace'
    # == "bar"
    # MyNamespace.Animal? == true
    # MyNamespace.Zoo? == true
    # MyNamespace.MyNamespace? == false
    # global.loadedLast == "Animal"
  • Same as Sibling: shadows sibling

    • In this case the file is required, but the directory is not.
    • i.e. The file shadows the directory.
    • Use case: A dot-file with the same name as a non-dot-directory effectively makes the directory optioanal without having to make the directory a dot-directory. This allows you to refactor a directory to be optional without breaking any existing requires by renaming the directory.
    • Example:
    # file: root/MyNamespace/Foo/
    module.exports = class Bar
    # file: root/MyNamespace/
    module.exports = class DotFoo
    # file: root/
    MyNamespace = require './MyNamespace'
    # MyNamespace.Foo? == false
    require './MyNamespace/Foo'
    # MyNamespace.Foo? == true
    # MyNamespace.Foo.Bar? == true
    Foo = require './MyNamespace/.Foo'
    # MyNamespace.Foo != Foo
    # == "DotFoo"


npm install neptune-namespaces


neptune-namespaces [options]

  -r, --root      list one or more --root arguments
  -w, --watch     stay running, watch for changes, and automatically update
  -v, --verbose   enable verbose output
  -s, --silent    suppress all output
  -f, --force     overwrite all index and namespace files

Each root directory specified is processed independently and bound to the runtime root namespace: global.Namespace.


  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request