This guide is written for developers who want a practical answer, not a giant theory dump. The goal is to help you understand the decision, use the idea in a real project, and explain it clearly in an interview or code review.
Quick answer
Use server actions for app-owned mutations close to React forms. Use API routes when external clients, webhooks, or explicit HTTP contracts matter.
Why developers search this
Developers search this when App Router examples show server actions but existing apps use API routes.
It is a good SEO topic because the search usually happens near a real task: fixing a broken build, choosing an architecture pattern, deploying an app, reviewing AI-generated code, or preparing portfolio proof. Those searches are more valuable than broad “what is programming?” traffic because the reader needs an answer they can use today.
Mental model
The question is boundary. Is this action only for your app UI, or is it an API other systems need to call and understand?
| Need | Better fit |
|---|---|
| Simple form mutation | Server action |
| Mobile app endpoint | API route |
| Webhook receiver | API route |
| Shared public contract | API route |
| Small internal dashboard action | Server action |
Practical example
"use server";
export async function createProject(formData: FormData) {
const name = String(formData.get("name") ?? "");
await saveProject({ name });
}
This example is intentionally small. In a real codebase, the surrounding details matter: naming, error handling, tests, runtime config, permissions, and how easy the next developer can understand the change.
Implementation checklist
- Validate input either way.
- Keep auth checks server-side.
- Use API routes for external callers.
- Use server actions when they reduce form boilerplate.
- Document stable contracts separately.
Common mistakes
- Treating server actions as public APIs.
- Skipping validation because code runs on the server.
- Putting business logic directly in UI files.
- Using server actions where webhooks need raw body access.
- Forgetting progressive enhancement and error handling.
How to explain this in an interview
Use a concrete sentence:
I used this pattern because [problem]. The main tradeoff was [tradeoff]. I verified it by [test or check].
That structure works because it shows judgment. Anyone can name a tool. Strong developers explain why they chose it, what could go wrong, and how they checked the result.
Related guides
- nextjs app router data fetching mistakes
- webhook signature verification nodejs
- zod validation api boundaries typescript
Sources checked
Final takeaway
Use server actions for app-owned mutations close to React forms. Use API routes when external clients, webhooks, or explicit HTTP contracts matter. Keep the implementation small, verify the edge cases, and write the decision down so the next person can trust it.
Discussion
What would you try, change, or challenge after reading this guide? Specific results and errors help the next reader.
Comments will load as you reach this section.