Vercel Edge

Half your dependencies
won't even run here.

Edge Runtime doesn't support Node.js APIs. That means no crypto, no fs, and half the packages on npm just crash at runtime. TinyFn works everywhere—it's just fetch().

Edge Runtime Compatibility

bcrypt Uses native bindings
jsonwebtoken Requires crypto module
validator 140 KB bundle size
moment 290 KB bundle size
TinyFn Just fetch() — 0 KB

Complete Example

A production-ready Next.js middleware with zero dependencies.

Edge Runtime is not Node.js

Vercel's Edge Runtime uses V8 isolates, not Node.js. That means no Buffer, no crypto, no fs, and no native modules. Packages like bcrypt, jsonwebtoken, and uuid (v4) won't work. TinyFn sidesteps all of this—it's just HTTP.

middleware.ts
Edge Runtime
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

const TINYFN = 'https://api.tinyfn.io/v1';

export const config = { matcher: '/api/:path*' };

export async function middleware(request: NextRequest) {
  const apiKey = process.env.TINYFN_API_KEY!;
  const clientIP = request.ip || request.headers.get('x-forwarded-for') || '';

  // Check if IP is in blocked range
  const { in_range } = await fetch(
    `${TINYFN}/ip/in-cidr?ip=${clientIP}&cidr=10.0.0.0/8`,
    { headers: { 'X-API-Key': apiKey } }
  ).then(r => r.json());

  if (in_range) {
    return new NextResponse('Forbidden', { status: 403 });
  }

  // Generate request ID for tracing
  const { uuid } = await fetch(`${TINYFN}/generate/uuid`, {
    headers: { 'X-API-Key': apiKey }
  }).then(r => r.json());

  const response = NextResponse.next();
  response.headers.set('x-request-id', uuid);
  return response;
}

Quick Start

Add TinyFn to your Next.js project in under a minute.

1

Get API Key

# Sign up at tinyfn.io
# Copy your API key
2

Add to Environment

# .env.local
TINYFN_API_KEY=your_key
3

Use in Middleware

await fetch(`${TINYFN}/...`,
  { headers: { 'X-API-Key': key } }
)

Patterns That Just Work

Things you'd normally need a package for—now they're one fetch() away. No import errors, no bundle bloat.

A/B Test Assignment

// Consistent user bucketing
const { hash } = await fetch(
  `${TINYFN}/hash/sha256?text=${userId}-exp`,
  { headers: { 'X-API-Key': key } }
).then(r => r.json());

const bucket = parseInt(hash.slice(0, 8), 16) % 100;
const variant = bucket < 50 ? 'A' : 'B';

JWT Auth Check

// Decode JWT without a library
const token = request.headers.get('authorization')
  ?.replace('Bearer ', '');

const { payload } = await fetch(
  `${TINYFN}/jwt/decode?token=${token}`,
  { headers: { 'X-API-Key': key } }
).then(r => r.json());

if (payload.role !== 'admin') { ... }

Webhook Verification

// Verify Stripe/GitHub webhooks
const { hash } = await fetch(
  `${TINYFN}/crypto/hmac-sha256?` +
  `text=${encodeURIComponent(body)}&` +
  `key=${WEBHOOK_SECRET}`,
  { headers: { 'X-API-Key': key } }
).then(r => r.json());

const valid = hash === signature;

Form Validation

// Validate email at the edge
const { is_valid, disposable } = await fetch(
  `${TINYFN}/validate/email?email=${email}`,
  { headers: { 'X-API-Key': key } }
).then(r => r.json());

if (!is_valid || disposable) {
  return Response.json({ error: 'Invalid' });
}

Popular Endpoints

Most-used utilities for Edge Functions.

Why This Works

The Edge Runtime is powerful but picky. TinyFn fits perfectly.

It Just Works

No more "Dynamic Code Evaluation" errors. No "Module not found". Just fetch().

No Bundle Anxiety

Stop worrying about the 4 MB limit. TinyFn adds literally zero bytes.

Ship Faster

No time spent finding "Edge-compatible" alternatives. It's all here.

Sleep Better

One API to keep updated vs a dozen packages with CVE alerts.

Stop fighting the Edge Runtime

Free tier gets you 10,000 requests/month. Enough to try it in your next middleware.