When Server Actions landed in Next.js, the question every developer faced was the same: do I rewrite my whole API, or ignore them entirely? Both choices are wrong.
If you are building a SaaS on Next.js, the answer is not one or the other -- it is knowing which tool fits which situation. Get this right from the start and you avoid the worst kind of refactor: the one where you realize six months in that every form in your app is harder to maintain than it needed to be.
An API route is a traditional HTTP endpoint at app/api/*.ts. It handles requests from anywhere -- your front end, a mobile app, a third-party webhook, a customer integration. It speaks HTTP, lives at a URL, and behaves exactly like any REST endpoint you have built before.
A Server Action is a function marked "use server" that runs on the server and can be called directly from a React component. No HTTP, no fetch, no JSON wiring. You call the function, Next.js handles the transport.
Both run on your server. The difference is who is calling them and why.
Use an API route when:
Use a Server Action when:
A quick test: if you can imagine a mobile app or external service calling this endpoint, make it an API route. If only your own UI will ever trigger it, a Server Action is almost always simpler.
Forms and settings pages: Server Actions. A profile update, a preferences form, a password change -- these are triggered by your own UI and benefit from the simplified wiring. You call the function, revalidate the page, done. If you have ever built a multi-step onboarding wizard, you know how much plumbing a form-to-API cycle adds.
Auth: API routes. Your login and register endpoints may be called by mobile apps, browser extensions, or automated tests. Keep them as HTTP endpoints so they work from anywhere. The authentication setup in this boilerplate uses API routes for exactly this reason.
Stripe webhooks: Always API routes. Stripe sends an HTTP POST to your domain, not a function call. There is no choice here.
Admin mutations: Server Actions work well for one-off admin operations that only your internal dashboard triggers. But if you plan to expose an admin API for automation later, start with a route.
File uploads: API routes. FormData with binary content needs real HTTP handling and explicit content-type control.
Dashboard data: Neither -- fetch in a Server Component. If you only need to read data for your own UI, you do not need an API route or a Server Action at all. Call your service layer directly from a page or a server component.
The Next.js SaaS Boilerplate uses API routes as the default in app/api/. They are thin handlers that validate input, call a service, and return a response -- nothing more. This makes every endpoint testable and callable from outside your app without special handling.
Server Actions are not wired in by default because the boilerplate is built for teams who may eventually want a mobile app or third-party API access. But the module structure keeps business logic in services, not in the transport layer, so switching later is straightforward.
If your SaaS is entirely web-only and you want to move fast on internal forms, Server Actions are a legitimate shortcut. Use them for mutations that only your own UI will ever trigger and you will write noticeably less code.
Build your auth, payment, and webhook handlers as API routes from day one. They will be called by things outside your control. For everything else -- forms, settings, admin actions -- ask whether anyone outside your own UI will ever need to trigger it. If the answer is "not for a long time", start with a Server Action and add an API route later only if the need appears.
That is not a compromise. It is the right architecture for a small team shipping fast.
Get the Next.js SaaS Boilerplate and start with a codebase where these decisions are already made for you -- auth, payments, email, and database all wired together so your first PR is a feature, not a setup task.