Skip to content

programmerstevie/cf-workers-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

38 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

⚑ Cloudflare Hono API Boilerplate Project

A production-ready API template built with Cloudflare Workers, Hono, and Drizzle ORM β€” designed for building fast, type-safe APIs on the edge with minimal setup.

This is ideal for developers who want to skip boilerplate setup and start building APIs for dashboards, storefronts, or internal tools β€” using the same stack that powers modern edge apps.


This boilerplate includes:

  • Local Docker integration for Postgres
  • Built-in OpenAPI generation and Swagger UI
  • JWT authentication (RSA)
  • CSRF protection (HMAC)
  • CORS protection
  • A fully working example schema (Items, Tags, Statuses)
  • Seed data and local migration setup
  • Secure environment variable handling

πŸ“˜ Overview

This API provides:

  • A data interface for the Storefront, fetching product information.
  • An Admin Panel (Product Management Portal) backend for creating, updating, and deleting products, tags, and statuses.

It's designed for projects where you want a typed, OpenAPI-compliant, and serverless backend that can scale to production.


πŸ“¦ What's Included

  • 🧱 Prebuilt CRUD endpoints (items, tags, statuses)

  • 🧩 Typed OpenAPI schemas with @hono/zod-openapi

  • πŸ” JWT, CSRF and CORS middleware

  • 🐘 Local Postgres via Docker

  • πŸ§ͺ Vitest setup with Workers runtime

  • 🧰 Utility scripts for seamless onboarding


🧱 Tech Stack

Component Purpose
Cloudflare Workers Global edge hosting environment
Hono Lightweight web framework optimized for Workers
Drizzle ORM Type-safe SQL builder and migration management
Neon Serverless Postgres Cloud Postgres with free-tier support
Zod Runtime schema validation
Swagger UI Interactive API documentation
---
config:
  look: classic
  layout: elk
  theme: 'base'
  themeVariables:
    primaryColor: '#d0ec99ff'
    primaryTextColor: '#000000'
    primaryBorderColor: '#004806ff'
    secondaryColor: '#e1e1e1ff'
    lineColor: '#8b8b8bff'
---
flowchart TD
    ClientBrowser["🌐 Browser Client<br>(JavaScript Frontend)"]
    ClientServer["πŸ–₯️ Server Client<br>(Trusted API Consumer)"]

    subgraph Worker["Cloudflare Worker"]
        Worker_Middleware["πŸ”’ Middleware Layer<br>JWT Auth Β· CSRF Β· CORS Β· API Key"]
        Worker_API["βš™οΈ API Routes<br>@hono/zod-openapi"]
        Worker_DrizzleORM["🧱 Drizzle ORM<br>Schema · Queries · Migrations"]
        Worker_SwaggerUI["πŸ“˜ Swagger UI<br>/doc Β· /doc/ui"]
    end

    DB[("πŸ—„οΈ Neon Serverless Postgres Database")]

    %% Data Flow
    ClientBrowser -->|HTTPS JSON Requests| Worker
    ClientServer -->|"HTTPS JSON Requests \(x-api-key\)"| Worker
    Worker_Middleware --> Worker_API
    Worker_API -->|Type-safe Queries| Worker_DrizzleORM
    Worker_DrizzleORM -->|SQL Queries| DB

    %% Styling
    classDef local fill:#f2f2f2,stroke:#666,stroke-width:1px;
    classDef cloud fill:#e3f2fd,stroke:#2196f3,stroke-width:1px;
    classDef worker fill:#FFE0B2,stroke:#FF6D00,stroke-width:1px;

		class ClientBrowser local
		class ClientServer cloud
    class Worker worker;
    class DB cloud;
Loading

🧭 API Documentation

Type URL
OpenAPI Spec [base_url]/doc
Swagger UI [base_url]/doc/ui

All routes automatically register with the OpenAPI spec using @hono/zod-openapi.


πŸ’» Installation and Setup

1️⃣ Clone the repository

git clone https://github.com/yourusername/cf-workers-api-starter.git
cd cf-workers-api-starter

2️⃣ Install dependencies

npm install

3️⃣ Set up environment

npm run init
  • Sets the project name
  • Creates a .dev.vars file in the root with the variables shown above.

4️⃣ Run local development

npm run docker:up     # Start Docker + Postgres
npm run db:migrate    # Apply migrations
npm run dev           # Start local Cloudflare worker

5️⃣ Stop containers

npm run docker:down

🧩 Project Scripts

All available scripts are defined in your package.json.

βš™οΈ Development

Command Description
npm run docker:up Start Postgres container
npm run dev Start Cloudflare Worker locally
npm run docker:down Stop Postgres container

πŸ—ƒοΈ Database

Command Description
npm run db:generate Generate Drizzle migrations
npm run db:migrate Apply migrations
npm run custom-mig-step Create a custom migration step

☁️ Cloudflare

Command Description
npm run deploy Deploy Worker to Cloudflare
npm run cf:types Generate Worker type definitions
npm run cf:size Check bundle size before deploy

🧹 Lint & Format

Command Description
npm run lint Check for linting issues
npm run lint:fix Fix linting issues automatically
npm run format Format all files
npm run typecheck Run TypeScript checks

πŸ§ͺ Tests

Command Description
npm run test Run Vitest tests
npm run github-actions:local-test Run GitHub Actions locally (act)

🧰 Utilities

Command Description
npm run init Initialize project configuration
npm run gen:dir_tree Generate a directory tree view

πŸ” Security & Keys

Command Description
npm run gen:rsa_json Generate JWT RSA keys for all environments (dev/testing/prod)
npm run gen:rsa_keys <env> Generate RSA key pair for JWT (development, production, etc.)
npm run gen:hmac_key <env> Generate HMAC key for CSRF (development, production, etc.)
npm run gen:api_key <env> Generate API key for Server Consumers (development, production, etc.)

Examples:

npm run gen:rsa_keys development
npm run gen:hmac_key production
npm run gen:rsa_json

πŸͺ„ Quick Start

# 1) Setup project name, and dev environment variables
npm run init

# 2) Start Docker + local Postgres
npm run docker:up

# 3) Run database migrations
npm run db:migrate

# 4) Start local Cloudflare Worker
npm run dev

Once running, open https://127.0.0.1:9080/doc/ui to access Swagger UI.


πŸš€ Deployment

See deployment documentation here

  1. Configure your production environment in wrangler.toml:

    name = "your-project-name" # change this to whatever you'd like the worker to be called in cloudflare. Defaults to the name you gave with `npm run init`
    main = "src/index.ts"
    compatibility_date = "2024-04-05" # don't change this unless you know what you're doing
    account_id = "your_account_id_here" # replace with your actual account ID
    
    
    # Environment Variables for Production
    [env.production]
    main = "src/index.ts"
    [env.production.vars]
    NODE_ENV = "production"
    JWT_RSA_PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----..."
  2. Deploy to Cloudflare:

    npm run deploy
  3. Use Neon for your database:

    • Copy the connection string from Neon.
    • Set DATABASE_URL in your Cloudflare secrets.

βš™οΈ Environment Variables

πŸ”’ Secrets

Not safe to show the public. (stored for development in .dev.vars, for production in the CfWorker Secrets)

# Database connection
DATABASE_URL=postgres://user:password@localhost:5432/localdb

# JWT signing
JWT_RSA_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----..."

# CSRF protection
HMAC_KEY="your-hmac-key"

# CSRF protection
API_KEY="your-api-key"

You can upload secrets from your local terminal by executing the command: npx wrangler secret put [secret_name] [secret_value] for example npx wrangler secret put DATABASE_URL "postgres://user:password@db.myserver.net:5432/mydb"

🌍 Variables (wrangler.toml)

Deployed with the worker, safe to expose. (stored for development and production in wrangler.toml. Development has [env.development.vars] and production has [env.production.vars])

[env.production.vars]
NODE_ENV = "production"
JWT_RSA_PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----..."

βœ… Rule of thumb for local development: Secrets β†’ .dev.vars Non-secrets β†’ wrangler.toml


🧱 Project Structure

src/
β”œβ”€ api/               # Hono routes
β”‚  β”œβ”€ middleware/     # CSRF, JWT, CORS, DB connectors
β”‚  └─ routes/         # Resource endpoints
β”œβ”€ db/                # Drizzle ORM queries & schema
β”œβ”€ lib/               # Utilities (security, errors, etc.)
β”œβ”€ schema/            # Zod & OpenAPI schemas
scripts/              # Dev scripts (docker, keygen, etc.)
docker/               # Docker Compose setup
docs/                 # Further documents to help you use this template

🧭 Notes

  • Ensure Docker is installed and running before using local Postgres.
  • Neon can replace Docker for remote Postgres hosting.
  • Use .dev.vars for secrets and local environment values.
  • The included check-and-start-docker.ts script ensures smooth onboarding on all platforms (macOS, Windows, Linux, WSL).

βš–οΈ License

This project is open-source software licensed under the MIT License.

Feel free to use it as the foundation for your own private, commercial, or client projects. For more details, see the LICENSE file.

Steven Santos πŸ“§ programmerstevie@gmail.com

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors