The `use server` Directive Explained

How the use server directive marks files and functions to run on the server, and the rules for calling them from Client Components.

7 min read

The use server directive marks a function or an entire file to run on the server. It is a React feature that Next.js wires into the App Router, so server code stays on the server while the client can still call it.

Place the directive at the top of a file and every exported function becomes a Server Function. Place it inside an async function body and only that function runs on the server.

index.tsindex.ts
// app/actions.ts
'use server'
 
export async function createUser(name: string, email: string) {
  const id = crypto.randomUUID()
  return { id, name, email }
}

Every export in this file is a Server Function. The client can import and call createUser, but the function body never ships in the browser bundle. This file-level form is what you use for shared actions.

The inline form marks one function instead of a whole file. It is useful when the action needs a value from the page it belongs to.

App.tsxApp.tsx
// app/contact/page.tsx
export default function ContactPage() {
  async function saveEmail(formData: FormData) {
    'use server'
    return { email: formData.get('email')?.toString() }
  }
  return <form action={saveEmail}>
    <label>Email <input type="email" name="email" required /></label>
    <button type="submit">Send</button>
  </form>
}

Here saveEmail runs on the server while ContactPage renders as a normal Server Component. Progressive enhancement still applies, so the form submits before JavaScript loads.

File-level vs inline placement

Choose the placement by how the action is shared.

PlacementUse it when
Top of a fileSeveral related actions live in one module
Inside a functionOne action needs a value from that page, such as a route parameter

Both forms produce a function the client can call. The file form is the default for real apps because it keeps actions together in one module. The inline form stays useful for a single page-local action that closes over its props.

Closing over a value has a cost worth knowing. Next.js encrypts variables captured by an inline action before sending them to the client, and on a self-hosted multi-instance deployment every instance needs the same encryption key or those references stop decrypting.

The rules around the use server directive

The directive is strict about where and how it appears. These rules decide whether your code works or fails at build time.

  • The directive must be the first thing in the file or function, above imports and other code.
  • Write it with single or double quotes, never backticks.
  • It can only mark async functions, because the call crosses the network.
  • It can only appear in server-side files. A Client Component cannot define a Server Function.

To call a Server Function from a Client Component, define it in a separate file with the use server directive at the top, then import it. The use client directive on the component does not stop the imported function from running on the server.

Return values are serialized

When a client calls a Server Function, the arguments and the return value travel over the network as serialized data. So the return value must be serializable, which is fine for plain objects and arrays but breaks for functions and classes.

  • Serializable: primitives, plain objects, arrays, FormData, Map, Set, Date, and Promises.
  • Not serializable: regular functions, classes, class instances, and React elements. Another Server Function is the exception, because it travels as a reference.

Keep return values specific to what the UI needs. Returning a raw database record is a common way to leak fields the client should never see. See Server Actions in Next.js for the full roundtrip picture.

Actions run inside a transition

When a Server Function is passed to a form or a button, React wraps the call in a transition automatically. That is what lets the UI show a pending state and stay responsive while the action runs.

In practice that means the page does not freeze during the request, and hooks such as useActionState can report a pending flag you render as a spinner or a disabled button.

If you call a Server Function directly from an event handler or an effect, no transition is created for you. Wrap the call in startTransition yourself so the same pending behavior applies.

The boundary is a trust boundary

Everything the client sends into a Server Function is untrusted, because the function is reachable over HTTP. Validate the input and check that the logged-in user is allowed to perform the action inside the function itself, not in the UI that calls it.

Next.js does supply framework-level guards, including an Origin check against the Host and encrypted action references. Those stop a cross-site request, not a logged-in user acting on a record that is not theirs.

Schema validation has the same gap. It proves the shape of the input, so a well-formed id can still point at somebody else's row. Send an identifier plus the change, then re-read the record from a trusted source using the session.

For the auth checks to write before shipping, see securing Server Actions. To decide when an action is the right tool instead of an endpoint, see Server Actions vs API Routes vs Route Handlers.

Rune AI

Rune AI

Key Insights

  • use server marks a file or an async function to run on the server only.
  • The directive must be the first line, in single or double quotes.
  • Client Components cannot define Server Functions and must import them.
  • Arguments and return values must be serializable.
  • Treat every argument as untrusted input and authorize each mutation.
RunePowered by Rune AI

Frequently Asked Questions

Can I use use server in a Client Component?

No. Client Components cannot define Server Functions. Move the function to a separate file with use server at the top, then import it into the client component.

Does use server have to use quotes?

Yes. The directive must be written with single or double quotes, not backticks, and it must be the first line of the file or function body.

What can a Server Function return?

Only serializable values: primitives, plain objects, arrays, FormData, and Promises. Functions, classes, and React elements cannot be returned to the client.

Conclusion

The use server directive is how you mark code to run only on the server. Put it at the top of a file to mark every export, or inside an async function to mark just that function, then call it from forms and Client Components.