What Are Server Actions?
The idea in one sentence
Section titled “The idea in one sentence”A Server Action is an async function marked with the "use server" directive that runs only on the server, and you can call it straight from a <form> or from a Client Component without writing an API route.
The "use server" directive
Section titled “The "use server" directive”There are two ways to mark a function as a Server Action. You can add "use server" at the top of an inline async function inside a Server Component, or you can add 'use server' at the top of a whole module file so every export in that file becomes an action.
// app/page.tsx — an inline Server Action inside a Server Componentexport default function Page() { async function createTodo(formData: FormData) { 'use server' const title = String(formData.get('title')) await db.todo.create({ data: { title } }) }
return ( <form action={createTodo}> <input name="title" /> <button type="submit">Add</button> </form> )}A shared actions module
Section titled “A shared actions module”When several components need the same action, put it in a dedicated file. Add 'use server' once at the top and every export becomes a callable action. This keeps mutation logic in one place and lets Client Components import it.
// app/actions.ts — every export here is a Server Action'use server'
export async function createTodo(formData: FormData) { const title = String(formData.get('title')) await db.todo.create({ data: { title } })}
export async function deleteTodo(id: string) { await db.todo.delete({ where: { id } })}Calling from a form and from a Client Component
Section titled “Calling from a form and from a Client Component”A Server Action can be wired directly to a form with <form action={createTodo}>, and Next.js posts the form data to the action on the server. It can also be imported into a Client Component and called like a normal function — Next.js turns that call into a network request for you.
// app/todo-button.tsx — calling an action from a Client Component'use client'
import { deleteTodo } from './actions'
export function DeleteButton({ id }: { id: string }) { return <button onClick={() => deleteTodo(id)}>Delete</button>}How it differs from a Route Handler
Section titled “How it differs from a Route Handler”A Route Handler in route.ts is a public URL you design, wire up, and fetch by hand. A Server Action is a function you call directly; Next.js generates the endpoint and the network call for you and supports progressive enhancement through forms. Reach for a Route Handler when you need a real public API or webhook; reach for a Server Action for form and mutation flows inside your own app.
graph LR A["form or Client Component"] -->|"calls action"| B["Next.js generated endpoint"] B -->|"runs on server only"| C["Server Action function"] C -->|"reads or writes"| D["Database"]