traits.js is a minimal, standards-compliant trait composition library for Javascript.

Here is the latest development version.
traits.js is also available as an npm package named 'traits' (thanks to Nathan Stott).

Why traits?

Traits are a flexible language feature to factor out and recombine reusable pieces of code. They are a more robust alternative to multiple inheritance or mixins. They are more robust because name clashes must be resolved explicitly by composers, and because trait composition is order-independent (hence more declarative). To put it simply: if you combine two traits that define a method with the same name, your program will fail. Traits won't automatically give precedence to either one.

Why traits.js?

Because it's minimal, easy to understand and because it plays nicely with the new object-manipulation API defined on Object in Ecmascript 5th edition.

traits.js introduces traits without also introducing classes. In this library, traits are like Javascript's functions: anonymous, first-class and freely lexically nestable.

What about the roles of classes not normally supported by traits, such as instance-private state and constructors to initialize that state? These roles are already supported by Javascript's functions: you can nest traits inside functions that close over the required state, and you can use the function body as the "constructor". Here's an obligatory 'point-and-color' example:

function makeColorTrait(col) {
  return Trait({
    color: function() { return col; }
function makePoint(x, y) {
  return Trait.create(      // create an instance of a trait
   Object.prototype,        // that inherits from Object.prototype
   Trait.compose(           // and is the composition of
     makeColorTrait('red'), // a color trait
     Trait({                // and an anonymous point trait
       getX: function() { return x; },
       getY: function() { return y; },
       toString: function() { return ''+x+'@'+y; }               
var p = makePoint(0,2);
p.color() // 'red'


traits.js is designed to work with the new object manipulation API defined in Ecmascript-262, Edition 5. However, the library is backwards-compatible with Edition 3. The library does not depend on any browser-specific features. To see if it works in your browser, just run the unit tests.

Bookmark and Share