why server actions? answering the most common questions - By Sourav Mishra (@souravvmishra)

okeyy, so let's see why next.js server actions exist and when you should actually use them.

BySourav Mishra5 min read

"what's the point of server actions?"

i see this question everywhere—on twitter, reddit, and discord. devs who have been using next.js for years look at server actions and ask: why should i use this instead of traditional api routes?

let me break it down in simple terms.


what server actions replace

before server actions, handling form submissions in next.js meant writing an api route, setting up state, calling fetch('/api/submit'), handling errors, and refreshing the UI.

with server actions, you write an async function directly on the server and call it straight from your form or button.

// app/actions.ts
'use server';

export async function createPost(formData: FormData) {
  const title = formData.get('title');
  await db.post.create({ data: { title } });
}

zero api boilerplate. full typescript auto-completion.


when to use server actions

  • form submissions: forms, comments, signups, profile updates.
  • simple mutations: toggling a like button, deleting an item, saving settings.
  • revalidating pages: calling revalidatePath('/dashboard') updates the UI instantly.

when NOT to use them

  • public REST APIs: if third-party mobile apps or external services call your endpoints, stick to API Routes (route.ts).
  • heavy data fetching: Server Components (page.tsx) handle fetching; Server Actions handle mutations (saving/editing data).

they make submitting and updating data in next.js super fast without writing endless API boilerplate.

The Traditional API Route Flow

The Server Action Equivalent

// app/actions.ts
"use server";

export async function createPost(formData: FormData) {
  const title = formData.get("title") as string;
  const content = formData.get("content") as string;
  
  await db.posts.create({ title, content });
  revalidatePath("/posts");
}

// app/posts/new/page.tsx
import { createPost } from "@/app/actions";

export default function NewPostPage() {
  return (
    <form action={createPost}>
      <input name="title" />
      <textarea name="content" />
      <button type="submit">Create</button>
    </form>
  );
}

One function. Direct import. Type-safe. No API route boilerplate.

The Real Benefits

1. Progressive Enhancement

Forms using Server Actions work without JavaScript. The form submits via a standard POST request, the server handles it, and the page updates.

2. Colocation

Your mutation logic lives next to where it's used. No jumping between /api/ routes and components. The mental overhead drops significantly.

3. Automatic Type Safety

When you import a Server Action, TypeScript knows its signature. No need for zod schemas on both client and server, no type mismatches.

4. Built-in Integration with Caching

Server Actions integrate directly with Next.js caching, allowing you to easily call revalidatePath or revalidateTag after a mutation.

5. Single Server Roundtrip

When you call a Server Action, Next.js returns both the action result AND the updated React tree in one response, collapsing the traditional client-server communication flow into one round trip.

When NOT to Use Server Actions

Server Actions aren't always the answer:

1. Complex Authentication/Middleware

If you need fine-grained control over headers, CORS, rate limiting, or middleware, API routes give you more flexibility.

2. External API Integrations

If you're building a webhook endpoint or a public API that non-Next.js clients will call, use API routes.

3. Long-Running Jobs

Server Actions should return quickly. For video processing, report generation, or anything that takes more than a few seconds, trigger a background job and poll for status instead.

4. You Need React Query's Features

If you heavily rely on React Query for complex caching or optimistic updates, you can continue to use it alongside Server Actions.

The Mental Model Shift

The real value of Server Actions isn't any single feature - it's the mental model change. The boundary between client and server becomes almost invisible. You just write functions and use them.

My Recommendation

  1. For new projects: Use Server Actions for mutations by default. Add API routes when you need them.
  2. For existing projects: Gradually adopt Server Actions for new features.
  3. For simple CRUD: Server Actions are almost always the right choice.
  4. For complex state management: Combine with React Query or your existing state solution.

Ready to implement Server Actions? Check out my complete guide: Next.js Server Actions: Complete Guide with Form Handling & Validation.

Frequently Asked Questions

Q: What are Next.js Server Actions?

Server Actions are async functions that run on the server and can be called directly from React components. They replace API routes for mutations, providing type-safe, colocated server logic with automatic form handling.

Q: Should I use Server Actions or API routes?

Use Server Actions for form submissions, CRUD operations, and simple mutations. Use API routes for webhook endpoints, external API integrations, complex authentication middleware, or when non-Next.js clients need access.

Q: Can I use Server Actions with React Query?

Yes. You can use Server Actions as the mutation function in React Query's useMutation. This gives you Server Actions' simplicity with React Query's caching, optimistic updates, and retry logic.

Q: Do Server Actions work without JavaScript?

Yes. Forms using Server Actions work via standard POST requests even if JavaScript hasn't loaded. This is called progressive enhancement and improves accessibility and reliability.

Share this post

Cover image for why server actions? answering the most common questions

You might also like

See all