Netlify Edge Functions are surprisingly not just for static sites anymore; they’re a powerful, performant way to run your Remix application’s server-side logic.

Let’s see this in action. Imagine a simple Remix app with a route that fetches data from an external API.

// app/routes/items.$itemId.jsx
import { json } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";

export async function loader({ params }) {
  const response = await fetch(`https://api.example.com/items/${params.itemId}`);
  if (!response.ok) {
    throw new Response("Not Found", { status: 404 });
  }
  const item = await response.json();
  return json(item);
}

export default function ItemDetails() {
  const item = useLoaderData();
  return (
    <div>
      <h1>{item.name}</h1>
      <p>{item.description}</p>
    </div>
  );
}

When deployed to Netlify Edge Functions, the loader function above doesn’t run on a traditional server. Instead, it executes in a distributed network of edge locations, closer to your users. This means lower latency for data fetching and server-side rendering.

The magic happens in your netlify.toml configuration. You tell Netlify to treat specific routes or your entire application as Edge Functions.

# netlify.toml

[build]
  command = "npm run build" # Or your build command
  publish = "build" # Or your output directory

[[edge_functions]]
  function = "remix" # This is the name of your Edge Function
  path = "/app/*"   # This tells Netlify to route requests for /app/* to this function

And in your remix.config.js, you ensure your app is built for the edge:

// remix.config.js
/** @type {import('@remix-run/dev').AppConfig} */
module.exports = {
  ignoredRouteFiles: ["**/.*"],
  // Add this for Netlify Edge Functions
  serverBuildTarget: "netlify-edge",
  server: "./server.js", // This is a placeholder, Netlify handles the actual server entry
};

Netlify’s build process then takes your Remix app and bundles it into a format that can be deployed as an Edge Function. When a user requests a page like /app/items/123, Netlify intercepts the request at the nearest edge location. It then invokes your remix Edge Function, which executes the loader for items.$itemId.jsx, fetches the data, and returns the rendered HTML – all from the edge.

The primary problem Remix on Netlify Edge Functions solves is the latency associated with traditional server deployments. Instead of a single origin server handling all requests, the computation is distributed globally. This drastically reduces the time it takes for your application to respond, especially for geographically dispersed users. It also simplifies your infrastructure; you don’t need to manage servers, scaling, or even a dedicated Node.js environment. Netlify handles all of that.

The "server.js" file mentioned in remix.config.js is a bit of a red herring in the context of Netlify Edge Functions. While Remix typically uses a server.js file to define its Node.js server, when you configure serverBuildTarget: "netlify-edge", Netlify’s build system generates the necessary code to integrate with its Edge Functions runtime. You don’t write or deploy a server.js file yourself; Netlify takes care of transforming your Remix app into a deployable Edge Function.

This setup is particularly powerful for dynamic routes and server-rendered content, turning what might have been a slow, origin-bound request into a near-instantaneous global experience.

The next evolution is to start leveraging Netlify’s local development tooling to simulate Edge Functions and understand how your app behaves before pushing to production.

Want structured learning?

Take the full Netlify course →