Changer le thème

Supabase Edge Functions en pratique : runtime Deno et déploiement edge mondial

Easton editorial illustration: Deno edge-function capsule facing a Cloudflare Worker capsule across runtime, cold-start, and deployment gauges

Sur le tableau de bord de monitoring, la ligne rouge clignote — le temps de réponse API atteint 2,3 secondes.

L’utilisateur est au Japon, le serveur en Ohio. Le aller-retour seul prend 120 ms, sans compter la requête base de données et la logique métier. Comment ne pas être lent ?

« Et si on essayait les edge functions ? » Un collègue m’envoie ça sur Slack.

J’étais sceptique. Des edge functions ? Ce n’est pas juste du code exécuté ailleurs ? Quelle différence ça peut faire ? Puis j’ai testé — et j’ai été surpris. Cold start 120 ms, réponse en 47 ms. Même logique, déplacée d’Ohio vers un nœud edge à Tokyo : presque 5× plus rapide.

Supabase Edge Functions s’exécute sur le runtime Deno, au plus près des utilisateurs via le réseau edge mondial. Cet article explique pourquoi c’est si rapide, la différence entre Deno et Node.js, comment monter une Edge Function de zéro, et comment choisir face à Cloudflare Workers.

1. Concepts clés : qu’est-ce qu’une Edge Function, et pourquoi c’est rapide

En bref, une Edge Function déplace votre code d’un « serveur central » vers un « nœud edge ».

Avant, quand vous déployiez une fonction Lambda, elle tournait dans une région fixe (US East, Europe, etc.). Un utilisateur à Tokyo envoyait une requête ; les données traversaient l’océan jusqu’à l’Est des États-Unis, revenaient traitées. La distance physique fixe une limite de latence — la lumière n’est pas infinie.

Edge Functions inverse la logique. Votre code est empaqueté dans un format compact appelé ESZip, puis distribué automatiquement sur des dizaines de nœuds edge mondiaux. Une requête depuis Tokyo s’exécute à Tokyo — la latence transocéanique disparaît.

Qu’est-ce qu’ESZip ?

Format de bundle développé par l’équipe Deno. Contrairement à un bundle JavaScript classique, ESZip embarque aussi le graphe complet des dépendances de modules. Résultat : au démarrage, plus besoin de télécharger des dépendances sur le réseau — tout est dans un seul fichier. Le cold start passe de « téléchargement + résolution + exécution » à « décompression + exécution ».

Modèle d’exécution Isolate

Supabase Edge Functions tourne dans un V8 Isolate, pas dans un conteneur ou une VM traditionnelle. Un Isolate, c’est comme un conteneur Worker ultra-léger. Un processus peut héberger des dizaines d’Isolates, chacun traitant une requête. Plus léger qu’un conteneur, plus rapide au démarrage.

D’après la documentation Supabase, le temps CPU maximal d’un Isolate est de 400 s (limite souple + limite stricte). Ça paraît énorme, mais les edge functions ne sont pas faites pour le gros calcul — validation JWT, proxy, logique légère. Le travail lourd reste sur le serveur central.

Voici la Edge Function la plus simple :

// Exemple minimal de Edge Function
import "jsr:@supabase/functions-js/edge-runtime.d.ts"

Deno.serve(async (req) => {
  const { name } = await req.json()
  const data = { message: `Hello ${name}!` }
  return new Response(JSON.stringify(data), {
    headers: { "Content-Type": "application/json" }
  })
})

Ce code tourne sur un nœud edge. La requête entre, Deno.serve la traite, la réponse repart — le tout au nœud le plus proche de l’utilisateur.

2. Runtime Deno : la « version sécurisée » de Node.js

La première fois que j’ai entendu parler de Deno, j’ai eu la même question : Node.js est si mature, pourquoi un nouveau runtime ?

La réponse est simple : Node.js a été conçu trop tôt ; beaucoup de problèmes sont apparus après coup.

Différence de sécurité

Node.js fait confiance par défaut. Votre code veut lire le disque ? OK. Se connecter au réseau ? Libre. Exécuter des commandes système ? Possible. Une dépendance malveillante peut tout faire.

Deno inverse la logique. Par défaut, le code est enfermé dans une sandbox : pas de lecture disque, pas de réseau, pas de commandes système. Pour obtenir une permission, il faut la déclarer explicitement :

# Permission réseau
deno run --allow-net server.ts

# Lecture/écriture de fichiers
deno run --allow-read --allow-write file_ops.ts

# Toutes les permissions (à utiliser avec prudence)
deno run -A everything.ts

En environnement edge, c’est crucial. Votre fonction tourne sur des dizaines de nœuds mondiaux ; une faille a un impact massif.

Différence de cold start

Données mesurées. Même code sur Deno Deploy et AWS Lambda :

RuntimeCold start
Deno Deploy~120 ms
AWS Lambda (Node.js)300-500 ms

Facteur 3. Les raisons sont complexes, mais le cœur du problème : Deno n’a pas le bagage historique de Node.js — CommonJS, résolution require, parcours de node_modules. ESZip + TypeScript natif suppriment une montagne de surcoût au démarrage.

Évolution du système de modules

Node.js utilise CommonJS : require() pour charger les modules, npm, package.json, dossier node_modules. Sur un gros projet, ce dossier peut peser des centaines de Mo.

Deno adopte directement le standard ESM. Pas de npm, pas de package.json, pas de node_modules. Import par URL :

// Import direct depuis une URL
import { serve } from "https://deno.land/[email protected]/http/server.ts"

// Ou via JSR (registre de packages Deno)
import { cors } from "jsr:@hono/hono/cors"

Au premier lancement, Deno télécharge et met en cache les modules localement. Ensuite, chaque démarrage lit le cache — plus de téléchargement réseau.

TypeScript sans configuration

Avec Node.js, TypeScript exige ts-node ou webpack/vite/esbuild, plus un tsconfig.json. Deno supporte TypeScript nativement :

deno run hello.ts

Compilation et vérification de types intégrées au runtime. Expérience de développement bien plus propre.

Question du lock-in fournisseur

C’était aussi ma crainte : avec Supabase Edge Functions, suis-je prisonnier de leur plateforme ?

Pas forcément. Deno est open source, et l’Edge Runtime de Supabase aussi (code sur GitHub). En théorie, vous pouvez faire tourner Edge Runtime sur votre propre serveur. Le coût d’exploitation d’un réseau edge mondial, en revanche, reste à votre charge. Techniquement, vous n’êtes pas « coincé ».

3. Mise en pratique : votre première Edge Function en 10 minutes

La théorie ne suffit pas — il faut essayer.

J’ai suivi la doc officielle, de l’installation au déploiement : moins de 10 minutes. Voici le flux complet :

Étape 1 : installer Supabase CLI

npm install -g supabase

Vérifiez la version :

supabase --version
# Sortie du type : 1.200.0

Étape 2 : initialiser le projet

Si vous avez déjà un projet Supabase, initialisez dans le répertoire :

supabase init

Cela crée un dossier supabase avec config.toml.

Étape 3 : créer une Edge Function

supabase functions new hello-world

Un fichier index.ts apparaît dans supabase/functions/hello-world/ :

import "jsr:@supabase/functions-js/edge-runtime.d.ts"

Deno.serve(async (req) => {
  const data = {
    message: "Hello from Edge Function!"
  }

  return new Response(JSON.stringify(data), {
    headers: { "Content-Type": "application/json" }
  })
})

Adaptez la logique. Par exemple, recevoir un paramètre name et renvoyer un message :

import "jsr:@supabase/functions-js/edge-runtime.d.ts"

Deno.serve(async (req) => {
  // Accepter uniquement POST
  if (req.method !== "POST") {
    return new Response("Method not allowed", { status: 405 })
  }

  try {
    const body = await req.json()
    const name = body.name || "Stranger"

    return new Response(JSON.stringify({
      message: `Hey ${name}, welcome to the edge!`,
      timestamp: new Date().toISOString()
    }), {
      headers: { "Content-Type": "application/json" }
    })
  } catch (err) {
    return new Response(JSON.stringify({ error: "Invalid JSON" }), {
      status: 400,
      headers: { "Content-Type": "application/json" }
    })
  }
})

Étape 4 : test local

Supabase CLI permet d’exécuter les Edge Functions en local :

supabase functions serve --no-verify-jwt

Service local sur le port 54321 par défaut. Test avec curl :

curl -X POST http://localhost:54321/functions/v1/hello-world \
  -H "Content-Type: application/json" \
  -d '{"name":"Easton"}'

# Retour :
# {"message":"Hey Easton, welcome to the edge!","timestamp":"2026-05-03T14:30:00.000Z"}

--no-verify-jwt désactive la validation JWT pour faciliter les tests locaux. En production, activez-la.

Étape 5 : déploiement mondial

Une fois les tests locaux OK, déployez sur le réseau edge Supabase :

# Connexion (si pas déjà fait)
supabase login

# Lier votre projet
supabase link --project-ref <your-project-id>

# Déployer la fonction
supabase functions deploy hello-world

Supabase distribue la fonction sur les nœuds edge mondiaux. Consultez les logs de déploiement et l’URL dans le Dashboard.

Étape 6 : test d’appel

URL de la fonction déployée :

https://<project-id>.supabase.co/functions/v1/hello-world

Appel avec curl :

curl -X POST https://<project-id>.supabase.co/functions/v1/hello-world \
  -H "Authorization: Bearer <anon-key>" \
  -H "Content-Type: application/json" \
  -d '{"name":"World"}'

Notez l’en-tête Authorization. Supabase Edge Functions valide le JWT par défaut — utilisez la clé anon du projet ou un token JWT utilisateur.


Au-delà de la démo, les cas d’usage sont nombreux :

Traitement de webhooks

Par exemple, un webhook Stripe après paiement réussi — une Edge Function reçoit et écrit en base :

// supabase/functions/stripe-webhook/index.ts
import "jsr:@supabase/functions-js/edge-runtime.d.ts"
import { createClient } from "jsr:@supabase/supabase-js@2"

Deno.serve(async (req) => {
  // Vérification de la signature Stripe (simplifiée ici ; en prod, validation HMAC)
  const event = await req.json()

  const supabase = createClient(
    Deno.env.get("SUPABASE_URL")!,
    Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!
  )

  if (event.type === "payment_intent.succeeded") {
    const payment = event.data.object

    await supabase.from("payments").insert({
      id: payment.id,
      amount: payment.amount,
      customer_id: payment.customer,
      created_at: new Date().toISOString()
    })
  }

  return new Response(JSON.stringify({ received: true }), {
    headers: { "Content-Type": "application/json" }
  })
})

Proxy API

Une API tierce nécessite une clé que vous ne voulez pas exposer au frontend ? Proxy via Edge Function :

// supabase/functions/openai-proxy/index.ts
Deno.serve(async (req) => {
  const body = await req.json()

  const response = await fetch("https://api.openai.com/v1/chat/completions", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${Deno.env.get("OPENAI_API_KEY")}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify(body)
  })

  return new Response(response.body, {
    headers: { "Content-Type": "application/json" }
  })
})

Le frontend appelle votre Edge Function ; la clé API reste sur le nœud edge.

4. Choix : Supabase vs Cloudflare Workers

En edge computing, la question revient souvent : Cloudflare Workers ou Supabase Edge Functions ?

Ce ne sont pas des concurrents directs. Le scénario dicte le choix.

Comparaison des performances

Sur le cold start, Cloudflare Workers est plus rapide : ~30 ms officiellement, contre ~120 ms pour Supabase Edge Functions.

Pourquoi ? Le runtime Workers de Cloudflare est propriétaire, optimisé pour le edge. Supabase utilise Deno — rapide, mais avec une couche de compilation TypeScript en plus.

En pratique ? Pour la plupart des cas, 120 ms vs 30 ms passent inaperçus — la latence réseau fluctue davantage. Pour le trading haute fréquence ou les enchères temps réel, Cloudflare Workers convient mieux.

Comparaison de l’intégration

Point fort de Supabase : avec Edge Functions, connexion directe à Postgres du même projet, Auth, Storage. Variables d’environnement injectées automatiquement.

Cloudflare Workers exige de gérer la connexion base vous-même — D1 (SQLite edge) ou base externe, avec un peu de configuration en plus.

Lock-in fournisseur

Cloudflare Workers : runtime propriétaire. Le code ne tourne que chez Cloudflare ; changer de plateforme implique des modifications.

Supabase Edge Functions : Deno open source. Même code portable vers Deno Deploy ou Edge Runtime auto-hébergé. Le réseau edge Supabase, lui, ne se déplace pas — mais le runtime ne vous enferme pas.

Comparaison des écosystèmes

Cloudflare Workers est plus mature (2017) : outils, frameworks, communauté. Hono, Remix supportent Workers.

Supabase Edge Functions (2022) est plus récent, mais hérite des bibliothèques Deno standard.

Recommandations

Votre situationRecommandation
Déjà sur Supabase (Auth, Database, Storage)Supabase Edge Functions
Edge pur, sans base de donnéesCloudflare Workers
Crainte du lock-inSupabase Edge Functions (Deno open source)
Cold start extrême (<50 ms)Cloudflare Workers
Postgres en edgeSupabase Edge Functions

Mon approche actuelle : hybride. Cloudflare Workers pour reverse proxy et cache frontend ; Supabase Edge Functions pour Auth et opérations base de données. Chaque plateforme à sa force.

5. Pièges rencontrés et bonnes pratiques

Les erreurs que j’ai faites — pour que vous les évitiez.

Piège 1 : utiliser des packages Node.js

J’ai voulu axios pour les requêtes HTTP : import axios from "axios". Déploiement → erreur : module introuvable.

Edge Functions = Deno, pas Node.js. Les packages npm ne passent pas. Utilisez des packages compatibles Deno ou l’API fetch native — largement suffisante :

// N'utilisez pas axios
// import axios from "axios"  // erreur au déploiement

// Utilisez fetch
const response = await fetch("https://api.example.com/data", {
  method: "GET",
  headers: { "Authorization": "Bearer xxx" }
})
const data = await response.json()

Alternative Deno proche d’axios : ky.

Piège 2 : fonction trop longue, arrêt forcé

Une fonction batch parcourant des milliers d’enregistrements. OK en local, coupée à 30 s en production.

Edge Functions a une limite CPU. D’après la doc, 400 s max par Isolate (souples + strictes). Au-delà, arrêt forcé.

Solution : pas de gros calcul en Edge Function. Validation, proxy, calcul léger — le reste sur serveur central ou Worker dédié.

Piège 3 : mauvaise connexion base de données

En edge, une connexion Postgres longue par nœud sature le pool rapidement.

Utilisez le Pooler Supabase ou des connexions courtes libérées immédiatement. SUPABASE_DB_URL pointe vers le Pooler :

import { Pool } from "https://deno.land/x/[email protected]/mod.ts"

const pool = new Pool(Deno.env.get("SUPABASE_DB_URL")!, 10)

Deno.serve(async (req) => {
  const client = await pool.connect()
  try {
    const result = await client.queryArray("SELECT * FROM users LIMIT 10")
    return new Response(JSON.stringify(result.rows))
  } finally {
    client.release()  // N'oubliez pas de libérer !
  }
})

Piège 4 : JWT non configuré

En local, --no-verify-jwt pour déboguer. Déploiement sans réactiver la validation → n’importe qui peut appeler la fonction.

Configuration dans config.toml :

[functions.hello-world]
verify_jwt = true

Ou au déploiement :

supabase functions deploy hello-world --verify-jwt

Quelques astuces utiles

  1. Hono à la place de Deno.serve natif

Hono est un framework web ultra-léger pour le edge : routes, middleware, 13 KB seulement. Bien plus adapté qu’Express :

import { Hono } from "jsr:@hono/hono"
import { cors } from "jsr:@hono/hono/cors"

const app = new Hono()

app.use("*", cors())

app.get("/health", (c) => c.json({ status: "ok" }))

app.post("/echo", async (c) => {
  const body = await c.req.json()
  return c.json({ echo: body })
})

Deno.serve(app.fetch)
  1. Gestion des variables d’environnement

Deux runtimes : Main Runtime (contrôlé par Supabase) et User Runtime (votre code). Permissions différentes :

  • SUPABASE_URL, SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY injectées automatiquement
  • Variables personnalisées via Dashboard ou CLI : supabase secrets set MY_VAR=value
  1. Import Map pour réduire la résolution

Beaucoup de modules externes ? Pré-définissez-les dans un Import Map :

// deno.json ou import_map.json
{
  "imports": {
    "hono": "jsr:@hono/hono",
    "supabase-js": "jsr:@supabase/supabase-js@2"
  }
}

Puis importez par nom court :

import { Hono } from "hono"
import { createClient } from "supabase-js"

Conclusion

En une phrase : Supabase Edge Functions pousse votre code au nœud le plus proche de l’utilisateur, sur le runtime Deno sécurisé, cold start 120 ms, distribution mondiale automatique.

Si vous utilisez déjà Supabase — Auth, Database ou Storage — Edge Functions est la suite naturelle. Pas de configuration connexion base, pas de Auth séparé, tout s’emboîte. Crainte du lock-in ? Deno est open source, Edge Runtime auto-hébergeable. Vous gardez une porte de sortie.

Prochaine étape : ouvrez le Dashboard Supabase, suivez le Quickstart. En 10 minutes, votre première Edge Function tourne sur le réseau edge mondial.

Autres articles de la série :

Intéressé par Cloudflare Workers ? Consultez aussi le guide des Workers KV. Chaque plateforme a ses forces — choisissez celle qui vous convient.

Déployer votre première Supabase Edge Function

Créer, tester et déployer une Edge Function sur le réseau edge mondial, de zéro

⏱️ Estimated time: 10 min

  1. 1

    Step 1: Installer Supabase CLI

    Installez Supabase CLI globalement :

    ```bash
    npm install -g supabase
    ```

    Puis vérifiez l'installation avec `supabase --version`.
  2. 2

    Step 2: Initialiser le projet

    Dans le répertoire du projet, lancez l'initialisation :

    ```bash
    supabase init
    ```

    Cela crée le dossier `supabase` et le fichier de configuration `config.toml`.
  3. 3

    Step 3: Créer une Edge Function

    Créez une nouvelle Edge Function via la CLI :

    ```bash
    supabase functions new hello-world
    ```

    La fonction générée se trouve dans `supabase/functions/hello-world/index.ts` et renvoie une réponse JSON par défaut.
  4. 4

    Step 4: Test local

    Démarrez le serveur de développement local :

    ```bash
    supabase functions serve --no-verify-jwt
    ```

    Port par défaut 54321. Testez avec curl ou Postman :

    ```bash
    curl -X POST http://localhost:54321/functions/v1/hello-world \
    -H "Content-Type: application/json" \
    -d '{"name":"Easton"}'
    ```
  5. 5

    Step 5: Déployer sur le réseau edge mondial

    Connectez-vous, liez le projet, puis déployez :

    ```bash
    supabase login
    supabase link --project-ref <your-project-id>
    supabase functions deploy hello-world
    ```

    Une fois déployé, consultez l'URL de la fonction et les logs dans le Dashboard.
  6. 6

    Step 6: Test d'appel

    Appelez la fonction avec son URL et un token d'authentification :

    ```bash
    curl -X POST https://<project-id>.supabase.co/functions/v1/hello-world \
    -H "Authorization: Bearer <anon-key>" \
    -H "Content-Type: application/json" \
    -d '{"name":"World"}'
    ```

    En production, activez la validation JWT : `supabase functions deploy hello-world --verify-jwt`

FAQ

Quelle est la différence entre Supabase Edge Functions et AWS Lambda ?
La différence principale porte sur le cold start et l'emplacement d'exécution. Edge Functions démarre en ~120 ms ; AWS Lambda (Node.js) met 300 à 500 ms. Edge Functions s'exécute sur des nœuds edge mondiaux, plus proches des utilisateurs ; Lambda tourne dans une région fixe. Edge Functions a une limite CPU (400 s) ; Lambda peut durer jusqu'à 15 minutes, mais n'est pas adapté au edge.
Peut-on utiliser des packages npm dans Edge Functions ?
Pas directement. Edge Functions repose sur le runtime Deno, pas sur l'écosystème npm de Node.js. Il faut : 1) utiliser des packages compatibles Deno (import depuis deno.land ou jsr.io) ; 2) remplacer axios par l'API fetch native ; 3) chercher des alternatives dans l'écosystème Deno (par ex. ky à la place d'axios).
Y a-t-il une limite de temps d'exécution pour Edge Functions ?
Oui. Le temps CPU maximal d'un V8 Isolate est de 400 s (limite souple + limite stricte). Au-delà, le processus est arrêté de force. Edge Functions convient à la logique légère (validation JWT, proxy de requêtes, calculs simples), pas aux tâches lourdes. Les traitements batch complexes doivent rester sur un serveur central ou un service Worker dédié.
Comment se connecter à Postgres depuis une Edge Function ?
Utilisez le pool de connexions (Pooler) fourni par Supabase pour éviter l'explosion du pool :

• Variable d'environnement `SUPABASE_DB_URL` (pointe automatiquement vers le Pooler)
• Package `postgres` pour créer un pool
• Libérer la connexion après chaque requête (`client.release()`)

Évitez les connexions longues : avec de nombreux nœuds edge, le pool sature rapidement.
Comment choisir entre Supabase Edge Functions et Cloudflare Workers ?
Selon votre scénario :

• Stack Supabase complète → Edge Functions (intégration profonde, développement rapide)
• Edge pur sans backend → Cloudflare Workers (cold start ~30 ms, plus rapide)
• Crainte du lock-in → Edge Functions (Deno open source, auto-hébergeable)
• Postgres en edge → Edge Functions (intégration native)

En pratique, vous pouvez combiner : Cloudflare Workers pour proxy et cache frontend, Edge Functions pour Auth et logique base de données.
Comment configurer la validation JWT pour protéger une Edge Function ?
Deux méthodes :

• Fichier de config : ajoutez `[functions.hello-world] verify_jwt = true` dans `config.toml`
• Ligne de commande : ajoutez `--verify-jwt` au déploiement

En local, utilisez `--no-verify-jwt` pour les tests ; en production, activez impérativement la validation. Sans JWT, n'importe qui peut appeler votre fonction.

12 min de lecture · Publié le: 3 mai 2026 · Mis à jour le: 27 juil. 2026

Commentaires

Connectez-vous avec GitHub pour laisser un commentaire

Easton BlogEaston Blog