Real-world examples of JavaScript Fetch API for modern apps

If you’re looking for practical, real examples of JavaScript Fetch API usage, you’re in the right place. Instead of another dry reference, this guide walks through examples of JavaScript Fetch API examples that mirror what you actually build in 2024–2025: dashboards, search UIs, file uploads, authentication flows, and more. These examples of JavaScript Fetch API examples focus on modern patterns: async/await, error handling, JSON parsing, streaming responses, and integration with popular backends. You’ll see how to wire up front-end code to real APIs, handle edge cases like timeouts, and make your code easier to maintain. Along the way, we’ll point to authoritative documentation and real APIs you can test against. Whether you’re refreshing an old jQuery-based project or building a new single-page app, these Fetch examples include everything from a basic GET to authenticated requests and file uploads. Copy, tweak, and drop them straight into your own codebase.
Written by
Jamie
Published
Updated

Quick-start example of JavaScript Fetch API in action

Let’s start with a minimal but realistic fetch call: requesting JSON from a public API and handling errors.

async function loadUsers() {
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/users');

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const users = await response.json();
    console.log('Users:', users);
  } catch (error) {
    console.error('Failed to load users:', error);
  }
}

loadUsers();

This is the baseline pattern you’ll see repeated across most real examples of JavaScript Fetch API usage:

  • Call fetch(url, options).
  • Check response.ok and response.status.
  • Parse JSON with response.json().
  • Wrap everything in try/catch with async/await.

From here, we’ll layer on more realistic scenarios.


Practical examples of JavaScript Fetch API examples for JSON APIs

Modern web apps live and die by JSON APIs. These examples of JavaScript Fetch API examples show how to handle common patterns you’ll see daily.

Example: Search with query parameters

A very common example of JavaScript Fetch API usage is a search box that calls a backend with query parameters.

async function searchBooks(query, page = 1) {
  const params = new URLSearchParams({ q: query, page: String(page) });

  const url = `https://openlibrary.org/search.json?${params.toString()}`;

  const response = await fetch(url);

  if (!response.ok) {
    throw new Error(`Search failed: ${response.status}`);
  }

  const data = await response.json();
  return data.docs; // array of books
}

// Usage
searchBooks('javascript').then(books => {
  console.log('Found books:', books.slice(0, 3));
});

This pattern shows up in dashboards, admin panels, and any app with filters or search.

Example: POST JSON to create a resource

Another one of the best examples of JavaScript Fetch API examples is sending JSON data to create or update something on the server.

async function createTodo(title) {
  const response = await fetch('https://jsonplaceholder.typicode.com/todos', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      title,
      completed: false,
    }),
  });

  if (!response.ok) {
    throw new Error(`Create failed: ${response.status}`);
  }

  const todo = await response.json();
  return todo;
}

createTodo('Write Fetch API article').then(todo => console.log(todo));

Key details:

  • Always set Content-Type: application/json when sending JSON.
  • Use JSON.stringify on the body.

Example: Updating with PATCH and handling 4xx errors

Sometimes you only want to update a single field. Here’s a PATCH example that also distinguishes user errors (4xx) from server errors (5xx).

async function markTodoDone(id) {
  const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${id}`, {
    method: 'PATCH',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ completed: true }),
  });

  if (!response.ok) {
    if (response.status >= 400 && response.status < 500) {
      const details = await response.text();
      throw new Error(`Client error \({response.status}: }\(details}`);
    }
    throw new Error(`Server error ${response.status}`);
  }

  return response.json();
}

This kind of error handling is the difference between “it works on my machine” and something you can ship to production.


Authenticated examples of JavaScript Fetch API examples

Real apps rarely work with public, unauthenticated APIs. These examples include authorization headers, cookies, and token refresh patterns you’ll see in production.

Example: Bearer token with fetch

Most modern backends use Bearer tokens (often JWTs) in the Authorization header.

async function getProfile(token) {
  const response = await fetch('https://api.example.com/profile', {
    headers: {
      'Authorization': `Bearer ${token}`,
      'Accept': 'application/json',
    },
    credentials: 'include', // if your API also uses cookies
  });

  if (!response.ok) {
    throw new Error(`Profile request failed: ${response.status}`);
  }

  return response.json();
}

Note the use of credentials: 'include' if your API also relies on cookies. The official MDN docs have a good explanation of credentials and CORS behavior: https://developer.mozilla.org/en-US/docs/Web/API/fetch

Example: Auto-refreshing an expired token

A more advanced example of JavaScript Fetch API usage is wrapping fetch in a helper that retries when a token expires.

let accessToken = null;

async function authFetch(input, init = {}) {
  if (!accessToken) {
    accessToken = await getNewAccessToken();
  }

  const withAuth = {
    ...init,
    headers: {
      ...(init.headers || {}),
      'Authorization': `Bearer ${accessToken}`,
    },
  };

  let response = await fetch(input, withAuth);

  if (response.status === 401) {
    // Token expired, try once more with a new token
    accessToken = await getNewAccessToken();

    const retryInit = {
      ...withAuth,
      headers: {
        ...(withAuth.headers || {}),
        'Authorization': `Bearer ${accessToken}`,
      },
    };

    response = await fetch(input, retryInit);
  }

  if (!response.ok) {
    throw new Error(`Request failed: ${response.status}`);
  }

  return response.json();
}

This pattern is common in React, Vue, and Svelte apps that talk to OAuth2 or OpenID Connect providers.


File upload and download: real examples with Fetch

The next class of examples of JavaScript Fetch API examples covers files: sending FormData, downloading blobs, and triggering user downloads.

Example: Uploading a file with FormData

Here’s a realistic file upload example, like sending a profile picture or document.

async function uploadAvatar(file) {
  const formData = new FormData();
  formData.append('avatar', file);

  const response = await fetch('https://api.example.com/upload-avatar', {
    method: 'POST',
    body: formData,
  });

  if (!response.ok) {
    throw new Error(`Upload failed: ${response.status}`);
  }

  return response.json();
}

// Usage with an <input type="file" id="avatar">
const input = document.getElementById('avatar');
input.addEventListener('change', async () => {
  const file = input.files[0];
  if (!file) return;

  try {
    const result = await uploadAvatar(file);
    console.log('Upload result:', result);
  } catch (error) {
    console.error(error);
  }
});

No Content-Type header is set manually here. The browser sets the correct multipart boundary when you pass FormData directly.

Example: Downloading a file and saving it

Another practical example of JavaScript Fetch API usage is downloading a file as a blob and triggering a save.

async function downloadReport() {
  const response = await fetch('https://api.example.com/report.pdf');

  if (!response.ok) {
    throw new Error(`Download failed: ${response.status}`);
  }

  const blob = await response.blob();
  const url = URL.createObjectURL(blob);

  const a = document.createElement('a');
  a.href = url;
  a.download = 'report.pdf';
  document.body.appendChild(a);
  a.click();
  a.remove();

  URL.revokeObjectURL(url);
}

This pattern appears in internal tools, analytics dashboards, and anywhere your users export CSV or PDF data.


In 2024–2025, the best examples of JavaScript Fetch API examples go beyond simple GET/POST. Developers are increasingly using streaming, request cancellation, and standardized APIs across environments.

Example: Canceling slow requests with AbortController

Users expect snappy interfaces. When they type in a search box, you don’t want old, slow requests overwriting new results. Here’s how to cancel outdated requests.

let currentController = null;

async function searchMovies(query) {
  if (currentController) {
    currentController.abort();
  }

  currentController = new AbortController();

  const response = await fetch(`https://api.example.com/movies?q=${encodeURIComponent(query)}`, {
    signal: currentController.signal,
  });

  if (!response.ok) {
    throw new Error(`Search failed: ${response.status}`);
  }

  return response.json();
}

AbortController is now widely supported in browsers and in modern Node.js, which means you can use the same pattern across front-end and back-end code.

Example: Reading a streaming response

For large responses or server-sent events, streaming helps you start rendering before all data arrives. MDN has an in-depth guide on streams and ReadableStream here: https://developer.mozilla.org/en-US/docs/Web/API/Streams_API

Here’s a simplified example of reading a text stream:

async function streamLogs() {
  const response = await fetch('https://api.example.com/log-stream');

  if (!response.ok || !response.body) {
    throw new Error('Streaming not supported or request failed');
  }

  const reader = response.body.getReader();
  const decoder = new TextDecoder();

  while (true) {
    const { value, done } = await reader.read();
    if (done) break;
    const chunk = decoder.decode(value, { stream: true });
    console.log('Log chunk:', chunk);
  }
}

Streaming examples include live logs, AI-generated text, and any long-running process where incremental updates matter.


Using Fetch in Node.js: server-side examples

Since Node.js 18, fetch is available globally in Node without extra libraries. That means many examples of JavaScript Fetch API examples now apply both in the browser and on the server.

Example: Server-side data fetch with timeout logic

Server code often needs stricter timeouts than browsers. Here’s a Node-friendly pattern that combines fetch with AbortController.

async function fetchWithTimeout(url, { timeoutMs = 5000, ...options } = {}) {
  const controller = new AbortController();
  const id = setTimeout(() => controller.abort(), timeoutMs);

  try {
    const response = await fetch(url, {
      ...options,
      signal: controller.signal,
    });

    if (!response.ok) {
      throw new Error(`Request failed: ${response.status}`);
    }

    return response.json();
  } finally {
    clearTimeout(id);
  }
}

// Example usage in an Express route
// app.get('/api/weather', async (req, res) => {
//   try {
//     const data = await fetchWithTimeout('https://api.weather.gov/gridpoints/MPX/107,71/forecast');
//     res.json(data);
//   } catch (error) {
//     res.status(504).json({ error: 'Upstream timeout' });
//   }
// });

The National Weather Service API at https://www.weather.gov/documentation/services-web-api is a good real API to test server-side Fetch code against.


Accessibility, reliability, and data sources you can trust

When you integrate third-party APIs with Fetch, you want sources that are stable and well-documented. For health or research-oriented apps, that often means government or academic APIs.

A few examples of reliable sources you can reach with these same Fetch patterns:

  • U.S. government open data via Data.gov: https://www.data.gov
  • National Institutes of Health open data and APIs: https://datascience.nih.gov/data
  • Academic datasets and APIs from universities such as Harvard: https://library.harvard.edu/services-tools/datasets

The examples of JavaScript Fetch API examples shown earlier can be adapted directly to these APIs: swap the URL, update headers if needed, and parse the returned JSON according to the provider’s schema.


FAQ: common questions about Fetch with real examples

What are some real examples of JavaScript Fetch API examples in production apps?

Real-world uses include:

  • Autocomplete search against a product or article index
  • Periodic polling of a status endpoint for long-running jobs
  • Uploading images or documents via FormData
  • Downloading CSV or PDF reports as blobs
  • Calling internal microservices from a Node.js backend using fetch

All of these reuse the patterns shown above: async/await, error checks, and sometimes AbortController.

Can you show an example of handling JSON and non-JSON responses in one place?

Yes. Here’s a small helper that inspects the Content-Type header:

async function fetchSmart(url, options) {
  const response = await fetch(url, options);

  if (!response.ok) {
    throw new Error(`Request failed: ${response.status}`);
  }

  const contentType = response.headers.get('Content-Type') || '';

  if (contentType.includes('application/json')) {
    return response.json();
  }

  if (contentType.startsWith('text/')) {
    return response.text();
  }

  return response.blob();
}

This pattern is handy when you’re calling third-party APIs that sometimes send JSON and sometimes send files.

Are these Fetch examples still relevant with libraries like Axios?

Yes. Axios is still popular, but in 2024–2025 the native Fetch API is supported across all evergreen browsers and modern Node.js. Many teams now prefer to standardize on Fetch and add a thin wrapper (like the authFetch and fetchSmart examples) instead of pulling in a separate HTTP library.

Where can I read more authoritative documentation about Fetch?

The best starting point for detailed Fetch documentation is MDN Web Docs: https://developer.mozilla.org/en-US/docs/Web/API/fetch. For server-side usage, the Node.js docs on the Fetch API are also worth reading: https://nodejs.org/api/globals.html#fetch


These real examples of JavaScript Fetch API examples are designed to drop straight into modern front-end and back-end projects. Start with the simple patterns, then layer on authentication, streaming, and cancellation as your app grows more sophisticated.

Explore More JavaScript Code Snippets

Discover more examples and insights in this category.

View All JavaScript Code Snippets