Hello Adonis - Journey to the future

Official Website http://adonisjs.com

Being a JavaScript developer, I adopted Node Js in its early days and no matter what, it has been a joyful journey.

Npm being the largest package manager (http://www.modulecounts.com) offers a bunch of tools to improve your everyday workflow. I myself have used nearly every popular package until I reached the point of saturation.

This saturation point is the real factor, I decided to write Adonis Js and approached things differently from all other libraries and frameworks offered by the community. This post is not a comparison to any existing frameworks, in fact, an opportunity to share the broader view of Adonis Js.

I generally receive questions on why to use Adonis Js over Sails Js or Express/Koa.

Express/Koa are thin wrappers over the Node Http server, which may be best suited for certain applications but the majority of applications requires a database layer, a mailing library, project structure and, more importantly, ease to manage everything.

As I mentioned earlier, Npm has ample of packages to fulfill these requirements but they have their own cost.

  1. The project structure will not be familiar to a new developer joining your team.
  2. How to approach the binding between your routes and controllers as requiring everything inside your routes file is something you will never enjoy.
  3. Where to store configuration for different environments?
  4. How to write tests without firing up the entire server?

Some of these questions are answered by Sails Js as it comes with a predefined structure and commonly used conventions.

At my heart, I have always felt something hacky about Sails Js, as it is a wrapper on top of Express with preloaded controllers and models into the memory.

Also, their official documentation http://sailsjs.org/documentation/concepts/testing talks about firing the actual Http server in order to write tests, which is not something I am a big fan off.

Hello Adonis #

It was important to discuss the history and challenges which gave birth to Adonis.

Adonis is a different breed altogether, from the very first day my focus has been to write a maintainable solution and add some quality to the project, instead of rolling out another Node Js framework.

The framework offers one of the best syntax to achieve desired results, instead of losing your way inside nested JSON structure. Don’t believe me?

Routing #

  .get('/user/:id', 'UserController.show')

// or

Validation #

const rules = {
  username: 'required',
  email: 'required|email',
  password: 'required_when:oauth,false'

const validation = yield Validator.validate(data, rules)
if (validation.fails()) {

IoC Container #

Being beautiful on the outside, Adonis is structured beautifully inside. It all starts with the IoC container, which is a box to save objects and their dependencies with a unique name called Namespace.

Instead of just holding dependencies, it does some really cool stuff behind the scenes to resolve dependencies in the most transparent way. Let’s take an example of Redis class.

class Redis {
  constructor (options) {
      this.client = new Client(options.port, ...)

As you can see Redis class is dependent upon some configuration to connect to the Redis server. In the plain Javascript world, you will pass the configuration to the redis constructor and your life is good.

const config = require('./config')
const redis = new Redis(config.redis)

But Adonis makes the entire process of initiating the class transparent and keep your code less verbose.

Ioc.bind('App/Redis', function (app) {
   const config = app.use('App/Config')
   return new Redis(config.redis)

and now anywhere inside your application you can use App/Redis to get the instance of Redis class.

const Redis = use('App/Redis')

Christopher Pitt did a great job explaining how to use the Adonis IoC container to have a happy programming life. https://medium.com/@assertchris/effortless-javascript-modules-f6c1059d11d4#.nc2epos1d

Ace - The Maestro #

When was the last time you wrote a terminal command? If you did then you will be amazed how easy it is to write a command using Ace.

ace is a command line wrapper which makes it easy to write terminal commands without getting into the mess of parsing CLI arguments.

class Greet {
  get signature () {
      return 'greet {name}'

  get description () {
     return 'Greet a user with their name'

  * handle (args, options) {
       this.info(`Hello ${args.name}`)

Yes! that’s all. signature defines the name of the command and it’s requirements. *handle method is called every time a given command is invoked inside the terminal.

ace greet John Doe
// prints - Hello John Doe

Adonis extracts all the boilerplate code required to write Http applications and offers you the best possible API. It makes use of

  1. Es6 generators to get rid of callbacks.
  2. Database migrations/seeds and factories.
  3. Lucid - An implementation of Active Record.
  4. Dot notation to access nested keys inside an object.
  5. IoC container to resolve dependencies and keep your code testable.
  6. Tested project structure with predefined directories to keep your code well organized.
  7. Beautiful documentation to quickly get started.

Future of Adonis #

Adonis has the rock solid core where every piece of code is written independently and tied up together inside the IoC container. In the process of being the most stable framework, here’s how we have defined our roadmap.

3.0 Release #

Within the span of 6 months, 3rd version of the framework is about to release. It will have exciting features like Model Hooks, Events Provider, Authentication Provider and bunch of other improvements.

As we iterated really fast, now is it time to release the most stable version of the framework. The majority of the code base has been tested and API has been locked. This can be time for you to the write your next ambitious web application and enjoy the beauty of Adonis.

RoadMap #

Trello is the best place to track the framework progress and also leave your suggestions. Also here is a quick summary.

  1. Sample applications to be used for the reference.
  2. Take documentation to the next level and make beginners feel right at home.
  3. A bunch of screen casts.
  4. Cache, Queue and Redis provider.

Now read this

Changing Route.url behavior

The Route.url method returns a fully qualified URL to a registered route. For example: // register route Route.get('user/:username', 'UserController.show') // following returns - user/virk Route.url('user/:username', { username: 'virk'... Continue →