AskHandle Blog
Building Web Applications with Hapi.js: A Node Developer's Guide

Building Web Applications with Hapi.js: A Node Developer's Guide
Hapi.js is a reliable Node.js web framework that helps developers create powerful and maintainable applications. Built by the Walmart team to handle their Black Friday traffic, Hapi focuses on configuration-driven architecture and clean code organization.
Why Choose Hapi?
The framework brings a fresh take on building web applications. Instead of mixing routes with business logic, Hapi encourages clear separation of concerns. Each part of your application stays organized in its own space, making it easier to test and maintain code as your project grows.
Getting Started
Setting up a basic Hapi server is straightforward. First, install Hapi using npm:
1npm install @hapi/hapiCreate your first server:
1const Hapi = require('@hapi/hapi');
2
3const init = async () => {
4 const server = Hapi.server({
5 port: 3000,
6 host: 'localhost'
7 });
8
9 server.route({
10 method: 'GET',
11 path: '/',
12 handler: (request, h) => {
13 return 'Hello World!';
14 }
15 });
16
17 await server.start();
18 console.log('Server running on %s', server.info.uri);
19};
20
21init();Key Features That Make Hapi Stand Out
Built-in input validation through Joi makes data handling secure and reliable. You can define exact schemas for your API endpoints, and Hapi automatically validates incoming requests:
1server.route({
2 method: 'POST',
3 path: '/users',
4 options: {
5 validate: {
6 payload: Joi.object({
7 username: Joi.string().min(3).max(30).required(),
8 email: Joi.string().email().required()
9 })
10 }
11 },
12 handler: userHandler
13});Plugin System
The plugin system in Hapi makes code reuse simple. You can package related functionality into plugins and share them across projects. This modular approach keeps your codebase clean and maintainable:
1const myPlugin = {
2 name: 'myPlugin',
3 register: async function(server, options) {
4 server.route({
5 method: 'GET',
6 path: '/plugin-route',
7 handler: (request, h) => 'Plugin works!'
8 });
9 }
10};
11
12await server.register(myPlugin);Security Features
Hapi takes security seriously. The framework includes built-in protection against common web vulnerabilities. It automatically sets secure headers and provides tools for rate limiting and authentication.
Testing Made Easy
The framework comes with built-in testing utilities. You can write tests for your routes without starting a real server:
1const Lab = require('@hapi/lab');
2const { expect } = require('@hapi/code');
3const { afterEach, beforeEach, describe, it } = exports.lab = Lab.script();
4
5describe('GET /', () => {
6 let server;
7
8 beforeEach(async () => {
9 server = Hapi.server();
10 // Add your routes here
11 });
12
13 it('responds with 200', async () => {
14 const res = await server.inject({
15 method: 'GET',
16 url: '/'
17 });
18 expect(res.statusCode).to.equal(200);
19 });
20});Building with Hapi feels natural once you learn its patterns. The framework's focus on configuration over convention means you spend less time fighting with your tools and more time building great applications.