Ashvara
Blog/Engineering
Engineering

Your backend is a folder now: what Server Actions changed

For many web apps the backend is now typed functions in the frontend repo, not a separate service. The catch: every one is a public endpoint you must guard.

S
Sahil Jain
Engineering · Ashvara
Jul 14, 2026
6 min read
Server Actions

For a large share of web apps in 2026, the backend stopped being a separate service you deploy and became a folder of typed functions inside the frontend repo - and the single most important thing to understand about that shift is that it hides the network boundary rather than removing it. Server Actions let a component call a server function as if it were local, which is a genuine ergonomic leap. But that convenience quietly relocates the seam between "runs in the browser" and "runs on the server" from an obvious, guarded doorway to an invisible one buried in your component tree. Getting the productivity without the security holes comes down to one habit: treat every server function as a public endpoint, because that is exactly what it is.

Why this matters now

The architecture of a typical web app has genuinely changed. Frontend teams increasingly lean on server functions, edge runtimes, and hosted data layers instead of building and maintaining a standalone backend - in 2026 the backend for many apps is expressed as typed functions rather than long-lived services. This isn't a fringe pattern; it's the default starting point for a lot of new work on meta-frameworks.

The upside is real: no separate API to version, no duplicated types across a client/server boundary, no serialization boilerplate. You write a function, mark it server-only, and call it from a component. But the mechanism underneath is unchanged from the old world - it's still a network request, still a public surface - and the risk is that the syntax makes people forget that.

The mechanism: an RPC wearing local-function clothes

Here's the part worth internalizing. A Server Action is a remote procedure call with the ergonomics of a local one. When you write 'use server' and call that function from a component, the framework compiles it into a network request behind the scenes.

Diagram contrasting a separate backend (browser to API service to database, an explicit visible boundary) with the Server Actions model (a component calls a use-server function across a hidden dashed boundary straight to the database); a rule band stating every Server Action is reachable by a direct POST so you must authenticate and authorize inside every one, keeping actions thin over a Data Access Layer; plus a list of when you still want a real standalone endpoint

The critical consequence, stated plainly in Next.js's own security guidance: once a Server Action is created, it is reachable via a direct POST request - not just through your app's UI. Even an action that isn't imported anywhere else can still be invoked externally by anyone who finds its endpoint. The framework generates a public route for it whether you think of it that way or not.

That single fact rewrites how you have to build. The old model gave you a visible boundary - a browser talking to an API service over an obvious wire, where you naturally put auth checks at the door. The new model hides that wire inside your component tree, so it's easy to write a server function that assumes it's only ever called from your own trusted UI. It isn't.

The rule the invisible boundary demands

There's a clean discipline that makes Server Actions safe, and it's not complicated:

  • Authenticate and authorize inside every action. Don't rely on the calling component having checked. Each action must independently verify who the caller is and whether they're allowed to do this - because it's directly reachable.
  • Keep actions thin; push logic into a Data Access Layer. Just as you'd use a dedicated data-access module for reads, do the same for mutations: auth, authorization, and database logic live in a server-only module, and your 'use server' functions stay small wrappers over it. One place to get security right beats scattering checks across dozens of actions.
  • Validate every input. A directly-callable endpoint receives whatever an attacker sends, not what your form sends. Parse and validate at the boundary.

Server Actions didn't remove the network boundary - they made it invisible. And an invisible boundary is the easiest one to forget to guard.

When you still want a real, standalone endpoint

"Backend as a folder" is a great default, not a universal law. Reach for an explicit Route Handler or a separate service when:

  • You need a public, format-flexible endpoint - JSON, XML, webhooks, RSS, a proxy - reachable independent of a page.
  • The caller isn't your own UI (third-party integrations, mobile clients, partners).
  • You need genuine parallel or long-running/background execution.
  • You simply want the boundary to be explicit, visible, and boring - a place you deliberately walk up to rather than a seam hidden in a component. (Note: Route Handlers have no built-in CSRF protection and accept any method including GET, so you secure them yourself.)

Our opinion

Our take: the "backend is a folder" model is a real productivity win, and you should use it - but only if the whole team internalizes that every action is a public door. The failure mode we watch for isn't performance; it's a beautifully ergonomic mutation that trusts its caller and ships an unauthenticated path straight to the database. The convenience is safe exactly to the degree that your team treats these functions with the same suspicion they'd give a hand-written public API route.

We'd also argue this makes the Data Access Layer pattern more important, not less. When the boundary was a separate service, the architecture forced some discipline on you. Now that the boundary is invisible, the discipline has to come from you - a deliberate server-only layer where all the auth and data logic lives. Get that right and Server Actions are excellent. Skip it and you've built a fast path to your own worst day.

How Ashvara helps

We build web apps on the modern meta-framework stack, and we build them with the boundary in mind: thin actions over a real data-access layer, auth and validation enforced on every server function, and an explicit endpoint where an explicit endpoint belongs. You get the speed of "backend as a folder" without the quietly-unauthenticated surface that so often ships with it.

If you're building on Server Actions and want it architected so the convenience doesn't become a liability, that's our backend and API development work. Talk to us and we'll help you keep the boundary safe even when it's invisible.

Source: Next.js - Data Security guide and How to think about security in Next.js (Server Actions are reachable by direct POST; authenticate, authorize, and validate inside each one).

Share this article
S
Sahil Jain

Founder at Ashvara, a studio that builds software end to end - mobile, web, AI, and the systems behind them. Writes about shipping products that last.

Building something? Let's talk.