Stop Mixing TypeScript Modules and Namespaces

A long time ago I wrote that you should Stop Mixing TypeScript Internal and External Modules. Well it is time to update my information on this point… because they are now called namespaces, and modules.

So my update is simply this:

Stop Mixing TypeSCript Modules and Namespaces

Let’s back this up with a bit more information.


Namespaces are used to:

  1. Reduce the amount of code in the global scope
  2. Provide a context for names, to reduce naming collisions
  3. Improve discoverability with a hierarchy

Namespace on their own are okay. They replace “lots of things” in the global scope with “one thing per namespace” and if you organise your namespaces well, you’ll actually have “one thing only” in the global scope.

Modules + Namespaces?

But what about namespaces with modules?

  1. Modules add zero code to the global scope. They execute in their own context. Adding namespaces improves this 0%.
  2. Modules already provide a context for names to reduce naming collisions. Adding namesapces improves this 0%.
  3. Modules already allow you to improve discoverability by providing a hierarchy. Adding namespaces impairs this!

Mixing modules and namespaces makes it harder for consumers of your code to find things. It has no benefit over using modules without namespaces. Don’t mix modules and namespaces. Thinking of modules simply as files is understandable as other languages work this way; but TypeScript is long past the “trying to be like C#/Java” phase and is now a language in its own right, with its own patterns. Don’t try to make TypeScript work like your programs written in other languages.


So after more than two years, my advice remains the same. Stop trying to mix modules and namesapces… and prefer modules to namespaces when you are writing a program.