Back to Blog
Tutorial11 min read2026-07-02

How to Run Supabase-Style Edge Functions on PandaStack

Love Supabase Edge Functions but want them next to your app and database? Learn how to build and deploy serverless edge functions on PandaStack as a Supabase alternative.

Ajay Kumar
Ajay Kumar
Founder & DevOps, PandaStack

Supabase Edge Functions are a great developer experience: write a TypeScript function, deploy it, and invoke it over HTTP, with your database a function call away. But if your app, database, and functions live on different platforms, you pay in latency and operational overhead. This guide shows how to run Supabase-style edge functions on PandaStack, where they sit alongside your container apps and managed databases.

What Supabase Edge Functions give you

Supabase Edge Functions are Deno-based serverless functions deployed to a global edge network. The model is:

  • Write a function as an HTTP handler.
  • Deploy it; get an invokable URL.
  • Access your Supabase Postgres and secrets from inside the function.
  • Pay per invocation, scale to zero.

The appeal is event-driven, short-lived compute that's cheap when idle and close to users.

The PandaStack equivalent

PandaStack includes edge functions as a first-class app type, alongside container apps, static sites, managed databases, and cronjobs. They support multiple runtimes and are event-driven. The key advantage of consolidating: your edge function, your managed PostgreSQL, and your main app all live in the same platform, so the function reaches the database over the internal network and you manage everything from one dashboard.

ConcernSupabase Edge FunctionsPandaStack Edge Functions
RuntimeDenoMultiple runtimes (Node, Python, Go, more)
Database accessSupabase PostgresManaged PostgreSQL/MySQL/Mongo/Redis, same platform
InvocationHTTP URLHTTP invoke with function tokens
Scalingscale to zeroevent-driven, included on all plans
Co-locationseparate from your app hostsame platform as apps + DB

Writing an edge function

An edge function is an HTTP handler. Here's a Node-style example that reads from a database and returns JSON:

// function.js
export async function handler(req) {
  const { searchParams } = new URL(req.url);
  const id = searchParams.get('id');

  // DATABASE_URL is injected when you link a managed database
  const result = await queryDatabase(
    'SELECT name FROM users WHERE id = $1',
    [id]
  );

  return new Response(JSON.stringify(result), {
    status: 200,
    headers: { 'content-type': 'application/json' },
  });
}

The exact handler signature depends on the runtime, but the shape is universal: receive a request, do work (often a DB query), return a response.

Migrating a Supabase function

Supabase functions use Deno's Deno.serve and the Supabase JS client. To port one:

  1. 1Replace the Supabase client with a direct DB client. Instead of createClient(...), connect to your managed PostgreSQL using the injected DATABASE_URL and a Postgres driver. This removes a layer and lets you write plain SQL.
  2. 2Move secrets to env vars. Supabase functions read secrets from the Supabase dashboard; on PandaStack you set env vars (and secrets) per function.
  3. 3Adjust the handler signature to the target runtime if you're not using Deno.

A Supabase function like this:

import { createClient } from '@supabase/supabase-js';
Deno.serve(async (req) => {
  const supabase = createClient(Deno.env.get('SUPABASE_URL')!, Deno.env.get('SUPABASE_ANON_KEY')!);
  const { data } = await supabase.from('users').select('name');
  return new Response(JSON.stringify(data));
});

becomes a direct-SQL handler against your own managed Postgres, which is often simpler and faster because there's no PostgREST hop.

Authentication with function tokens

Public edge functions need access control. PandaStack edge functions use function tokens — you pass a token to invoke a protected function, similar to how Supabase uses the anon/service keys. Generate a token, store it as a secret on the caller's side, and require it in the function:

const token = req.headers.get('authorization')?.replace('Bearer ', '');
if (token !== expectedToken) {
  return new Response('Unauthorized', { status: 401 });
}

For finer control, validate JWTs issued by your main app so the function trusts your existing auth.

Wiring up the database

Link a managed PostgreSQL instance to your edge function and DATABASE_URL is injected automatically — the same auto-wiring used for container apps. Because the database and function are on the same platform, the connection stays on the internal network rather than traversing the public internet to a separate provider.

When to use edge functions vs a container app

Use edge functions forUse a container app for
Webhooks, short-lived handlersLong-running APIs
Event-driven, spiky trafficSteady traffic, persistent connections
Glue between servicesFull backend frameworks
Lightweight transformsHeavy compute, stateful work

If you find yourself reaching for persistent connections, background workers, or a full framework, deploy a container app instead. Edge functions shine for small, event-driven units of work.

Deploying

Create an edge function, point it at your function code in the repo, link a managed database if it needs data, set any secrets, and deploy. You get an invokable URL protected by a function token. Live logs (self-hosted Elasticsearch) let you trace invocations and debug errors.

git push origin main

Conclusion

Running Supabase-style edge functions on PandaStack means writing an HTTP handler, linking a managed database for auto-injected DATABASE_URL, securing it with function tokens, and deploying it next to your apps and database. The big win over a separate edge provider is co-location: functions, database, and app all in one platform, on one network, in one dashboard.

Edge functions are included on PandaStack's free tier alongside container apps, static sites, and a managed database. Migrate your first function at [dashboard.pandastack.io](https://dashboard.pandastack.io).

References

  • [Supabase Edge Functions Documentation](https://supabase.com/docs/guides/functions)
  • [Deno: Deno.serve and HTTP](https://docs.deno.com/runtime/manual/runtime/http_server_apis)
  • [PostgreSQL: Connection URIs](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING)
  • [MDN: Request and Response (Fetch API)](https://developer.mozilla.org/en-US/docs/Web/API/Request)
  • [JSON Web Tokens (jwt.io)](https://jwt.io/introduction)

Ready to deploy?

Start free on PandaStack.

Start free on PandaStack

More in Tutorial

Browse all Tutorial articles →

See also