Skip to main content
Contributions should follow the project’s coding and structure rules to keep the repository consistent and maintainable.

Experiment Structure

Every experiment lives under experiments/<name>/ with this standardized layout:

Directory Breakdown

The main entry point for the Worker. This file:
  • Creates a new Hono app instance
  • Mounts route handlers
  • Registers global error handling
  • Exports { fetch: app.fetch }
Example:
Contains route handlers only. Each file exports a Hono app with one or more related routes.Example from src/routes/check.ts:
Domain logic and business functionality. This includes:
  • URL validation
  • Fetch operations
  • Data parsing
  • External API interactions
Example from src/lib/url.ts:
Shared helper functions used across the experiment.Example from src/utils/response.ts:
Optional directory for configuration values and literals.Example from src/constants/defaults.ts:
All TypeScript type definitions. Worker environment bindings go in env.d.ts.Example from src/types/env.d.ts:

Core Principles

No shared code between experiments: Each experiment is standalone with its own package.json and dependencies. Do not import from other experiments or the repo root.
Single responsibility: One experiment = one Cloudflare capability (e.g. Workers AI, Browser Rendering, D1).
Edge-first, under ~60 seconds: Prefer stateless, fast request paths that complete quickly.

TypeScript and API Style

Strict TypeScript

  • Use strict TypeScript; avoid any
  • Type Worker env in src/types/env.d.ts and use Hono<{ Bindings: Env }>
  • All types should be explicitly defined

Error Handling

Use a shared helper for client errors:
Status code guidelines:
  • 400 for bad request (invalid input)
  • 404 for not found
  • 502 for server/upstream errors (don’t expose internals)
Example:

Success Responses

Use jsonSuccess(c, data) for JSON success responses:

Global Error Handler

In src/index.ts, register app.onError(...) so uncaught errors return consistent JSON:

URL Parameter Validation

For any endpoint that takes a url query param:
  • Validate with a shared validateUrl(input) in src/lib/url.ts
  • Allow only http:// and https://
  • Return jsonError with a clear message and code (e.g. INVALID_URL) when invalid
Example:

Naming Conventions

  • Error codes: Descriptive uppercase with underscores (e.g. INVALID_URL, FETCH_ERROR, INTERNAL_ERROR)
  • Routes: Files in src/routes/ with kebab-case filenames matching the path (e.g. check.ts for /check)
  • Functions: camelCase for functions and variables
  • Types: PascalCase for interfaces and types

Real-World Examples

Error Handling Pattern

From src/lib/fetch.ts in the is-it-down experiment:

Database Operations with Error Handling

From src/routes/shorten.ts in the link-shortener experiment:

Configuration Files

wrangler.toml/wrangler.json

Declare all Cloudflare bindings (D1, KV, R2, AI, etc.) in this file. These bindings must also be typed in src/types/env.d.ts.

package.json

Each experiment has its own dependencies. Common dependencies:
  • hono - Web framework
  • @cloudflare/workers-types - TypeScript types for Workers

tsconfig.json

Enable strict mode and configure paths appropriately for the experiment.

Quality Checklist

Before submitting a PR, ensure:
  • TypeScript strict mode is enabled with no any types
  • All errors use jsonError with descriptive codes
  • Global error handler is registered in index.ts
  • URL parameters are validated with validateUrl
  • Environment bindings are declared in both wrangler.toml and src/types/env.d.ts
  • Routes are in src/routes/, logic in src/lib/, helpers in src/utils/
  • The experiment can be deployed with npx wrangler deploy
  • README.md documents the API and usage

Next Steps