AdonisJS bundles the utilities used by the framework or the ecosystem packages into a Helpers module and makes them available to your application code.

Since these utilities are already installed and used by the framework, the helpers module does not add any additional bloat to your node_modules.

String helpers

The string helpers expose the following transformation methods.


Convert a string to its camelCase version.

import { string } from '@ioc:Adonis/Core/Helpers'
string.camelCase('hello-world') // helloWorld


Convert a string to its snake_case version.

import { string } from '@ioc:Adonis/Core/Helpers'
string.snakeCase('helloWorld') // hello_world


Convert a string to its dash-case version. Optionally, you can also capitalize the first letter of each segment.

import { string } from '@ioc:Adonis/Core/Helpers'
string.dashCase('helloWorld') // hello-world
string.dashCase('helloWorld', { capitalize: true }) // Hello-World


Convert a string to its PascalCase version.

import { string } from '@ioc:Adonis/Core/Helpers'
string.pascalCase('helloWorld') // HelloWorld


Capitalize a string

import { string } from '@ioc:Adonis/Core/Helpers'
string.capitalCase('helloWorld') // Hello World


Convert string to a sentence

import { string } from '@ioc:Adonis/Core/Helpers'
string.sentenceCase('hello-world') // Hello world


Convert string to its version.

import { string } from '@ioc:Adonis/Core/Helpers'
string.dotCase('hello-world') //


Remove all sorts of casing

import { string } from '@ioc:Adonis/Core/Helpers'
string.noCase('hello-world') // hello world
string.noCase('hello_world') // hello world
string.noCase('helloWorld') // hello world


Convert a sentence to title case

import { string } from '@ioc:Adonis/Core/Helpers'
string.titleCase('Here is a fox') // Here Is a fox


Pluralize a word.

import { string } from '@ioc:Adonis/Core/Helpers'
string.pluralize('box') // boxes
string.pluralize('i') // we

You can also define your own irregular rules using the defineIrregularRule method. The method accepts the singular version as the first argument and the plural version as the second argument.

import { string } from '@ioc:Adonis/Core/Helpers'
string.defineIrregularRule('auth', 'auth')
string.plural('auth') // auth

You can also define your own uncountable rules using the defineUncountableRule method.

import { string } from '@ioc:Adonis/Core/Helpers'
string.plural('login') // home


Truncate a string after a given number of characters

import { string } from '@ioc:Adonis/Core/Helpers'
'This is a very long, maybe not that long title',
) // This is a ve...

By default, the string is truncated exactly after the given characters. However, you can instruct the method to wait for the words to complete.

'This is a very long, maybe not that long title',
completeWords: true
) // This is a very...

Also, it is possible to customize the suffix.

'This is a very long, maybe not that long title',
completeWords: true,
suffix: ' <a href="/1"> Read more </a>',
) // This is a very <a href="/1"> Read more </a>


The excerpt method is the same as the truncate method. However, it strips the HTML from the string.

import { string } from '@ioc:Adonis/Core/Helpers'
'<p>This is a <strong>very long</strong>, maybe not that long title</p>',
) // This is a very...


Condense whitespaces from a given string. The method removes the whitespace from the left, right, and multiple whitespaces between the words.

import { string } from '@ioc:Adonis/Core/Helpers'
string.condenseWhitespace(' hello world ')
// hello world


Escape HTML from the string

import { string } from '@ioc:Adonis/Core/Helpers'
string.escapeHTML('<p> foo © bar </p>')
// &lt;p&gt; foo © bar &lt;/p&gt;

Additionally, you can also encode non-ASCII symbols.

import { string } from '@ioc:Adonis/Core/Helpers'
'<p> foo © bar </p>',
encodeSymbols: true
// &lt;p&gt; foo &#xA9; bar &lt;/p&gt;


Encode symbols. Checkout he for available options

import { string } from '@ioc:Adonis/Core/Helpers'
string.encodeSymbols('foo © bar')
// foo &#xA9; bar


Join an array of words with a separator.

import { string } from '@ioc:Adonis/Core/Helpers'
]) // route, middleware, and controller
]) // route and middleware

You can define the following options to customize the output.

], {
separator: '/ ',
lastSeparator: '/or '
}) // route/ middleware/or controller


Convert bytes value to a human-readable string. For options, reference the bytes package.

import { string } from '@ioc:Adonis/Core/Helpers'
string.prettyBytes(1024) // 1KB
string.prettyBytes(1024, { unitSeparator: ' ' }) // 1 KB


Convert human-readable string to bytes. This method is the opposite of the prettyBytes method.

import { string } from '@ioc:Adonis/Core/Helpers'
string.toBytes('1KB') // 1024


Convert time in milliseconds to a human-readable string

import { string } from '@ioc:Adonis/Core/Helpers'
string.prettyMs(60000) // 1min
string.prettyMs(60000, { long: true }) // 1 minute


Convert human-readable string to milliseconds. This method is the opposite of the prettyMs method.

import { string } from '@ioc:Adonis/Core/Helpers'
string.toMs('1min') // 60000


Ordinalize a string or a number value

import { string } from '@ioc:Adonis/Core/Helpers'
string.ordinalize(1) // 1st
string.ordinalize(99) // 99th


Generate a cryptographically strong random string

import { string } from '@ioc:Adonis/Core/Helpers'


Find if a value is empty. Also checks for empty strings with all whitespace

import { string } from '@ioc:Adonis/Core/Helpers'
string.isEmpty('') // true
string.isEmpty(' ') // true

Type detection

Type detection in JavaScript is very weak and often leads to unexpected bugs. For example: typeof null is object and typeof [] is also an object.

You can use the types helper to have more accurate and consistent type checking in your application.


The lookup method returns the type for a given value.

import { types } from '@ioc:Adonis/Core/Helpers'
types.lookup({}) // object
types.lookup([]) // array
types.lookup(Object.create(null)) // object
types.lookup(null) // null
types.lookup(function () {}) // function
types.lookup(class Foo {}) // class
types.lookup(new Map()) // map


Find if the given value is null

import { types } from '@ioc:Adonis/Core/Helpers'
types.isNull(null) // true


Find if the given value is a boolean

import { types } from '@ioc:Adonis/Core/Helpers'
types.isBoolean(true) // true


Find if the given value is a buffer

import { types } from '@ioc:Adonis/Core/Helpers'
types.isBuffer(new Buffer()) // true


Find if the given value is a number

import { types } from '@ioc:Adonis/Core/Helpers'
types.isNumber(100) // true


Find if the given value is a string

import { types } from '@ioc:Adonis/Core/Helpers'
types.isString('hello') // true


Find if the given value is an arguments object

import { types } from '@ioc:Adonis/Core/Helpers'
function foo() {
types.isArguments(arguments) // true


Find if the given value is a plain object

import { types } from '@ioc:Adonis/Core/Helpers'
types.isObject({}) // true


Find if the given value is a date object

import { types } from '@ioc:Adonis/Core/Helpers'
types.isDate(new Date()) // true


Find if the given value is an array

import { types } from '@ioc:Adonis/Core/Helpers'
types.isArray([1, 2, 3]) // true


Find if the given value is a regular expression

import { types } from '@ioc:Adonis/Core/Helpers'
types.isRegexp(/[a-z]+/) // true


Find if the given value is an instance of the error object.

import { types } from '@ioc:Adonis/Core/Helpers'
import { Exception } from '@poppinss/utils'
types.isError(new Error('foo')) // true
types.isError(new Exception('foo')) // true


Find if the given value is a function

import { types } from '@ioc:Adonis/Core/Helpers'
types.isFunction(function foo() {}) // true


Find if the given value is a class constructor. Uses regex to distinguish between a function and a class.

import { types } from '@ioc:Adonis/Core/Helpers'
class User {}
types.isClass(User) // true
types.isFunction(User) // true


Find if the given value is an integer.

import { types } from '@ioc:Adonis/Core/Helpers'
types.isInteger(22.00) // true
types.isInteger(22) // true
types.isInteger(-1) // true
types.isInteger(-1.00) // true
types.isInteger(22.10) // false
types.isInteger(.3) // false
types.isInteger(-.3) // false


Find if the given value is a float number.

import { types } from '@ioc:Adonis/Core/Helpers'
types.isFloat(22.10) // true
types.isFloat(-22.10) // true
types.isFloat(.3) // true
types.isFloat(-.3) // true
types.isFloat(22.00) // false
types.isFloat(-22.00) // false
types.isFloat(-22) // false


Find if the given value has a decimal. The value can be a string or a number. The number values are casted to a string by calling the toString() method on the value itself.

The string conversion is performed to test the value against a regex since there is no way to find a decimal value in JavaScript natively.

import { types } from '@ioc:Adonis/Core/Helpers'
types.isDecimal('22.10') // true
types.isDecimal(22.1) // true
types.isDecimal('-22.10') // true
types.isDecimal(-22.1) // true
types.isDecimal('.3') // true
types.isDecimal(0.3) // true
types.isDecimal('-.3') // true
types.isDecimal(-0.3) // true
types.isDecimal('22.00') // true
types.isDecimal(22.0) // false (gets converted to 22)
types.isDecimal('-22.00') // true
types.isDecimal(-22.0) // false (gets converted to -22)
types.isDecimal('22') // false
types.isDecimal(22) // false
types.isDecimal('0.0000000000001') // true
types.isDecimal(0.0000000000001) // false (gets converted to 1e-13)


Compares two values with each other by avoiding the timing attack . This method internally uses the crypto.timingSafeEqual method, but can also compare two strings.

import { safeEqual } from '@ioc:Adonis/Core/Helpers'
if (safeEqual('hello world', 'hello world')) {


Helper to require all the .js, .ts and .json files from a directory. This method only works with commonjs modules and not with ES modules.

import { join } from 'path'
import { requireAll } from '@ioc:Adonis/Core/Helpers'
const configTree = requireAll(join(__dirname, 'config'))

The files are imported recursively by default. However, you can turn off recursive scanning by setting the second argument to false

requireAll(join(__dirname, 'config'), false)

An exception is raised when the root directory is missing. However, you can instruct the method to ignore the missing directory by setting the third argument as true.

requireAll(join(__dirname, 'config'), true, true)


Recursively scan all and collect paths for all the .js, .ts, and .json files from a given directory.

import { join } from 'path'
import { fsReadAll } from '@ioc:Adonis/Core/Helpers'
fsReadAll(join(__dirname, 'config'))
// ['app.ts', 'bodyparser.ts', 'cors.ts']

Optionally you can define a custom filter function to ignore certain paths. Defining a custom filter removes the existing filter of selecting only .js, .ts and .json files.

fsReadAll(join(__dirname, 'config'), (filePath) => {
return filePath.endsWith('.md')


Encode/decode base64 values. Make use of the urlEncode and urlDecode methods if you want to pass the encoded value to a URL.

import { base64 } from '@ioc:Adonis/Core/Helpers'
base64.encode('hello world')
base64.decode(base64.encode('hello world'))
// URL safe encoding
base64.urlEncode('hello world')
base64.urlDecode(base64.urlEncode('hello world'))

You can also define custom encoding for the input value.

const encoded = base64.encode(bufferValue, 'binary')
base64.decode(encoded, 'binary')


A lightweight helper method to interpolate curly braces inside a string. This method is not a replacement for any template engines.

import { interpolate } from '@ioc:Adonis/Core/Helpers'
interpolate('hello {{ username }}', { username: 'virk' })
// Nested values
interpolate('hello {{ user.username }}', {
user: { username: 'virk' }
// Array of objects
interpolate('hello {{ users.0.username }}', {
users: [{ username: 'virk' }]
// Array of literal values
interpolate('hello {{ scores.0 }}', {
scores: [67, 80]


JavaScript doesn't have a concept of inheriting multiple classes together, and neither does TypeScript. However, the official documentation of TypeScript does talks about the concept of mixins.

As per the TypeScript docs, you can create and apply mixins as follows.

type Constructor = new (...args: any[]) => any
const UserWithEmail = <T extends Constructor>(superclass: T) => {
return class extends superclass {
public email: string
const UserWithPassword = <T extends Constructor>(superclass: T) => {
return class extends superclass {
public password: string
class BaseModel {}
class User extends UserWithPassword(UserWithEmail(BaseModel)) {}

Mixins are close to a perfect way of inheriting multiple classes. I recommend reading this article for the same.

However, the syntax of applying multiple mixins is ugly, as you have to apply mixins over mixins, creating a nested hierarchy as shown below.

class User extends UserWithAttributes(
) {}

The compose method is a small utility to improve the syntax a bit.

import { compose } from '@ioc:Adonis/Core/Helpers'
class User extends compose(
) {}

Mixins gotchas

TypeScript has an open issue related to the constructor arguments of the mixin class or the base class.

TypeScript expects all classes used in the mixin chain to have a constructor with only one argument of ...args: any[]. For example: The following code will work fine at runtime, but the typescript compiler complains about it.

class BaseModel {
constructor(name: string) {}
const UserWithEmail = <T extends typeof BaseModel>(superclass: T) => {
return class extends superclass {
// ERROR: A mixin class must have a constructor with a single rest parameter of type 'any[]'.ts(2545)
public email: string
class User extends compose(BaseModel, UserWithEmail) {}

You can work around this by overriding the base class's constructor using the NormalizeConstructor type.

import {
} from '@ioc:Adonis/Core/Helpers'
const UserWithEmail = <T extends NormalizeConstructor<typeof BaseModel>>(
superclass: T
) => {
return class extends superclass {
public email: string


Generate a collision resistant id .

import { cuid } from '@ioc:Adonis/Core/Helpers'
// cjld2cjxh0000qzrmn831i7rn