Server Actions

Async server functions callable from client/server to mutate data.

Since Next 14 (stable) Spec ↗

Syntax

'use server'; export async function action(formData) { ... }

Parameters

NameTypeRequiredDescription
input FormData | serializable args Yes Form data (when used as a form `action`) or bound arguments.

Returns

Promise<Serializable> — A serializable result returned to the caller.

Examples

// app/actions.ts
'use server'
import { revalidatePath } from 'next/cache'

export async function createTodo(formData: FormData) {
  const text = String(formData.get('text'))
  await db.todos.create({ text })
  revalidatePath('/todos')
}
// Server Component form using the action
import { createTodo } from './actions'

export default function Page() {
  return (
    <form action={createTodo}>
      <input name="text" />
      <button type="submit">Add</button>
    </form>
  )
}
'use client'
import { useTransition } from 'react'
import { createTodo } from './actions'

export function QuickAdd() {
  const [pending, start] = useTransition()
  return (
    <button
      disabled={pending}
      onClick={() => start(() => createTodo(new FormData()))}
    >
      Add
    </button>
  )
}

Notes

Marked with `'use server'` (file-level or inline). They run only on the server, can be passed to `<form action>` or called from event handlers, and arguments/return values must be serializable. Always validate inputs and authorize the caller — actions are public endpoints. Pair with `revalidatePath`/`revalidateTag`.

See also