How to Mock REST APIs in React

Mocking REST APIs is a crucial practice in React development that allows developers to build, test, and prototype user interfaces without relying on a live backend. This article explores the most effective methods for mocking APIs in React, including using local mock data, JSON Server for a simulated backend, and Mock Service Worker (MSW) for seamless network interception. By the end of this guide, you will understand how to implement these strategies to streamline your frontend development workflow.

1. Using Local Mock Data and State

The simplest way to mock an API in React is by defining static JSON data directly inside your project and loading it into your component’s state. This approach requires no external libraries and is ideal for quick prototyping.

import React, { useState, useEffect } from 'react';

const mockUsers = [
  { id: 1, name: 'Alice Smith' },
  { id: 2, name: 'Bob Jones' }
];

function UserList() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    // Simulate an API delay
    const timer = setTimeout(() => {
      setUsers(mockUsers);
    }, 500);

    return () => clearTimeout(timer);
  }, []);

  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

While easy to set up, this method does not test actual network requests and can make your components messy if mock data scales.

2. Mocking with JSON Server

If you need a realistic REST API with actual HTTP requests (GET, POST, PUT, DELETE) without building a backend, JSON Server is an excellent tool. It creates a full fake REST API using a single JSON file.

Step 1: Install JSON Server

Run the following command in your terminal:

npm install json-server --save-dev

Step 2: Create a Database File

Create a file named db.json in your project root:

{
  "posts": [
    { "id": 1, "title": "React Mocking Guide" },
    { "id": 2, "title": "Understanding Hooks" }
  ]
}

Step 3: Run the Server

Add a script to your package.json or run it directly:

npx json-server --watch db.json --port 5000

Your React app can now fetch data from http://localhost:5000/posts using standard fetch or axios calls, exactly as it would with a real backend.

3. Using Mock Service Worker (MSW)

Mock Service Worker (MSW) is the industry-standard tool for mocking APIs in modern React applications. Instead of bypassing the network layer, MSW uses the browser’s Service Worker API to intercept outgoing HTTP requests at the network level and return mock responses.

This method allows you to use the exact same mock definitions for both browser development and unit testing (with Jest or Vitest).

Step 1: Install MSW

npm install msw --save-dev

Step 2: Define Request Handlers

Create a file named src/mocks/handlers.js to define your API endpoints:

import { http, HttpResponse } from 'msw';

export const handlers = [
  http.get('/api/products', () => {
    return HttpResponse.json([
      { id: 101, name: 'Wireless Mouse' },
      { id: 102, name: 'Mechanical Keyboard' }
    ]);
  })
];

Step 3: Set Up the Worker

Generate the Service Worker file in your public directory:

npx msw init public/ --save

Then, configure the worker in src/mocks/browser.js:

import { setupWorker } from 'msw/browser';
import { handlers } from './handlers';

export const worker = setupWorker(...handlers);

Step 4: Start the Worker in Development

In your src/index.js or src/main.jsx, start the worker before rendering the React application:

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

async function enableMocking() {
  if (process.env.NODE_ENV !== 'development') {
    return;
  }
  const { worker } = await import('./mocks/browser');
  return worker.start();
}

enableMocking().then(() => {
  ReactDOM.createRoot(document.getElementById('root')).render(
    <React.StrictMode>
      <App />
    </React.StrictMode>
  );
});

Once configured, any fetch('/api/products') call made by your React components will be intercepted by MSW and resolved with your mock data, keeping your component code production-ready.