Edge Functions
Edge Functions are serverless functions powered by Deno that execute JavaScript/TypeScript code in response to HTTP requests.
Features
Section titled “Features”- Deno runtime for TypeScript/JavaScript
- HTTP triggered via REST API or SDK
- Secure sandbox with configurable permissions
- Direct database access
- Execution logging and versioning
- Configurable timeouts
Use Cases
Section titled “Use Cases”- Process webhooks from third-party services
- Transform and validate data
- Integrate with external APIs
- Run scheduled tasks
- Implement custom business logic
- Extend authentication flows
Installation
Section titled “Installation”npm install @fluxbase/sdkQuick Start
Section titled “Quick Start”import { FluxbaseClient } from "@fluxbase/sdk";
const client = new FluxbaseClient({ url: "http://localhost:8080", apiKey: process.env.FLUXBASE_API_KEY,});
// Create functionawait client.functions.create({ name: "hello-world", description: "My first edge function", code: ` async function handler(req) { const data = JSON.parse(req.body || '{}') return { status: 200, headers: { "Content-Type": "application/json" }, body: JSON.stringify({ message: \`Hello \${data.name || 'World'}!\` }) } } `, enabled: true,});
// Invoke functionconst result = await client.functions.invoke("hello-world", { name: "Alice",});
console.log(result); // { message: "Hello Alice!" }
// List functionsconst functions = await client.functions.list();
// Get function detailsconst details = await client.functions.get("hello-world");
// View execution historyconst executions = await client.functions.getExecutions("hello-world", { limit: 10,});Writing Functions
Section titled “Writing Functions”Function Signature
Section titled “Function Signature”Every function must export an async handler function:
async function handler(req) { // req contains: method, url, headers, body, params
return { status: 200, headers: { "Content-Type": "application/json" }, body: JSON.stringify({ result: "success" }), };}Request Object
Section titled “Request Object”interface Request { method: string; // GET, POST, etc. url: string; headers: Record<string, string>; body: string; // Raw body (use JSON.parse for JSON) params: Record<string, string>; // Query parameters
// Authentication context (if user is authenticated) user_id?: string; // Authenticated user's ID user_email?: string; // User's email from JWT claims user_role?: string; // User's role from JWT claims session_id?: string; // Current session ID}Using the Fluxbase SDK
Section titled “Using the Fluxbase SDK”Edge functions can import and use the Fluxbase SDK for database operations, authentication, and more:
import { createClient } from "@fluxbase/sdk";
async function handler(req) { // Create a service client with elevated permissions const client = createClient( Deno.env.get("FLUXBASE_BASE_URL")!, Deno.env.get("FLUXBASE_SERVICE_ROLE_KEY")! );
// Query the database const { data, error } = await client .from("users") .select("*") .eq("id", req.user_id) .execute();
if (error) { return { status: 500, body: JSON.stringify({ error: error.message }), }; }
return { status: 200, headers: { "Content-Type": "application/json" }, body: JSON.stringify(data), };}Note: The SDK is available via import maps configured in /functions/deno.json. For local development with live SDK changes, use /functions/deno.dev.json which points to your local SDK mount.
Response Object
Section titled “Response Object”interface Response { status: number; headers?: Record<string, string>; body?: string;}Function Examples
Section titled “Function Examples”Simple Data Processing
Section titled “Simple Data Processing”async function handler(req) { const { email } = JSON.parse(req.body || "{}");
// Validate email if (!email || !email.includes("@")) { return { status: 400, body: JSON.stringify({ error: "Invalid email" }), }; }
return { status: 200, body: JSON.stringify({ valid: true }), };}Database Query
Section titled “Database Query”async function handler(req) { // Database client is available via env const dbUrl = Deno.env.get("DATABASE_URL");
// Use pg client or any PostgreSQL library const result = await fetch(`${dbUrl}/users`);
return { status: 200, body: JSON.stringify(result), };}External API Call
Section titled “External API Call”async function handler(req) { const { query } = JSON.parse(req.body || "{}");
// Call external API const response = await fetch(`https://api.example.com/search?q=${query}`); const data = await response.json();
return { status: 200, headers: { "Content-Type": "application/json" }, body: JSON.stringify(data), };}Error Handling
Section titled “Error Handling”async function handler(req) { try { const data = JSON.parse(req.body || "{}");
// Process data const result = await processData(data);
return { status: 200, body: JSON.stringify({ result }), }; } catch (error) { return { status: 500, body: JSON.stringify({ error: "Processing failed", message: error.message, }), }; }}Authentication
Section titled “Authentication”Functions automatically receive the authenticated user context:
async function handler(req) { // User info from JWT token (if authenticated) const userId = req.user_id; // UUID string const userEmail = req.user_email; // Email string const userRole = req.user_role; // Role string (e.g., "authenticated", "admin")
if (!userId) { return { status: 401, body: JSON.stringify({ error: "Unauthorized" }), }; }
// Use user context for authorization return { status: 200, body: JSON.stringify({ userId, userEmail, userRole }), };}How it works:
- Fluxbase validates the JWT token in the
Authorizationheader - User context (id, email, role) is extracted from the token
- User info is added to the request object (
user_id,user_email,user_role) - Function handler receives the request with user context
- Handler can use user info for authorization and data filtering
Handler Execution Flow
Section titled “Handler Execution Flow”graph TB A[HTTP Request] --> B[Initialize Deno Runtime] B --> C[Load Function Code] C --> D[Apply Permissions<br/>net, env, read, write] D --> E[Execute handler req] E --> F{Success?} F -->|Yes| G[Return Response Object] F -->|Error| H[Return Error Response] G --> I[HTTP Response to Client] H --> I
style B fill:#000,color:#fff style D fill:#ff6b6b,color:#fffExecution steps:
- Initialize Deno runtime with configured permissions
- Load the function code into the sandbox
- Apply security permissions (net, env, read, write)
- Execute the handler with the request object
- Return the response to the client
npm Package Support
Section titled “npm Package Support”Fluxbase supports importing npm packages in your edge functions using Deno’s npm: specifier or URL imports. Functions are automatically bundled when they contain imports.
Using npm Packages
Section titled “Using npm Packages”// Import from npmimport { z } from "npm:zod@3.22.4";import dayjs from "npm:dayjs@1.11.10";
// Import from URLimport { marked } from "https://esm.sh/marked@9.1.0";
async function handler(req) { const data = JSON.parse(req.body || "{}");
// Use zod for validation const schema = z.object({ name: z.string(), email: z.email(), });
const validated = schema.parse(data);
return { status: 200, body: JSON.stringify({ success: true, data: validated }), };}How Bundling Works
Section titled “How Bundling Works”- Detection - Fluxbase detects import statements in your code
- Validation - Imports are checked against security blocklist
- Bundling - Deno bundles your code with dependencies into a single file
- Storage - Bundled code is stored in the database for fast execution
- Execution - Runtime uses the pre-bundled code (no bundling overhead)
Performance: Bundling happens once at creation/update time, not on every invocation.
Security Restrictions
Section titled “Security Restrictions”For security, the following packages are blocked:
child_process/node:child_process- Process executionvm/node:vm- Code evaluationfs/node:fs- Filesystem accessprocess/node:process- Process manipulation
Use Deno’s built-in APIs or web-standard alternatives instead.
Bundling Errors
Section titled “Bundling Errors”If bundling fails, Fluxbase stores the error but keeps the unbundled code:
// Check bundling statusconst func = await client.functions.get("my-function");console.log("Is bundled:", func.is_bundled);console.log("Bundle error:", func.bundle_error);Common bundling errors:
- Package not found - Check package name and version
- Network timeout - npm registry may be slow/unavailable
- Bundle too large - Limit is 5MB after bundling
- Blocked package - Using a restricted security package
Shared Modules
Section titled “Shared Modules”Shared modules allow you to reuse code across multiple edge functions, similar to Supabase’s _shared directory pattern. Modules are stored with a _shared/ prefix and can be imported by any function.
Creating Shared Modules
Section titled “Creating Shared Modules”Via SDK:
await client.functions.createSharedModule({ module_path: "_shared/cors.ts", description: "CORS headers helper", content: ` export function corsHeaders(origin?: string) { return { 'Access-Control-Allow-Origin': origin || '*', 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type', 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, PUT, DELETE' } } `,});Via File System:
Create a _shared/ directory in your functions folder:
functions/├── _shared/│ ├── cors.ts ← Shared CORS utilities│ ├── database.ts ← Database helpers│ └── validation.ts ← Input validation└── my-function.tsexport function corsHeaders(origin?: string) { return { "Access-Control-Allow-Origin": origin || "*", "Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type", "Access-Control-Allow-Methods": "POST, GET, OPTIONS, PUT, DELETE", };}
export function handleCors(req: Request) { if (req.method === "OPTIONS") { return { status: 200, headers: corsHeaders(), }; } return null;}Using Shared Modules
Section titled “Using Shared Modules”Import shared modules using the _shared/ prefix:
import { corsHeaders, handleCors } from "_shared/cors.ts";import { validateEmail } from "_shared/validation.ts";
async function handler(req) { // Handle preflight requests const corsResponse = handleCors(req); if (corsResponse) return corsResponse;
const data = JSON.parse(req.body || "{}");
// Use shared validation if (!validateEmail(data.email)) { return { status: 400, headers: corsHeaders(), body: JSON.stringify({ error: "Invalid email" }), }; }
return { status: 200, headers: corsHeaders(), body: JSON.stringify({ success: true }), };}Nested Shared Modules
Section titled “Nested Shared Modules”Organize shared code in subdirectories:
functions/├── _shared/│ ├── utils/│ │ ├── date.ts│ │ └── string.ts│ ├── database/│ │ ├── connection.ts│ │ └── queries.ts│ └── cors.ts└── my-function/ └── index.tsimport { corsHeaders } from "_shared/cors.ts";import { formatDate } from "_shared/utils/date.ts";import { query } from "_shared/database/queries.ts";
async function handler(req) { const users = await query("SELECT * FROM users"); const timestamp = formatDate(new Date());
return { status: 200, headers: corsHeaders(), body: JSON.stringify({ users, timestamp }), };}Common Shared Module Patterns
Section titled “Common Shared Module Patterns”CORS Helper:
export function corsHeaders(origin?: string) { return { "Access-Control-Allow-Origin": origin || "*", "Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type", "Access-Control-Allow-Methods": "POST, GET, OPTIONS, PUT, DELETE", };}
export function handleCors(req: Request) { if (req.method === "OPTIONS") { return { status: 200, headers: corsHeaders(), }; } return null;}Input Validation:
export function validateEmail(email: string): boolean { const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return regex.test(email);}
export function validateRequired(data: any, fields: string[]): string[] { const missing = []; for (const field of fields) { if (!data[field]) { missing.push(field); } } return missing;}
export function sanitizeString(str: string): string { return str.trim().replace(/[<>]/g, "");}Error Responses:
export function errorResponse(message: string, status = 400) { return { status, headers: { "Content-Type": "application/json" }, body: JSON.stringify({ error: message }), };}
export function successResponse(data: any, status = 200) { return { status, headers: { "Content-Type": "application/json" }, body: JSON.stringify(data), };}Managing Shared Modules
Section titled “Managing Shared Modules”List all shared modules:
const modules = await client.functions.listSharedModules();console.log(modules);// [// { module_path: '_shared/cors.ts', version: 1, ... },// { module_path: '_shared/validation.ts', version: 2, ... }// ]Get a specific module:
const module = await client.functions.getSharedModule("_shared/cors.ts");console.log(module.content);Update a shared module:
await client.functions.updateSharedModule("_shared/cors.ts", { content: ` export function corsHeaders() { // Updated implementation } `, description: "Updated CORS helper",});Delete a shared module:
await client.functions.deleteSharedModule("_shared/cors.ts");How Bundling Works with Shared Modules
Section titled “How Bundling Works with Shared Modules”- Detection - Fluxbase detects imports from
_shared/in function code - Loading - All shared modules are loaded from database or filesystem
- Bundling - Deno bundles the function with all dependencies and shared modules
- Storage - Bundled code is stored for fast execution
- Execution - Runtime uses the pre-bundled code
Important: When you update a shared module, you must re-save or reload any functions that use it to trigger re-bundling.
File-Based vs Database Shared Modules
Section titled “File-Based vs Database Shared Modules”File-Based (functions/_shared/*.ts):
- ✅ Version controlled with your code
- ✅ Easy local development
- ✅ Syncs on reload/boot
- ❌ Requires filesystem access
Database (created via SDK/API):
- ✅ Dynamically updatable
- ✅ No filesystem required
- ✅ Versioning built-in
- ❌ Not version controlled with code
Best Practice: Use file-based shared modules for production deployments and database modules for dynamic/temporary utilities.
Deployment Methods
Section titled “Deployment Methods”1. SDK Deployment
Section titled “1. SDK Deployment”await client.functions.create({ name: "my-function", code: `async function handler(req) { ... }`, enabled: true,});
// Update existing functionawait client.functions.update("my-function", { code: `async function handler(req) { ... }`,});2. File-Based Deployment
Section titled “2. File-Based Deployment”Mount a directory with function files:
services: fluxbase: image: ghcr.io/fluxbase-eu/fluxbase:latest volumes: - ./functions:/app/functions environment: FLUXBASE_FUNCTIONS_ENABLED: "true" FLUXBASE_FUNCTIONS_FUNCTIONS_DIR: /app/functions FLUXBASE_FUNCTIONS_AUTO_LOAD_ON_BOOT: "true" # Load on startup (default: true)Function File Patterns:
Fluxbase supports two ways to organize your functions:
1. Flat File Pattern (simple functions):
async function handler(req) { return { status: 200, body: JSON.stringify({ message: "Hello!" }), };}2. Directory Pattern (complex functions with multiple files):
functions/└── complex-webhook/ ├── index.ts ← Entry point (handler function) ├── types.ts ← Type definitions ├── helpers.ts ← Shared utilities └── config.ts ← Configurationimport { processData } from "./helpers.ts";import { WebhookConfig } from "./types.ts";
async function handler(req) { const data = processData(req.body); return { status: 200, body: JSON.stringify(data), };}Priority Rules:
- If both
hello.tsandhello/index.tsexist, the flat file takes precedence - Directory pattern requires
index.tsas the entry point - Only
.tsfiles are supported
Auto-Load on Boot:
By default (AUTO_LOAD_ON_BOOT=true), functions are automatically loaded from the filesystem when Fluxbase starts. Auto-load:
- ✅ Creates new functions from filesystem
- ✅ Updates existing functions from filesystem
- ❌ Never deletes functions (preserves UI-created functions)
Manual Reload: Trigger full sync after adding/updating/deleting function files:
curl -X POST http://localhost:8080/api/v1/admin/functions/reload \ -H "Authorization: Bearer ADMIN_TOKEN"Manual reload performs full synchronization:
- ✅ Creates new functions from filesystem
- ✅ Updates existing functions from filesystem
- ✅ Deletes functions missing from filesystem
File-Based Workflow:
Mixed UI + File-based Functions:
- Functions created via UI/SDK remain in database even after container restarts
- File-based functions sync on boot (create/update only)
- Use manual reload to remove functions deleted from filesystem
Pure File-based Functions:
- Mount functions directory to container
- Add/update/delete
.tsor.jsfiles - Call reload endpoint to sync deletions
- Functions are bundled and stored in database
Important: If you use both UI-created and file-based functions, do not call the reload endpoint unless you understand it will delete UI-created functions that don’t exist on the filesystem.
3. Admin Dashboard
Section titled “3. Admin Dashboard”- Navigate to Functions section
- Click “New Function”
- Write code in browser editor
- Save (stores in database and syncs to filesystem)
Namespaces
Section titled “Namespaces”Namespaces provide multi-tenant function isolation. Use namespaces to organize functions by team, environment, or service:
// Create function in specific namespaceawait client.admin.functions.create({ name: "process-payment", namespace: "payment-service", code: `async function handler(req) { ... }`,});
// Invoke with namespaceconst result = await client.functions.invoke( "payment-service/process-payment", { body: JSON.stringify({ amount: 100 }), });
// List functions by namespaceconst functions = await client.admin.functions.list("payment-service");Default namespace: Functions without an explicit namespace use "default".
Namespace use cases:
- Multi-tenancy: Isolate functions per customer
- Environments: Separate dev, staging, production functions
- Services: Organize by microservice boundaries
Sync API
Section titled “Sync API”For bulk function deployment, use the sync API:
// Sync functions from filesystem or APIconst result = await client.admin.functions.sync({ namespace: "default", functions: [ { name: "fn1", code: "..." }, { name: "fn2", code: "..." }, ], delete_missing: false, // Don't delete existing functions dry_run: false, // Apply changes});
console.log(result.summary);// { created: 2, updated: 0, deleted: 0, unchanged: 5 }Options:
delete_missing: true- Remove functions not in sync listdry_run: true- Preview changes without applying
Best Practices
Section titled “Best Practices”Performance:
- Keep functions lightweight
- Avoid long-running operations (use timeouts)
- Cache external API responses when possible
- Minimize database queries
Security:
- Validate all inputs
- Never expose secrets in function code
- Use environment variables for sensitive data
- Implement proper authentication checks
- Sanitize user-provided data
Error Handling:
- Always wrap code in try-catch blocks
- Return appropriate HTTP status codes
- Log errors for debugging
- Provide meaningful error messages
Code Organization:
- Keep functions focused on single tasks
- Extract shared logic into utility modules
- Use consistent naming conventions
- Document function purpose and parameters
Configuration
Section titled “Configuration”Set function-level configuration:
await client.functions.create({ name: "my-function", code: "...", timeout: 30, // seconds memory: 256, // MB env: { API_KEY: "secret-key", API_URL: "https://api.example.com", },});Access environment variables in function:
async function handler(req) { const apiKey = Deno.env.get("API_KEY"); // Use apiKey...}Function Annotations
Section titled “Function Annotations”Fluxbase supports special @fluxbase: directives in function code comments to configure function behavior. These annotations provide a convenient way to set function-level configuration without API calls.
Authentication Annotations
Section titled “Authentication Annotations”@fluxbase:allow-unauthenticated - Allow function invocation without authentication:
/** * Public webhook handler * * @fluxbase:allow-unauthenticated */async function handler(req) { // This function can be called without auth return { status: 200, body: JSON.stringify({ message: "OK" }), };}@fluxbase:public - Control whether function is publicly listed (default: true):
/** * Internal helper function * * @fluxbase:public false */async function handler(req) { // This function won't appear in public function listings return { status: 200, body: "OK" };}CORS Annotations
Section titled “CORS Annotations”Configure Cross-Origin Resource Sharing (CORS) per function. If not specified, functions use the global FLUXBASE_CORS_* environment variables.
@fluxbase:cors-origins - Allowed origins (comma-separated):
/** * API function with restricted origins * * @fluxbase:cors-origins https://app.example.com,https://admin.example.com */async function handler(req) { return { status: 200, headers: { "Content-Type": "application/json" }, body: JSON.stringify({ data: "result" }), };}@fluxbase:cors-methods - Allowed HTTP methods (comma-separated):
/** * Read-only API endpoint * * @fluxbase:cors-methods GET,OPTIONS */async function handler(req) { // Only GET and OPTIONS methods allowed return { status: 200, body: JSON.stringify({ data }) };}@fluxbase:cors-headers - Allowed request headers (comma-separated):
/** * Custom header requirements * * @fluxbase:cors-headers Content-Type,Authorization,X-API-Key */async function handler(req) { const apiKey = req.headers["x-api-key"]; // Process request...}@fluxbase:cors-credentials - Allow credentials (cookies, auth headers):
/** * Function that requires cookies * * @fluxbase:cors-origins https://app.example.com * @fluxbase:cors-credentials true */async function handler(req) { // Can receive cookies from app.example.com return { status: 200, body: "OK" };}@fluxbase:cors-max-age - Preflight cache duration in seconds:
/** * Long-lived preflight cache * * @fluxbase:cors-max-age 3600 */async function handler(req) { // Preflight results cached for 1 hour return { status: 200, body: "OK" };}Complete CORS Example
Section titled “Complete CORS Example”/** * Webhook handler with custom CORS * * @fluxbase:allow-unauthenticated * @fluxbase:cors-origins https://api.stripe.com,https://api.github.com * @fluxbase:cors-methods POST,OPTIONS * @fluxbase:cors-headers Content-Type,X-Stripe-Signature,X-Hub-Signature * @fluxbase:cors-max-age 300 */async function handler(req) { if (req.method === "POST") { // Process webhook const payload = JSON.parse(req.body); // ... handle webhook ...
return { status: 200, body: JSON.stringify({ received: true }), }; }
return { status: 405, body: "Method not allowed" };}Annotation Priority
Section titled “Annotation Priority”Configuration sources are applied in this order (highest to lowest priority):
- API Request - Explicit values in
functions.create()orfunctions.update() - Code Annotations -
@fluxbase:directives in function comments - Global Defaults -
FLUXBASE_CORS_*environment variables
Example:
// Function with partial CORS config/** * @fluxbase:cors-origins https://app.example.com */async function handler(req) { ... }
// Result:// - origins: https://app.example.com (from annotation)// - methods: FLUXBASE_CORS_ALLOWED_METHODS (from env)// - headers: FLUXBASE_CORS_ALLOWED_HEADERS (from env)// - credentials: FLUXBASE_CORS_ALLOW_CREDENTIALS (from env)// - max_age: FLUXBASE_CORS_MAX_AGE (from env)Automatic Preflight Handling
Section titled “Automatic Preflight Handling”When CORS is configured (via annotations, API, or global settings), Fluxbase automatically handles OPTIONS preflight requests. Your function code doesn’t need to handle OPTIONS methods - the server manages this automatically.
Debugging
Section titled “Debugging”View Logs
Section titled “View Logs”const logs = await client.functions.getLogs("my-function", { limit: 50,});
logs.forEach((log) => { console.log(`${log.timestamp}: ${log.message}`);});Test Locally
Section titled “Test Locally”Use Deno CLI to test functions:
deno run --allow-net --allow-env my-function.tsExecution History
Section titled “Execution History”const executions = await client.functions.getExecutions("my-function");
executions.forEach((exec) => { console.log("Status:", exec.status); console.log("Duration:", exec.duration_ms, "ms"); console.log("Error:", exec.error);});Limitations
Section titled “Limitations”- Maximum execution time: 60 seconds (configurable)
- Maximum response size: 6MB
- No filesystem persistence (use database or external storage)
- Limited Deno permissions by default (configurable)
Security Considerations
Section titled “Security Considerations”Permissions: Functions run with restricted permissions. Enable only what’s needed:
await client.functions.create({ name: "my-function", code: "...", permissions: { net: true, // Allow network access env: true, // Allow environment variables read: false, // Deny filesystem read write: false, // Deny filesystem write },});Input Validation: Always validate and sanitize inputs:
async function handler(req) { const data = JSON.parse(req.body || "{}");
// Validate required fields if (!data.email || typeof data.email !== "string") { return { status: 400, body: JSON.stringify({ error: "Invalid email" }) }; }
// Sanitize inputs const email = data.email.trim().toLowerCase();
// Continue processing...}Environment Variable Security:
Only FLUXBASE_* prefixed variables are accessible in functions. Sensitive secrets are automatically blocked for security:
// ✅ Allowedconst apiUrl = Deno.env.get("FLUXBASE_API_URL");const customConfig = Deno.env.get("FLUXBASE_MY_CONFIG");
// ❌ Blocked (returns undefined)const jwtSecret = Deno.env.get("FLUXBASE_AUTH_JWT_SECRET");const dbPassword = Deno.env.get("FLUXBASE_DATABASE_PASSWORD");const s3Secret = Deno.env.get("FLUXBASE_STORAGE_S3_SECRET_KEY");Blocked variables:
FLUXBASE_AUTH_JWT_SECRETFLUXBASE_DATABASE_PASSWORD/FLUXBASE_DATABASE_ADMIN_PASSWORDFLUXBASE_STORAGE_S3_SECRET_KEY/FLUXBASE_STORAGE_S3_ACCESS_KEYFLUXBASE_EMAIL_SMTP_PASSWORDFLUXBASE_SECURITY_SETUP_TOKEN
REST API
Section titled “REST API”For direct HTTP access without the SDK, see the SDK Documentation.
Troubleshooting
Section titled “Troubleshooting”Function not executing:
- Verify function is enabled:
enabled: true - Check function syntax (use Deno to validate TypeScript)
- Review execution logs for errors
Timeout errors:
- Increase timeout configuration
- Optimize slow operations
- Consider breaking into smaller functions
Permission errors:
- Enable required permissions in function config
- Check environment variable availability
Memory errors:
- Increase memory allocation
- Optimize data processing (stream large datasets)
- Reduce in-memory caching
Migration from Supabase
Section titled “Migration from Supabase”Supabase Edge Functions use serve(), Fluxbase uses handler():
// Supabaseimport { serve } from "https://deno.land/std@0.168.0/http/server.ts";
serve(async (req) => { const data = await req.json(); return new Response(JSON.stringify(result), { headers: { "Content-Type": "application/json" }, });});
// Fluxbase equivalentasync function handler(req) { const data = JSON.parse(req.body || "{}"); return { status: 200, headers: { "Content-Type": "application/json" }, body: JSON.stringify(result), };}Related Documentation
Section titled “Related Documentation”- Authentication - Secure function access
- Webhooks - Trigger functions from events
- SDK Documentation - Complete SDK documentation