How To Use Typescript With HapiJs

Babatunde Akinyanmi
4 min readNov 26, 2018

--

In this article, I will attempt to show you how to use typescript with hapi (version 18.4.x). We will clone the API server example on hapi.js’ homepage only that our clone will make use of Typescript. Also i’ll be using yarn instead of npm. There’s nothing wrong with using npm so you can use npm if you prefer that.

Before going further, this tutorial is beginner level but I assume that you at least already know what Typescript is and Typescript types. If you don’t, you can read this ‘TypeScript vs. JavaScript’ article. With that out of the way, let’s start.

Create a package.json

This is easy.

yarn init

Add dependencies

This is a hapi server so obviously, hapi is a dependency for this project. Run the command below to add it.

yarn add @hapi/hapi

Development dependencies

Most importantly, we need TypeScript. Also, we need a tool to watch our code and restart our server anytime we make a change. For this, I chose Nodemon. Let’s add the three dependencies to our project. We’ll make use of nodemon later on in the tutorial.

yarn add typescript --dev
yarn add nodemon --dev

Next, we need to install type declarations for both node and hapi. It’s easy as well. Run the commands below

yarn add @types/node --dev
yarn add @types/hapi__hapi --dev

Note: Take care not to install @types/hapi except you are installing hapijs 17.x.

At this point, your package.json should look similar to this:

{
"name": "hapiserver",
"version": "0.0.1",
"description": "API server",
"main": "index.js",
"author": "Your Name",
"license": "MIT",
"dependencies": {
"hapi": "^18.4.0"
},
"devDependencies": {
"@types/hapi__hapi": "^18.2.6",
"@types/node": "^13.1.1",
"nodemon": "^2.0.2",
"typescript": "^3.7.4"
}
}

Congratulations. We have everything we need but we still need to configure our TypeScript.

Configure TypeScript

Prepare the file structure

In your project’s root directory, create a directory called src. It will contain all our application’s typescript code. Next, create another directory in the root directory named dist which will contain all our javascript code compiled from our typescript code.

Note: You can use any file structure you like and name the directories whatever pleases you. This article is just a tutorial to get you going.

At this point, your file structure should look like this

tsconfig.json

Typescript looks for a file named tsconfig.jsonto get the specifications of the root file and compiler options required to compile the project. You can learn how to make use of the tsconfig.json file and the available options here.

Add a tsconfig.json file to your root directory. You can start with something like this:

{  "compilerOptions": {
"outDir": "./dist",
"allowJs": false,
"target": "es6",
"sourceMap": true,
"module": "commonjs",
"moduleResolution": "node",
},
"include": [
"./src/**/*",
],
"exclude": [
"node_modules"
],
}

Now, let’s test to make sure we haven’t goofed somewhere.

In the tsconfig.json file above, the outDiroption is set to ‘./dist’. This tells the compiler to save compiled files into a directory called ‘dist’. We can test our outDir is working as follows.

Start by deleting the dist folder we created.

Next, add an empty file called index.ts to the src folder we created.

Finally, in your terminal (make sure you are in the root directory of your project), compile your project with this command

node_modules/typescript/bin/tsc

After it is done, the dist folder that we deleted should be back. This time around, the dist folder should also contain the result of our compiled index.ts file named index.js .

That’s it. We can now start writing code.

Write The Server (With TypeScript)

Let’s now rewrite the server on hapi’s home page using typescript.

We will use the index.ts file in our src directory. It is important that our index.ts file is located in the src directory because we have configured typescript to compile only the files in the src directory.

.ts files are typescript files, .js files are javascript files

Write the code for the server:

index.ts

import { Server, Request, ResponseToolkit } from "@hapi/hapi";const init = async () => {
const server: Server = new Server({
port: 3000,
host: 'localhost'
});
server.route({
method: 'GET',
path: '/',
handler: (request: Request, h: ResponseToolkit) => {
return 'Hello World!';
}
});
await server.start();
console.log('Server running on %s', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();

Because our code is typescript, we can’t get it to run just yet. We need to compile our source into javascript and run it with node.

Compile typescript to javascript and run (the code)

We already ran the command that makes typescript compile our code to javascript. Every time we change our code, we have to recompile. So run the tsc command again.

node_modules/typescript/bin/tsc

In the ‘dist’ folder, index.js should contain our server code. We can now launch the application.

node ./dist/index.js

You should see this output in your terminal:

Server running at: http://localhost:8000

Finishing touches

Instead of manually recompiling source code after every edit, we can make use of npm scripts and nodemon (we installed this as a dependency earlier on) to automate things for us.

Add this to your package.json

{
...
"scripts": {
"start": "./node_modules/nodemon/bin/nodemon.js -e ts --exec \"yarn run compile\"",
"compile": "tsc && node ./dist/index.js"
}
}

With this addition, all you have to do is run:

yarn start

What will then happen is nodemon begins to watch your files for changes. If any change is detected, nodemon will run the typescript tsccommand to compile your files and re-launch the application.

If you using windows, nodemon will fail. But the fix is easy. Do the following

Install nodemon globally rather than just for your project. To do this, run this in your terminal. Note that this is also totally valid for other operating systems.

yarn global add nodemon --dev

2. Next, update your package.json’s script field like this:

{
...
"scripts": {
"start": nodemon -e ts --exec \"yarn run compile\"",
"compile": "tsc && node ./dist/index.js"
}
}

Done

That’s all. Hapi with Typescript is that easy.

Babatunde Akinyanmi

--

--