Skip to main content

Concepts

EdgeMaster is built on a foundation of proven architectural patterns adapted for edge computing. This section introduces the key concepts that make EdgeMaster powerful yet simple to use.


Why EdgeMaster?

The Edge Computing Challenge

Edge computing brings applications closer to users for better performance, but it comes with unique constraints:

  • Limited CPU Time: Workers have strict execution limits (10-50ms)
  • No File System: No access to traditional Node.js APIs
  • Minimal Dependencies: Every KB counts in bundle size
  • Global Distribution: Code runs in 300+ data centers
  • Stateless Execution: Each request is isolated

Traditional frameworks like Express.js weren't built for these constraints. EdgeMaster was designed from the ground up for edge environments.

The Problem EdgeMaster Solves

As edge applications grow, they quickly become unmaintainable:

// ❌ Typical edge app growth pattern
if (path === '/users' && method === 'GET') {
// Check auth
if (!hasAuth(req)) return unauthorized();
// Check rate limit
if (isRateLimited(req)) return tooManyRequests();
// Handle request
const users = await getUsers();
return json(users);
}
else if (path === '/users' && method === 'POST') {
// Duplicate auth check
if (!hasAuth(req)) return unauthorized();
// Duplicate rate limit check
if (isRateLimited(req)) return tooManyRequests();
// Handle request
const user = await createUser(req);
return json(user);
}
// ... 50 more routes with duplicated logic

EdgeMaster brings structure and reusability:

// ✅ EdgeMaster approach
const app = new EdgeController();

// Apply to all routes
app.addInterceptor(jwtInterceptor({ secret: env.JWT_SECRET }));
app.addInterceptor(rateLimitInterceptor({ limit: 100, window: 60 }));

// Define routes cleanly
app.GET('/users', listUsersHandler);
app.POST('/users', createUserHandler);

Core Concepts

1. EdgeController - The Orchestrator

The EdgeController is the central hub that manages everything:

const app = new EdgeController();

// It orchestrates:
// - Route matching
// - Request/response interceptors
// - Error handling
// - Context management

Key insight: One controller per worker, configured once, handles all requests.

2. Routes - Defining Endpoints

Routes map incoming requests to handlers:

// HTTP method helpers
app.GET('/users', handler);
app.POST('/users', handler);
app.PUT('/users/:id', handler);
app.DELETE('/users/:id', handler);

// Route grouping
app.group('/api/v1', (api) => {
api.GET('/users', handler); // /api/v1/users
api.POST('/posts', handler); // /api/v1/posts
});

// Priority-based matching
app.addRoute(specificMatcher, handler, 100); // Matched first
app.addRoute(generalMatcher, handler, 0); // Matched last

Key insight: Routes are matched by priority, allowing fine-grained control.

3. Interceptors - Cross-Cutting Concerns

Interceptors are EdgeMaster's middleware system, split into two types:

Request Interceptors (Before)

Execute before your route handler:

app.addInterceptor(jwtInterceptor());          // Authentication
app.addInterceptor(rateLimitInterceptor()); // Rate limiting
app.addInterceptor(cacheCheckInterceptor()); // Check cache
app.addInterceptor(loggingInterceptor().request); // Log requests

Response Interceptors (After)

Execute after your route handler:

app.addInterceptor(corsInterceptor());         // Add CORS headers
app.addInterceptor(cacheStoreInterceptor()); // Store in cache
app.addInterceptor(loggingInterceptor().response); // Log responses

Key insight: Interceptors can short-circuit the pipeline (e.g., return from cache, block rate-limited requests).

4. Tasks - Units of Work

Tasks are the atomic units that do the actual work:

new Task({
when: async ({ req }) => req.method === 'POST', // Condition (optional)
do: async ({ req, env }) => { // Main logic
const body = await parseJSON(req);
const result = await processData(body, env);
return json({ result });
},
doThen: async (res, ctx) => { // Post-process (optional)
console.log('Task completed');
}
});

Key insight: Tasks compose - multiple tasks can run in sequence for a single route.

5. Context - Shared State

The context object flows through the entire request lifecycle:

interface Context {
reqCtx: { req: Request }; // The request
env?: any; // Environment (KV, D1, secrets)
ctx?: ExecutionContext; // Workers context
state: Map<string, any>; // Shared state
}

Use the context to share data:

// In interceptor
setState(ctx, 'user', { id: 123, role: 'admin' });

// In handler
const user = getState(ctx, 'user');

Key insight: State is scoped to a single request - perfect for edge's stateless model.

6. Helpers - Developer Experience

EdgeMaster provides helpers for common operations:

// Request helpers
const body = await parseJSON(req);
const formData = await parseFormData(req);
const query = getQuery(req, 'search');

// Response helpers
return json({ data }); // JSON response
return text('Hello'); // Text response
return html('<h1>Hi</h1>'); // HTML response
return redirect('/new-path'); // Redirect

// Error helpers
return badRequest('Invalid input');
return unauthorized('Auth required');
return notFound('Not found');
return serverError('Oops');

Key insight: Helpers abstract away boilerplate, letting you focus on business logic.


Framework Philosophy

1. Zero Dependencies = Maximum Compatibility

EdgeMaster has zero runtime dependencies. This means:

  • ✅ Smallest possible bundle size (~14 KB)
  • ✅ Works on any edge platform (Cloudflare, AWS, Azure, etc.)
  • ✅ No supply chain vulnerabilities
  • ✅ Predictable behavior

2. Type Safety First

Full TypeScript support with strict typing:

// Auto-complete and type checking everywhere
app.GET('/users', new RouteHandler(new Task({
do: async (ctx: ContextWithReq): Promise<Response> => {
// ctx.reqCtx.req is typed as Request
// env is typed based on your interface
// Return value must be Response
}
})));

3. Composability Over Configuration

Instead of complex configuration files, EdgeMaster uses composition:

// Compose interceptors
const authWithLogging = [
loggingInterceptor().request,
jwtInterceptor(),
loggingInterceptor().response
];

authWithLogging.forEach(i => app.addInterceptor(i));

// Compose tasks
const validateAndProcess = new RouteHandler(
validateTask,
processTask,
logTask
);

4. Edge-First Performance

Every decision optimized for edge constraints:

  • Fast cold starts (<1ms) - no heavy initialization
  • Minimal allocations - reuse objects where possible
  • CPU-efficient - async/await throughout, early exits
  • Memory-efficient - small footprint, no global state

5. Production-Ready Out of the Box

Built-in features you need for production:

  • JWT & API key authentication
  • Rate limiting (memory & KV-backed)
  • Caching (Cloudflare Cache API)
  • CORS support
  • Request/response logging
  • Error handling

When to Use EdgeMaster

✅ Great For:

  • API Gateways - Route and transform requests to backend services
  • REST APIs - Full CRUD operations with auth and caching
  • Microservices - Individual services on the edge
  • Proxy/Router - Intelligent request routing
  • Authentication Services - JWT/OAuth flows
  • Content APIs - Serve dynamic content from KV/D1
  • Real-time APIs - Low-latency responses globally

⚠️ Consider Alternatives For:

  • Static Sites - Use Cloudflare Pages or similar
  • Long-running Tasks - Use Durable Objects or traditional servers
  • Heavy Computation - Use traditional cloud functions
  • File Uploads >100MB - Use R2 directly with signed URLs
  • WebSocket-heavy Apps - Use Durable Objects

Comparison with Other Frameworks

vs Express.js

AspectEdgeMasterExpress
EnvironmentEdge (Workers)Node.js
Bundle Size14 KB200+ KB
Cold Start<1ms100-500ms
PhilosophyFunctional compositionImperative middleware
Best ForGlobal APIs, low latencyTraditional backends

vs Hono

AspectEdgeMasterHono
ArchitectureTask-based, structuredLightweight, simple
Built-in FeaturesAuth, rate limit, cacheBasic routing
ComplexityScales to large appsBest for simple apps
State ManagementContext.state MapContext variables

vs itty-router

AspectEdgeMasteritty-router
Size14 KB1 KB
FeaturesFull frameworkMinimal router
Production ReadyYes (auth, cache, etc.)DIY
Learning CurveModerateLow

Recommendation: Use itty-router for tiny projects, Hono for simple APIs, EdgeMaster for production applications.


Learning Path

1. Start Here

2. Understand the Foundation

3. Build Real Features

4. Master the Details


Key Takeaways

  1. EdgeMaster brings structure to edge computing - No more spaghetti code
  2. Interceptors handle cross-cutting concerns - DRY principle in action
  3. Tasks compose for complex logic - Build big from small pieces
  4. Context flows through the pipeline - Share data safely
  5. Zero dependencies = maximum compatibility - Works everywhere
  6. Type-safe by default - Catch errors before deployment
  7. Production-ready features included - Auth, caching, rate limiting

Next Steps


Welcome to EdgeMaster! The structured framework for edge computing.