| name | supabase-edge-functions |
| description | Use when creating, naming, or organizing Supabase Edge Functions |
Supabase: Edge Functions
Guidelines for creating Supabase Edge Functions, including naming conventions, import configuration, and common patterns.
CRITICAL: deno.json Import Maps
Each Edge Function folder MUST have its own deno.json file with import mappings. Deno does not support bare module specifiers like Node.js.
Required deno.json Structure
{
"compilerOptions": {
"lib": ["deno.window", "deno.ns"],
"strict": true
},
"imports": {
"supabase": "https://esm.sh/@supabase/supabase-js@2",
"http-server": "https://deno.land/std@0.168.0/http/server.ts"
}
}
Common Import Mappings
| Bare Specifier | Deno Import URL |
|---|
"supabase" | "https://esm.sh/@supabase/supabase-js@2" |
"http-server" | "https://deno.land/std@0.168.0/http/server.ts" |
"@codemirror/state" | "npm:@codemirror/state@6.5.2" |
"@codemirror/collab" | "npm:@codemirror/collab@6.1.1" |
"diff" | "npm:diff@5.2.0" |
Example: Function with CodeMirror
{
"compilerOptions": {
"lib": ["deno.window", "deno.ns"],
"strict": true
},
"imports": {
"supabase": "https://esm.sh/@supabase/supabase-js@2",
"http-server": "https://deno.land/std@0.168.0/http/server.ts",
"@codemirror/state": "npm:@codemirror/state@6.5.2",
"@codemirror/collab": "npm:@codemirror/collab@6.1.1",
"diff": "npm:diff@5.2.0"
}
}
Common Mistake
import { serve } from "http-server";
import { createClient } from "supabase";
Fix: Create deno.json in the function folder with proper import mappings.
Naming Conventions
Core Pattern
Structure: [namespace]_[sub-namespace]_[action-words]
| Separator | Used For | Example |
|---|
_ | Namespace boundaries | page-scene_script_ |
- | Words within a segment | create-script |
All names are lowercase. No uppercase letters.
supabase/functions/
├── page-scene_script_create-script/
│ ├── index.ts
│ └── deno.json
├── page-scene_script_delete-script/
│ ├── index.ts
│ └── deno.json
├── file-browser_upload-start/
│ ├── index.ts
│ └── deno.json
└── _shared_validate-token/
├── index.ts
└── deno.json
Why flat structure? Supabase CLI only discovers functions at the root level of /supabase/functions/. Nested subdirectories are not supported.
PascalCase to Kebab-Case Conversion
Convert frontend entity names by:
- Split on underscores and capital letters
- Join with hyphens (for words) or underscores (for namespaces)
- Lowercase everything
| Frontend Entity | Edge Function Prefix |
|---|
PageScene_Script | page-scene_script_ |
PageOrganization_Projects | page-organization_projects_ |
FileBrowser | file-browser_ |
PageProject_SetCard | page-project_set-card_ |
Namespaces (First Segment)
Derived from Page or feature names:
page-scene_ # From Page_Scene
page-organization_ # From Page_Organization
file-browser_ # From FileBrowser feature
storage_ # Domain-level namespace
auth_ # Domain-level namespace
Sub-namespaces (Second Segment)
Derived from subcomponent or entity names:
page-scene_script_ # From PageScene_Script
page-scene_timeline_ # From PageScene_Timeline
file-browser_upload_ # Grouped upload functions (optional)
Action Names (Final Segment)
Verb-noun pattern with hyphens:
create-script
delete-file
generate-upload-url
send-invitation
validate-token
Creating a New Edge Function
Step 1: Create Function Folder
npx supabase functions new page-scene_script_create-script
mkdir supabase/functions/page-scene_script_create-script
Step 2: Create deno.json (REQUIRED)
touch supabase/functions/page-scene_script_create-script/deno.json
Add appropriate imports based on dependencies needed.
Step 3: Create index.ts
import { serve } from "http-server";
import { createClient } from "supabase";
const supabaseUrl = Deno.env.get("SUPABASE_URL")!;
const supabaseServiceKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!;
const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type",
"Access-Control-Allow-Methods": "POST, OPTIONS",
};
serve(async (req: Request) => {
if (req.method === "OPTIONS") {
return new Response(null, { status: 204, headers: corsHeaders });
}
return new Response(JSON.stringify({ success: true }), {
headers: { ...corsHeaders, "Content-Type": "application/json" },
});
});
Shared/Utility Functions
Use _shared_ prefix for cross-cutting functions:
_shared_validate-token
_shared_check-permissions
_shared_send-notification
When to use _shared_:
- Authentication/authorization utilities
- Functions called by multiple namespaces
- Infrastructure utilities (logging, error handling)
URL Mapping
Edge function URLs use the folder name directly:
| Function Name | URL |
|---|
page-scene_script_create-script | /functions/v1/page-scene_script_create-script |
_shared_validate-token | /functions/v1/_shared_validate-token |
Common Mistakes
# ❌ Wrong - missing deno.json (causes import errors)
supabase/functions/my-function/
└── index.ts
# ✅ Correct - includes deno.json
supabase/functions/my-function/
├── index.ts
└── deno.json
# ❌ Wrong - nested folders (not supported by Supabase)
page-scene/script/create-script
# ❌ Wrong - uppercase letters
PageScene_Script_CreateScript
# ❌ Wrong - using hyphens for namespace separation
page-scene-script-create-script
# ❌ Wrong - no namespace prefix
create-script
# ✅ Correct
page-scene_script_create-script
Migration from Legacy Names
Existing functions should be migrated to namespaced structure:
| Current (Legacy) | Target (Namespaced) |
|---|
delete-file | file-browser_delete-file |
generate-upload-url | storage_generate-upload-url |
invite-member | page-organization_invite-member |
Related Skills
- frontend-naming-conventions - Source patterns this skill mirrors
- supabase-supabase-cli - CLI commands for deploying functions