DEV Community

Mason Roy
Mason Roy

Posted on

How to Run Supabase Edge Functions Locally Without a Separate Runtime

Running Supabase Edge Functions Locally with tinbase

Supabase Edge Functions are useful when you need server-side logic without building a separate backend service. But during local development, setting up the complete environment around a project can add friction.

What if you could keep your local backend, database, authentication, and Edge Functions in one lightweight development environment?

This is where tinbase can be useful. It is a Supabase-compatible backend that can run locally and provides support for Edge Functions alongside database, Auth, Storage, Realtime, and Row Level Security.

In this tutorial, we will create a simple Edge Function and invoke it from a JavaScript application.

What We Are Building

The example will have this flow:

Client
   ↓
supabase.functions.invoke()
   ↓
tinbase
   ↓
Edge Function
   ↓
JSON Response
Enter fullscreen mode Exit fullscreen mode

The important part is that the client can continue using the familiar Supabase SDK.

1. Create a Function

A typical Supabase project keeps Edge Functions inside:

supabase/
└── functions/
    └── hello/
        └── index.ts
Enter fullscreen mode Exit fullscreen mode

Create index.ts:

Deno.serve(async () => {
  return new Response(
    JSON.stringify({
      message: "Hello from the Edge Function!",
    }),
    {
      headers: {
        "Content-Type": "application/json",
      },
    },
  );
});
Enter fullscreen mode Exit fullscreen mode

The function simply returns a JSON response.

2. Start tinbase

With tinbase running locally, the backend can load functions from the project's supabase/functions directory.

The goal is to keep the local development environment simple:

npx tinbase start
Enter fullscreen mode Exit fullscreen mode

You now have a local Supabase-compatible backend that can handle the function alongside your other backend services.

3. Invoke the Function

Because tinbase is compatible with the Supabase client API, you can invoke the function using supabase-js.

const { data, error } = await supabase.functions.invoke("hello");

if (error) {
  console.error(error);
} else {
  console.log(data);
}
Enter fullscreen mode Exit fullscreen mode

The application does not need a custom HTTP wrapper just to communicate with the function.

4. Passing Data to a Function

Edge Functions become more useful when they accept input.

For example:

Deno.serve(async (req) => {
  const { name } = await req.json();

  return new Response(
    JSON.stringify({
      message: `Hello, ${name}!`,
    }),
    {
      headers: {
        "Content-Type": "application/json",
      },
    },
  );
});
Enter fullscreen mode Exit fullscreen mode

The client can send data:

const { data, er
Enter fullscreen mode Exit fullscreen mode

Top comments (0)