• Blog
  • Documentation
  • Courses
  • Changelog
  • AI Starters
  • UI Kit
  • FAQ
  • Supamode
    New
  • Pricing

Launch your next SaaS in record time with Makerkit, a React SaaS Boilerplate for Next.js and Supabase.

Makerkit is a product of Makerkit Pte Ltd (registered in the Republic of Singapore)Company Registration No: 202407149CFor support or inquiries, please contact us

About
  • FAQ
  • Contact
  • Verify your Discord
  • Consultation
  • Open Source
  • Become an Affiliate
Product
  • Documentation
  • Blog
  • Changelog
  • UI Blocks
  • Figma UI Kit
  • AI SaaS Starters
License
  • Activate License
  • Upgrade License
  • Invite Member
Legal
  • Terms of License

Server Actions vs Route Handlers in Next.js

Dec 16, 2024

Next.js allows you to use Server Actions or API Route Handlers to execute code server side and call it from the client. Which one should you use?

next

There are two ways to execute server-side code in Next.js:

  1. Server Actions
  2. API Route Handlers

It's often misunderstood which ones to use. This article will help you understand the differences between them.

Server Actions Functions

Server Actions, introduced in Next.js 13, are special functions that, while they are executed server side, can be called from React Components client-side just like any other Javascript function.

There are two ways to define a Server Action:

  1. Globally per file: Using the directive use server at the top of the file. This turns every exported function in the file into a Server Action.
  2. Per Function: Using the use server directive at the top of the body of a function. This turns the function only into a Server Action.

To declare all the exported functions as server actions, we place the directive use server at the top of the file:

app/lib/server-actions.ts
'use server';
export async function createPostAction(data: {
title: string;
content: string;
}) {
const db = createDbService();
const result = await db.createPost(data);
return {
success: true
};
}

Instead, we can also declare a Server Action in a Server Component:

app/page.tsx
function MyComponent() {
// form that uses "createPostAction"
}
async function createPostAction(data: {
title: string;
content: string;
}) {
'use server';
const db = createDbService();
const result = await db.createPost(data);
return {
success: true
};
}

Normally, it's more common to create a server actions file, because it's more common to call Server Actions from Client Components (in my experience).

It's very important to note that Server Actions, at this time, are exclusively POST requests. POST requests are suitable for creating, updating, and deleting data, but they're not suitable for reading data.

Server Functions

Starting from Next.js 15/React 19, Server Actions are no longer a thing, or better said, they're a type of Server Function. Server Functions, like Server Actions, are functions that can be called from the client-side.

However, unlike Server Actions which are POST-only, Server Functions can be called using any HTTP method.

At this time, they're still experimental, however it's where React is heading. For more information, please head to the Server Functions documentation.

Route Handlers

Route Handlers are "normal" API routes that we would commonly use in Next.js Pages Router, or similar frameworks.

Next.js allows us to create API handlers by exporting a function named like an HTTP verb from special files named route.ts:

app/api/hello/route.ts
import { NextRequest, NextResponse } from 'next/server';
export const GET = async (request: NextRequest) => {
const db = createDbService();
const posts = await db.getPosts();
return NextResponse.json(posts);
};

The GET function exported from a route.ts file will turn the function into an API handler responding to GET requests.

Since we created the file at app/api/hello/route.ts, Next.js will automatically create a route at /api/hello that will respond to GET requests and execute the body of the function as a server-side function.

If you were to export a function named POST from the same file, Next.js would create a route at /api/hello that would respond to POST requests and execute the body of the function as a server-side function.

Main Differences between a Server Action and a Route Handler in Next.js

As you can see, there are similarities between a Server Action and a Route Handler, but there are also some key differences:

  1. Server Actions are exclusively POST requests: Server Actions are exclusively executed on the server, and they're only executed when a POST request is made. This means that Server Actions are not suitable for reading data. This is true at this time, but with Server Functions being released, things are likely going to change.
  2. Server Actions are not suitable for reading data: At this time, refrain from using a Server Action instead of a GET request to read data. GET requests are preferable for reading data since you can cache them natively.
  3. Server Actions are only usable from your Next.js app: Server Actions are only usable from your Next.js app, and are not meant to be used externally.

When should you use a Server Action?

Prefer Server Actions for mutations when calling a mutation (POST, DELETE, UPDATE) from within your Next.js application.

The enhanced developer experience from Server Actions makes them perfect to call Server-side functions from within your Next.js application.

In fact, calling a Server Actions is just like any other function, except Next.js will automatically run it on the server.

tsx
<form onSubmit={e => {
e.preventDefault();
// Call the Server Action
return createPostAction(data);
}>
{/* ... */}
</form>

You also get strong-typing for free, since you're just calling a function.

Instead, calling a Route Handler involves using a fetch call to the API. Which it isn't hard, bit it's not as convenient as calling a Server Action.

When should you use a Route Handler?

  1. Prefer Route Handlers when fetching data from a Client Component: GET requests can be cached and are more suitable for reading data. This may change with the introduction of Server Functions, so keep an eye on this.
  2. Use Route Handlers when calling the API from an external source: whether you're using a GET, POST or any other HTTP method, Route Handlers are the way to go when calling the API from an external source (webhooks, APIs, etc.).

NB: in the future, Server Functions will allow us to call different HTTP methods, so Route Handlers will become less relevant in the context of calling these functions from within the Next.js application.

Conclusion

In this article, we've explored the different ways to call the API from within your Next.js application.

I hope this article has been useful to you, and I'd love to hear your thoughts on it.

Some other posts you might like...
Jun 9, 2025Claude Code: Build a SaaS with AIThis is a step-by-step guide to building an AI Content Repurposer SaaS by vibe-coding with Claude Code and Makerkit.
Apr 23, 2025Next.js Security: A Comprehensive Guide how to secure your Next.js applicationA comprehensive guide to securing your Next.js application, focusing on practical strategies to protect your application and user data from common vulnerabilities.
Jan 17, 2025Best Practices for Building a SaaS with Windsurf and MakerkitWindsurf is a new AI-powered editor taking the developer experience to the next level. With the new optimized rules for Makerkit, building a SaaS just got a lot easier!
Jan 16, 2025Best Practices for Building a SaaS with Cursor and MakerkitCursor is the hottest AI editor in the market. With the new optimized rules for Makerkit, building a SaaS just got a lot easier!
Dec 26, 2024Choosing the best hosting provider for your Next.js applicationIn this post, we'll show you how to choose the best hosting provider for your Next.js application.
Dec 24, 2024Next.js API Routes: The Ultimate GuideLearn how to build robust, secure, and efficient API endpoints in Next.js. This comprehensive guide will walk you through the critical best practices for creating robust, secure, and efficient API endpoints in Next.js.