August 07, 2024

Using npm packages in AdonisJS

One of the most asked questions in the AdonisJS community has to be about how to use X package in AdonisJS. Those asking this question tend to forget that AdonisJS is a Node.js framework and as a result, we can use an npm package the same way we'd use it in any Node.js project.

In this tutorial, I'll show two ways of using an npm package in AdonisJS. I'll use the Paddle Node.js SDK to demonstrate this but the same principles apply to other npm packages.

Using the package directly

The simplest way to use an npm package in AdonisJS is to install the package and use it directly wherever we want to use it in our codebase.

We need to first install the package:

npm install @paddle/paddle-node-sdk

Let's say we are working with the concept of customer and we have a CustomersController. First, we import the package and then use it in the controller:

// app/controllers/customers_controller.ts
import { Paddle } from '@paddle/paddle-node-sdk'
import config from '@adonisjs/core/services/config'
export default class CustomersController {
async handle({ auth }: HttpContext) {
const paddle = new Paddle(config.get('services.paddle.apiKey'))
await paddle.customers.get(auth.user!.paddleId)
}
}

Using a service class

The problem with the above approach is that we end up littering our codebase with the same package import (and initialisation) over and over. For some packages that could be okay. For example, using a package like lodash. But with the package and concept we are working with, that might not be the case.

So to take the above implementation one step further, we could create a PaddleService. We could create the service manually but there's a command for that:

node ace make:service paddle

This will create an empty paddle_service.ts file inside app/services. Add the following code inside the file:

// app/services/paddle_service.ts
import config from '@adonisjs/core/services/config'
import { Customer, Paddle } from '@paddle/paddle-node-sdk'
import app from '@adonisjs/core/services/app'
export default class PaddleService {
private paddle: Paddle
constructor() {
this.paddle = new Paddle(config.get('services.paddle.apiKey'))
}
async getCustomer(customerId: string): Promise<Customer> {
return this.paddle.customers.get(customerId)
}
}

Like before, we import the package and initiate it. For the usage, we create a method that we can use in controllers or other places. Now, we can keep all Paddle-specified implementations contained in one place.

We can make use of the service class in two ways. First, we import and initialise the class manually:

// app/controllers/customers_controller.ts
import { inject } from '@adonisjs/core'
import PaddleService from '#services/paddle_service'
export default class CustomersController {
async handle({ auth }: HttpContext) {
const paddle = new PaddleService()
await paddle.customers.get(auth.user!.paddleId)
}
}

The other way is to leverage AdonisJS Dependency Injection (DI) to initialise the class with the necessary dependencies. We can do that using the @inject decorator:

// app/controllers/customers_controller.ts
import { inject } from '@adonisjs/core'
import PaddleService from '#services/paddle_service'
export default class CustomersController {
@inject()
async handle({ auth }: HttpContext, paddle: PaddleService) {
await paddle.customers.get(auth.user!.paddleId)
}
}

Here, we are using method injection but we could also use constructor injection.

Conclusion

So that's how to use npm packages in AdonisJS. Remember, AdonisJS is just a Node.js framework.

Chimezie Enyinnaya
Chimezie Enyinnaya
Author
Share: