cd..blog

Integrating Hapi, Netlify, and TypeScript for Scalable Web Apps

const published = "Feb 5, 2026, 10:37 PM";const readTime = 4 min;
hapinetlifytypescriptstate managementdeployment
Build and deploy robust web applications by integrating Hapi.js, Netlify, and modern state management with TypeScript.

Building Modern Web Applications with Hapi, Netlify, and TypeScript

Developing scalable and maintainable web applications requires a thoughtful combination of robust backend services, efficient frontend deployment, and intelligent state management. This post demonstrates how to integrate Hapi.js for your API, Netlify for seamless deployment, and Zustand for frontend state management, all powered by TypeScript.

Backend with Hapi.js: A Robust API Foundation

Hapi.js is a rich framework for building APIs and web applications, offering a modular plugin-based architecture. It provides a solid, enterprise-grade foundation for handling requests, routing, and authentication, making your backend reliable and easy to extend. Learn more about Hapi.js

Let's set up a basic Hapi server to serve some data:

// src/server.ts
import Hapi from '@hapi/hapi';

interface Item {
  id: string;
  name: string;
}

const init = async () => {
  const server = Hapi.server({
    port: process.env.PORT || 3000,
    host: 'localhost',
    routes: {
      cors: true, // Enable CORS for frontend consumption
    },
  });

  server.route({
    method: 'GET',
    path: '/api/items',
    handler: (request, h) => {
      const items: Item[] = [
        { id: '1', name: 'TypeScript' },
        { id: '2', name: 'Hapi.js' },
        { id: '3', name: 'Netlify' },
      ];
      return items;
    },
  });

  await server.start();
  console.log(`Server running on ${server.info.uri}`);
};

process.on('unhandledRejection', (err) => {
  console.log(err);
  process.exit(1);
});

init();

Frontend & State Management with React and Zustand

For the frontend, we'll use React and Zustand, a minimalist state management library. Zustand simplifies state management with a hook-based API, making it lightweight and highly performant for consuming data from our Hapi API. Explore Zustand

Here's a React component that fetches data from our Hapi backend and manages it with Zustand:

// src/store/itemStore.ts
import { create } from 'zustand';

interface Item {
  id: string;
  name: string;
}

interface ItemState {
  items: Item[];
  fetchItems: () => Promise<void>;
}

const useItemStore = create<ItemState>((set) => ({
  items: [],
  fetchItems: async () => {
    try {
      const response = await fetch(`${process.env.REACT_APP_API_URL}/api/items`);
      if (!response.ok) throw new Error('Network response was not ok');
      const data: Item[] = await response.json();
      set({ items: data });
    } catch (error) {
      console.error('Failed to fetch items:', error);
    }
  },
}));

export default useItemStore;

// src/components/ItemList.tsx
import React, { useEffect } from 'react';
import useItemStore from '../store/itemStore';

const ItemList: React.FC = () => {
  const { items, fetchItems } = useItemStore();

  useEffect(() => {
    fetchItems();
  }, [fetchItems]);

  return (
    <div>
      <h2>Items from Hapi API:</h2>
      {items.length === 0 ? (
        <p>Loading items...</p>
      ) : (
        <ul>
          {items.map((item) => (
            <li key={item.id}>{item.name}</li>
          ))}
        </ul>
      )}
    </div>
  );
};

export default ItemList;

Cloud & Deployment with Netlify

Netlify provides an intuitive platform for deploying frontend applications, offering continuous deployment, global CDN, and serverless functions. It simplifies the entire deployment workflow, allowing developers to focus on building features. Discover Netlify's features

To connect our React frontend to the Hapi backend, we'll use Netlify's redirects to proxy API requests. This allows the frontend to call /api/items while Netlify internally forwards the request to our deployed Hapi API.

Create a netlify.toml file in your frontend's root directory:

# netlify.toml
[build]
  command = "npm run build"
  publish = "build"

[[redirects]]
  from = "/api/*"
  to = "${REACT_APP_API_URL}/api/:splat"
  status = 200
  force = true

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

Here, REACT_APP_API_URL is an environment variable set in Netlify's UI (e.g., https://your-hapi-backend.com). The redirect rule ensures that calls like /api/items from your frontend are seamlessly proxied to your external Hapi backend.

Integrating the Ecosystem

This architecture leverages the strengths of each component:

  • Hapi.js delivers a robust, scalable backend API, decoupled from the frontend.
  • Zustand provides a performant and developer-friendly way to manage frontend state, consuming data from the Hapi API.
  • Netlify handles the entire frontend deployment lifecycle, including CI/CD, global content delivery, and intelligent proxying to the backend.

By deploying your Hapi API to a suitable cloud platform (e.g., AWS Fargate, Render, or a VPS) and your frontend to Netlify, you achieve a highly performant, maintainable, and scalable application. Netlify's environment variables and redirect rules are key to securely connecting these decoupled services.

This setup ensures a smooth developer experience and a fast, reliable application for your users, demonstrating a modern full-stack approach with TypeScript at its core.