{"id":31725700,"url":"https://github.com/code-yeongyu/bun-elysiajs-cfworkers-template","last_synced_at":"2025-10-09T05:57:00.519Z","repository":{"id":317008142,"uuid":"1065310265","full_name":"code-yeongyu/bun-elysiajs-cfworkers-template","owner":"code-yeongyu","description":"Production-ready API template with Bun, ElysiaJS, and Cloudflare Workers. Features automatic OpenAPI generation and type-safe request/response validation.","archived":false,"fork":false,"pushed_at":"2025-09-28T06:45:19.000Z","size":28,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-09-28T08:40:09.302Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/code-yeongyu.png","metadata":{"files":{"readme":"README.en-us.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-27T13:17:36.000Z","updated_at":"2025-09-28T06:45:23.000Z","dependencies_parsed_at":"2025-09-29T22:17:44.917Z","dependency_job_id":null,"html_url":"https://github.com/code-yeongyu/bun-elysiajs-cfworkers-template","commit_stats":null,"previous_names":["code-yeongyu/bun-elysiajs-cfworkers-template"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/code-yeongyu/bun-elysiajs-cfworkers-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-yeongyu%2Fbun-elysiajs-cfworkers-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-yeongyu%2Fbun-elysiajs-cfworkers-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-yeongyu%2Fbun-elysiajs-cfworkers-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-yeongyu%2Fbun-elysiajs-cfworkers-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/code-yeongyu","download_url":"https://codeload.github.com/code-yeongyu/bun-elysiajs-cfworkers-template/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-yeongyu%2Fbun-elysiajs-cfworkers-template/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279000741,"owners_count":26082932,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-09T05:56:59.181Z","updated_at":"2025-10-09T05:57:00.505Z","avatar_url":"https://github.com/code-yeongyu.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Bun ElysiaJS Cloudflare Workers Template\n\nA production-ready API template built with Bun, ElysiaJS, and Cloudflare Workers. Ships with automatic OpenAPI documentation generation and type-safe request/response validation.\n\n## Why This Stack\n\n- **Type-safe**: Elysia's type system catches errors at compile time\n- **Fast**: Elysia AOT compilation with no runtime overhead\n- **Auto-documented**: Define schemas once, get OpenAPI specs automatically\n\nStandard Elysia has [limitations when running on Cloudflare Workers](https://elysiajs.com/integrations/cloudflare-worker.html#limitations) - notably, TypeGen (automatic type generation) doesn't work in the Workers environment. This template solves these issues by generating OpenAPI specifications at build time and serving them as [static assets](https://developers.cloudflare.com/workers/static-assets/) from Cloudflare Workers. All documentation (openapi.json, Swagger UI, Redoc, and Scalar) is pre-generated and bundled as static files, ensuring fast delivery and AOT compilation compatibility.\n\n## Requirements\n\n- [Bun](https://bun.sh/)\n- Cloudflare Workers account (for deployment)\n\n## Quick Start\n\n```bash\n# Install dependencies\nbun install\n\n# Generate OpenAPI spec\nbun run generate:openapi\n\n# Start dev server\nbun run dev\n```\n\nYour API runs at `http://localhost:8787`\nDocumentation lives at `http://localhost:8787/docs`\n\n## Project Structure\n\n```\nsrc/\n├── index.ts              # Cloudflare Workers entry (AOT compiled)\n├── app.ts                # App factory\n├── config/\n│   └── openapi.ts        # OpenAPI configuration\n└── routes/\n    ├── base/\n    │   ├── index.ts      # Route aggregator\n    │   ├── echo.ts       # Example endpoint\n    │   └── schemas/      # Type definitions\n    │       ├── requests/\n    │       ├── responses/\n    │       └── headers/\n    └── docs/             # Documentation routes\n```\n\n## Configuration\n\n### OpenAPI Settings\n\nEdit `src/config/openapi.ts` to customize your API documentation:\n\n```typescript\nexport const getOpenAPIConfig = (): ElysiaSwaggerConfig =\u003e {\n  return {\n    documentation: {\n      info: {\n        title: 'Your API Name',\n        version: '1.0.0',\n        description: 'API description'\n      },\n      servers: [\n        { url: 'https://your-domain.workers.dev', description: 'Production' }\n      ],\n      tags: [\n        { name: 'YourTag', description: 'Tag description' }\n      ]\n    },\n    path: '/swagger',\n    provider: 'scalar'\n  };\n};\n```\n\n### Cloudflare Workers\n\nUpdate `wrangler.toml` with your project details:\n\n```toml\nname = \"your-project-name\"\nmain = \"src/index.ts\"\ncompatibility_date = \"2025-06-01\"\ncompatibility_flags = [\"nodejs_compat\"]\n```\n\n## Writing Endpoints\n\nThis is where it gets good. Define types once, get validation and docs automatically.\n\n### 1. Define Schemas\n\nCreate your request/response schemas using Elysia's type system:\n\n```typescript\n// src/routes/example/schemas/requests/create_user.ts\nimport { t } from 'elysia';\n\nexport const CreateUserRequest = t.Object({\n  name: t.String({ minLength: 1 }),\n  email: t.String({ format: 'email' }),\n  age: t.Optional(t.Number({ minimum: 0 }))\n});\n```\n\n```typescript\n// src/routes/example/schemas/responses/create_user.ts\nimport { t } from 'elysia';\n\nexport const CreateUserResponse = t.Object({\n  id: t.String(),\n  name: t.String(),\n  email: t.String(),\n  createdAt: t.String()\n});\n```\n\n### 2. Create Endpoint\n\nWire up your schemas to an endpoint:\n\n```typescript\n// src/routes/example/create_user.ts\nimport { Elysia } from 'elysia';\nimport { CreateUserRequest } from './schemas/requests/create_user';\nimport { CreateUserResponse } from './schemas/responses/create_user';\n\nexport const createUserRoute = new Elysia().post(\n  '/users',\n  ({ body }) =\u003e {\n    // TypeScript knows the shape of `body` here\n    return {\n      id: crypto.randomUUID(),\n      name: body.name,\n      email: body.email,\n      createdAt: new Date().toISOString()\n    };\n  },\n  {\n    body: CreateUserRequest,\n    response: CreateUserResponse,\n    detail: {\n      summary: 'Create a new user',\n      description: 'Creates a user account with the provided details',\n      tags: ['Users']\n    }\n  }\n);\n```\n\n### 3. Register Route\n\nAdd your route to the router:\n\n```typescript\n// src/routes/example/index.ts\nimport { Elysia } from 'elysia';\nimport { createUserRoute } from './create_user';\n\nexport const exampleRouter = new Elysia()\n  .use(createUserRoute);\n```\n\nThen register the router in `src/app.ts`:\n\n```typescript\nimport { exampleRouter } from './routes/example';\n\nexport const createApp = (config?: ConstructorParameters\u003ctypeof Elysia\u003e[0]) =\u003e {\n  return new Elysia(config)\n    .use(baseRouter)\n    .use(exampleRouter)  // Add this\n    .use(docsRoute);\n};\n```\n\n### 4. Regenerate OpenAPI Spec\n\n```bash\nbun run generate:openapi\n```\n\nThat's it. Your endpoint is now:\n- Type-checked at compile time\n- Validated at runtime\n- Documented in OpenAPI/Swagger\n\n## How It Works\n\nThe key difference is in two components:\n\n1. **AOT Compilation** (`src/index.ts`):\n```typescript\nconst app = createApp({\n  adapter: CloudflareAdapter,\n  aot: true  // Ahead-of-time compilation for Cloudflare\n});\n\nexport default app.compile();\n```\n\n2. **Static Documentation Serving** (`src/routes/docs/index.ts`):\n```typescript\nconst getOpenAPISpec = async () =\u003e {\n  const module = await import('./generated/openapi.json');\n  return module.default;\n};\n```\n\nThe OpenAPI spec and all documentation interfaces are pre-generated at build time and served as [static assets](https://developers.cloudflare.com/workers/static-assets/) from Cloudflare Workers. This approach enables both AOT compilation performance and complete API documentation without runtime generation overhead.\n\n## Development\n\n```bash\n# Type checking\nbun run typecheck\n\n# Run tests\nbun run test\n\n# Format code\nbun run format\n\n# Lint\nbun run lint\n\n# Test OpenAPI freshness\nbun run test:openapi\n```\n\nThe freshness test ensures your OpenAPI spec stays in sync with your routes. It fails if route files are modified after the spec was generated.\n\n## Deployment\n\n```bash\n# Deploy to Cloudflare Workers\nbun run deploy\n```\n\nThis command:\n1. Generates fresh OpenAPI spec\n2. Runs freshness tests\n3. Deploys to Cloudflare Workers\n\nConfigure deployment environments in `wrangler.toml`:\n\n```toml\n[env.production]\nname = \"your-project-production\"\n```\n\n## Performance Notes\n\n- **Cold start**: ~10ms (thanks to AOT compilation)\n- **Request handling**: Sub-millisecond for simple routes\n- **Bundle size**: Minimal (Elysia is lean)\n\nThe combination of Bun's build speed, Elysia's AOT, and Cloudflare's edge network means your API responds fast from anywhere.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcode-yeongyu%2Fbun-elysiajs-cfworkers-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcode-yeongyu%2Fbun-elysiajs-cfworkers-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcode-yeongyu%2Fbun-elysiajs-cfworkers-template/lists"}