next-safe-action
Guides

Executing actions

There are four ways to execute a safe action from a Client Component. Each approach serves different needs:

Three execution methods: Direct Call, useAction, Form Action

Comparison

Given the same action:

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

import { z } from "zod";
import { actionClient } from "@/lib/safe-action";

export const greetUser = actionClient
	.inputSchema(z.object({ name: z.string() }))
	.action(async ({ parsedInput }) => {
		return { greeting: `Hello, ${parsedInput.name}!` };
	});

Here's how each method calls it:

src/app/page.tsx
"use client";

import { greetUser } from "./actions";

export default function Page() {
	const handleClick = async () => {
		const result = await greetUser({ name: "Alice" });

		if (result.data) {
			alert(result.data.greeting);
		}
	};

	return <button onClick={handleClick}>Greet</button>;
}

Use when: You need a simple one-off call, or you're calling from a Server Component or event handler where you don't need reactive UI updates.

Which method should I use?

NeedMethod
Simple call, no loading UIDirect call
Loading states, callbacks, reactive resultuseAction hook
Forms with callbacks, status, and prevResultuseStateAction hook
Optimistic UI updatesuseOptimisticAction hook
Progressive enhancement / no-JS formsuseActionState (React)
Server Component calling an actionDirect call

What's next?

On this page