Production-tested standard library for Supabase Edge Functions. Modular, zero-config, Deno-native.
Built from real-world experience running 76 edge functions in production. Each module is independent — install only what you need.
| Package | Description | Install |
|---|---|---|
errors |
Error/success responses, CORS, error codes, exception converter | jsr:@supa-edge-toolkit/errors |
validation |
Schema validation with Zod, request/query/header parsing | jsr:@supa-edge-toolkit/validation |
auth |
JWT verification, auth middleware, secure test mode | jsr:@supa-edge-toolkit/auth |
resilience |
Timeout, circuit breaker, retry with exponential backoff | jsr:@supa-edge-toolkit/resilience |
logger |
Structured JSON logging with request context | jsr:@supa-edge-toolkit/logger |
testing |
MockDBState, PostgREST emulator, mock fetch, assertions | jsr:@supa-edge-toolkit/testing |
langfuse |
Lightweight Langfuse prompt fetcher for Deno | jsr:@supa-edge-toolkit/langfuse |
All packages are v0.1.0, MIT licensed, with full test coverage.
import {
createCorsResponse,
createSuccessResponse,
errorToResponse,
validationError,
} from "jsr:@supa-edge-toolkit/errors";
Deno.serve(async (req) => {
if (req.method === "OPTIONS") return createCorsResponse();
try {
const body = await req.json();
if (!body.email) {
return validationError("Missing required fields", { email: "Required" });
}
return createSuccessResponse({ id: "123", email: body.email });
} catch (error) {
return errorToResponse(error);
}
});import { AuthError, verifyUserToken } from "jsr:@supa-edge-toolkit/auth";
Deno.serve(async (req) => {
try {
const { userId, role } = await verifyUserToken(req);
return new Response(JSON.stringify({ userId, role }));
} catch (error) {
if (error instanceof AuthError) {
return new Response(error.message, { status: error.statusCode });
}
throw error;
}
});import { z } from "npm:zod";
import { parseRequestBody } from "jsr:@supa-edge-toolkit/validation";
Deno.serve(async (req) => {
const schema = z.object({
email: z.string().email(),
name: z.string().min(1),
});
const body = await parseRequestBody(req, schema);
// body is typed as { email: string; name: string }
});import { resilientFetch } from "jsr:@supa-edge-toolkit/resilience";
// Fetch with timeout (5s), retry (3 attempts), and circuit breaker
const response = await resilientFetch("https://api.example.com/data", {
timeout: { timeoutMs: 5000 },
retry: { maxAttempts: 3 },
circuitBreaker: { failureThreshold: 5 },
});import { createLogger } from "jsr:@supa-edge-toolkit/logger";
const logger = createLogger("my-function");
logger.info("Processing request", { userId: "123", action: "create" });
// => {"timestamp":"...","level":"INFO","function":"my-function","message":"Processing request","userId":"123","action":"create"}import {
assertFetchCount,
createTestContext,
} from "jsr:@supa-edge-toolkit/testing";
Deno.test("my edge function", async () => {
const ctx = createTestContext({
dbSeed: { users: [{ id: "u1", name: "Alice" }] },
});
try {
// globalThis.fetch is mocked — Supabase client works against in-memory DB
const res = await fetch("http://localhost:54321/rest/v1/users?id=eq.u1");
const data = await res.json();
assertEquals(data[0].name, "Alice");
assertFetchCount(ctx.fetchLog, "/rest/v1/users", 1);
} finally {
ctx.cleanup();
}
});import {
compilePrompt,
getLangfusePrompt,
} from "jsr:@supa-edge-toolkit/langfuse";
const config = {
host: Deno.env.get("LANGFUSE_URL")!,
publicKey: Deno.env.get("LANGFUSE_PUBLIC_KEY")!,
secretKey: Deno.env.get("LANGFUSE_SECRET_KEY")!,
};
const promptData = await getLangfusePrompt("my-prompt", config);
const messages = compilePrompt(promptData, { name: "Alice" });Supabase Edge Functions lack a standard library. Every project ends up writing the same boilerplate:
- CORS headers and error response formatting
- JWT verification and auth middleware
- Request body validation
- Retry logic and timeouts for external API calls
- Structured logging
- Test utilities for mocking the Supabase client
This toolkit extracts these patterns into tested, independent modules. Each package works standalone — no framework lock-in, no mandatory dependencies between packages.
- Zero coupling — packages are independent, install only what you need
- Deno-native — built for Deno runtime, published on JSR
- Production-tested — extracted from a system running 76 edge functions
- Minimal API — small surface area, easy to learn
- Type-safe — full TypeScript with strict types, no
any
# Run all tests (265 test steps across 7 packages)
deno task test
# Type check all packages
deno task check
# Lint
deno task lint
# Format
deno task fmt
# Check formatting without modifying
deno task fmt:check- Fork the repository
- Create a feature branch
- Run
deno task testto ensure all tests pass - Submit a pull request
Each package has its own README with detailed API documentation.
MIT