Connecting directly to Postgres Connecting to Postgres from Edge Functions.
Connect to your Postgres database from an Edge Function by using the supabase-js
client.
You can also use other Postgres clients like Deno Postgres
The supabase-js
client is a great option for connecting to your Supabase database since it handles authorization with Row Level Security, and it automatically formats your response as JSON.
_24 import { createClient } from 'jsr:@supabase/supabase-js@2'
_24 Deno.serve(async (req) => {
_24 const supabase = createClient(
_24 Deno.env.get('SUPABASE_URL') ?? '',
_24 Deno.env.get('SUPABASE_ANON_KEY') ?? '',
_24 { global: { headers: { Authorization: req.headers.get('Authorization')! } } }
_24 const { data, error } = await supabase.from('countries').select('*')
_24 return new Response(JSON.stringify({ data }), {
_24 headers: { 'Content-Type': 'application/json' },
_24 return new Response(String(err?.message ?? err), { status: 500 })
Using a Postgres client#
Because Edge Functions are a server-side technology, it's safe to connect directly to your database using any popular Postgres client. This means you can run raw SQL from your Edge Functions.
Here is how you can connect to the database using Deno Postgres driver and run raw SQL.
Check out the full example .
_39 import * as postgres from 'https://deno.land/x/postgres@v0.17.0/mod.ts'
_39 // Get the connection string from the environment variable "SUPABASE_DB_URL"
_39 const databaseUrl = Deno.env.get('SUPABASE_DB_URL')!
_39 // Create a database pool with three connections that are lazily established
_39 const pool = new postgres.Pool(databaseUrl, 3, true)
_39 Deno.serve(async (_req) => {
_39 // Grab a connection from the pool
_39 const connection = await pool.connect()
_39 const result = await connection.queryObject`SELECT * FROM animals`
_39 const animals = result.rows // [{ id: 1, name: "Lion" }, ...]
_39 // Encode the result as pretty printed JSON
_39 const body = JSON.stringify(
_39 (key, value) => (typeof value === 'bigint' ? value.toString() : value),
_39 // Return the response with the correct content type header
_39 return new Response(body, {
_39 headers: { 'Content-Type': 'application/json; charset=utf-8' },
_39 // Release the connection back into the pool
_39 return new Response(String(err?.message ?? err), { status: 500 })
You can use Drizzle together with Postgres.js . Both can be loaded directly from npm:
supabase/functions/ import_map.json
_10 "drizzle-orm": "npm:drizzle-orm@0.29.1",
_10 "drizzle-orm/": "npm:/drizzle-orm@0.29.1/",
_10 "postgres": "npm:postgres@3.4.3"
supabase/functions/drizzle/ index.ts
_14 import { drizzle } from 'drizzle-orm/postgres-js'
_14 import postgres from 'postgres'
_14 import { countries } from '../_shared/schema.ts'
_14 const connectionString = Deno.env.get('SUPABASE_DB_URL')!
_14 Deno.serve(async (_req) => {
_14 // Disable prefetch as it is not supported for "Transaction" pool mode
_14 const client = postgres(connectionString, { prepare: false })
_14 const db = drizzle(client)
_14 const allCountries = await db.select().from(countries)
_14 return Response.json(allCountries)
You can find the full example on GitHub .
Deployed edge functions are pre-configured to use SSL for connections to the Supabase database. You don't need to add any extra configurations.
If you want to use SSL connections during local development, follow these steps:
_10 SSL_CERT_FILE=/path/to/cert.crt # set the path to the downloaded cert
_10 DENO_TLS_CA_STORE=mozilla,system