Published: Tue Oct 18 2022 - Avg Reading Time: 5min

AdonisJS - The full stack Typescript framework


A few months back I was working on a Full-stack project using NodeJS with express and MongoDB, this used to be my go to framework for building full-stack applications, usually coupled with vue or react.

As much as I enjoy working with this stack I usually get frustrated at the amount of boilerplate I need to write first and the lack of project structure which really slowed down my development speed. So I decided I need more of a structured framework and set out to scour the internet for a NodeJS framework similar to Laravel, Django or Rails.

Low and behold after hours of searching and almost giving up I stumbled upon AdonisJS after going through their documentation I was hooked!

Here I will go over all the features AdonisJS offers, if you are familiar with Laravel, Django or Rails and you have a strong interest in typescript you should enjoy working with AdonisJS.

What is AdonisJS

AdonisJS is a backend framework. It helps you create data-driven dynamic web applications. Using AdonisJS, you can handle the HTTP requests, query the database, authenticate users, upload files, send emails, and do a lot more.

Creating Routes is super simple

import Route from '@ioc:Adonis/Core/Route'

Route.get('/', () => {
  return 'Hello! This is the homepage of my new app'
})
Enter fullscreen mode Exit fullscreen mode

This how you would query the database within a route using dynamic params.

import Route from '@ioc:Adonis/Core/Route'
import Database from '@ioc:Adonis/Lucid/Database'

Route.get('posts/:id', ({ params }) => {
  return Database
    .from('posts')
    .select('*')
    .where('id', params.id)
    .first()
})
Enter fullscreen mode Exit fullscreen mode

Controllers are your best friend for HTTP requests

Where is my laravel devs?

01 Create a controller

node ace make:controller Posts
Enter fullscreen mode Exit fullscreen mode

02 Implement the required methods

import Database from '@ioc:Adonis/Lucid/Database'

  export default class PostsController {
    public async show({ params }) {
      return Database
        .from('posts')
        .select('*')
        .where('id', params.id)
        .first()
    }
  }
Enter fullscreen mode Exit fullscreen mode

03 Register it with the route

Route.get('posts/:id', 'PostsController.show')
Enter fullscreen mode Exit fullscreen mode

Query database using the ORM

Interacting with databases is super simple using an offical package called Lucid (epic name btw), Lucid has a rich API to perform schema migrations, seed databases with dummy data, and construct SQL queries.

01 Create a new model

  node ace make:model Post
Enter fullscreen mode Exit fullscreen mode

02 Configure columns

import { column, BaseModel } from '@ioc:Adonis/Lucid/Orm'

  export default class Post extends BaseModel {
    @column({ isPrimary: true })
    public id: number

    @column()
    public title: string

    @column()
    public description: string
  }
Enter fullscreen mode Exit fullscreen mode

03 Import and use it inside the controller

import Post from 'App/Models/Post'

  export default class PostsController {
    public async show({ params }) {
      const post = await Post.find(1)
      return post
    }
  }
Enter fullscreen mode Exit fullscreen mode

Render HTML using templates

AdonisJS also ships with a homegrown template engine - "Edge". Edge is really easy to use especially if you are used to React or Vue, using your Frontend JS Framework skills can come in handy here.

01 Create a view template

  node ace make:view posts/index
Enter fullscreen mode Exit fullscreen mode

02 Write the markup

 <div class="article">
    <h1> {{ post.title }} </h1>
    <p> {{ post.description }} </p>
  </div>
Enter fullscreen mode Exit fullscreen mode

03 Render it inside the controller

import Post from 'App/Models/Post'

  export default class PostsController {
    public async show({ params, view }) {
      const post = await Post.find(1)
      return view.render('posts/index', { post })
    }
  }
Enter fullscreen mode Exit fullscreen mode

If you prefer to stick to React or VueJS no problem, AdonisJS supports both via InertiaJS

Authenticate users using the auth package

Auth has never been easier than this in my entire life. It's too easy!!

01 Install and configure the auth package

 npm i @adonisjs/auth
Enter fullscreen mode Exit fullscreen mode
node ace configure @adonisjs/auth
Enter fullscreen mode Exit fullscreen mode

02 Login users using sessions

export default class AuthController {
    public async login({ request, auth, response }) {
      const email = request.input('email')
      const password = request.input('password')

      await auth
        .use('web') // 👈 using sessions guard
        .attempt(email, password)

      response.redirect().toRoute('dashboard')
    }
  }
Enter fullscreen mode Exit fullscreen mode

03 Generate an API token instead

 export default class AuthController {
    public async login({ request, auth }) {
      const email = request.input('email')
      const password = request.input('password')

      const token = await auth
        .use('api') // 👈 using API guard
        .attempt(email, password)

      return token
    }
  }
Enter fullscreen mode Exit fullscreen mode

Validate input using the validator

Server Side Validation is just as easy, and Adonis provides a bunch of common rules to help along with the ability to create custom rules and error messages.

01 Create a validator

 node ace make:validator CreatePost
Enter fullscreen mode Exit fullscreen mode

02 Define the validation schema

import { schema, rules } from '@ioc:Adonis/Core/Validator'
  import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'

  export default class CreatePostValidator {
    constructor (protected ctx: HttpContextContract) {
    }

    public schema = schema.create({
      title: schema.string(),
      description: schema.string({}, [
        rules.escape()
      ]),
    })
  }
Enter fullscreen mode Exit fullscreen mode

03 Validate the request

  import CreatePost from 'App/Validators/CreatePostValidator'

  export default class PostsController {
    public async store({ request }) {
      const post = await request.validate(CreatePost)
      console.log(post.title)
      console.log(post.description)
    }
  }
Enter fullscreen mode Exit fullscreen mode

Compile assets using webpack encore

At some point in time, you may reach for a CSS framework and might want to sprinkle some JavaScript to make your web apps interactive.

As per the standards today, the CSS and the frontend JavaScript need to be transpiled and minified before serving it to the browser. This bundling process is not that simple, and hence you must use a bundler for it.

AdonisJS pre-configures Webpack (an industry-standard bundler) with sane defaults so that you don't have to waste time adjusting its knobs.

Still not convinced I got you!

Do you need Social Authentication ? No problem.

AdonisJS support social auth with their package called ally. It supports multiple providers. Google, Twitter, LinkedIn, Facebook, Discord, Spotify, and GitHub and has an extensible API to add custom social providers.

But what about TDD ? hmmmm.....

E2E, Unit tests and HTTP tests Adonis got you covered heres what they have to say:

AdonisJS has out of the box support for testing, and there is no need to install any third-party packages for the same. Just run the node ace test and the magic will happen. AdonisJS uses Japa (A homegrown testing framework) for writing and executing tests.

I18n ????

npm i @adonisjs/i18n
Enter fullscreen mode Exit fullscreen mode

Helpers to perform language-sensitive formatting for dates, currencies, names, and so on.
Support for storing translations in ICU messages format.
Add your custom messages formatter and translations loader.

But my SAAS needs to send emails!

AdonisJS comes with a mailer packaged called mail. It is built on top of nodemailer and it has support for multiple drivers. SparkPost, SES, Mailgun and Smtp, plus you can use their edge templates to create markup for your emails.

Massive file uploads with Drive.

AdonisJS Drive is an abstraction on top of cloud storage services, such as: Amazon S3, DigitalOcean Spaces, and Google Cloud Storage.


If you like to get Started head over to AdonisJS


Here is a full list of additional features for you to ponder over:

  • Full typescript support

  • Web security

  • CORS Config

  • Encryption

  • Signed URls

  • Hashing

  • REPL

  • Logger

  • Events

  • Helpers Utilities

  • Redis

  • Rate Limiting

  • VS Code Extension

  • Community Packages