{"id":28148520,"url":"https://github.com/luukgoossen/elysia-procedures","last_synced_at":"2026-04-26T22:31:22.516Z","repository":{"id":293257478,"uuid":"979667945","full_name":"luukgoossen/elysia-procedures","owner":"luukgoossen","description":"A type-safe, composable procedure builder for Elysia with TypeBox validation. Build robust API endpoints with reusable middleware, input validation, and full TypeScript support. Inspired by tRPC's procedure pattern for end-to-end type safety.","archived":false,"fork":false,"pushed_at":"2025-12-13T12:18:04.000Z","size":186,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-12-14T11:53:37.702Z","etag":null,"topics":["elysia","typebox","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/luukgoossen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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-05-07T22:03:09.000Z","updated_at":"2025-12-13T12:18:07.000Z","dependencies_parsed_at":"2025-05-15T01:13:43.996Z","dependency_job_id":"a779445c-18db-4fac-a264-343bfc4e1b85","html_url":"https://github.com/luukgoossen/elysia-procedures","commit_stats":null,"previous_names":["luukgoossen/elysia-procedures"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/luukgoossen/elysia-procedures","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luukgoossen%2Felysia-procedures","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luukgoossen%2Felysia-procedures/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luukgoossen%2Felysia-procedures/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luukgoossen%2Felysia-procedures/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/luukgoossen","download_url":"https://codeload.github.com/luukgoossen/elysia-procedures/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luukgoossen%2Felysia-procedures/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32315711,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T21:09:39.134Z","status":"ssl_error","status_checked_at":"2026-04-26T21:09:21.240Z","response_time":129,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["elysia","typebox","typescript"],"created_at":"2025-05-15T01:13:41.182Z","updated_at":"2026-04-26T22:31:22.511Z","avatar_url":"https://github.com/luukgoossen.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Elysia Procedures\n\nA type-safe, composable procedure builder for [Elysia](https://elysiajs.com) with [TypeBox](https://github.com/sinclairzx81/typebox) validation. Build robust API endpoints with reusable middleware, input validation, and full TypeScript support. Inspired by tRPC's procedure pattern for end-to-end type safety.\n\n## Table of Contents\n\n- [Features](#features)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Usage](#usage)\n  - [Creating a Basic Procedure](#creating-a-basic-procedure)\n  - [Adding Schema Validation](#adding-schema-validation)\n  - [Creating Actions](#creating-actions)\n- [Integrating with Elysia](#integrating-with-elysia)\n- [Caching](#caching)\n- [Telemetry](#telemetry)\n- [Acknowledgments](#acknowledgments)\n\n## Features\n\n- 🥇 **Elysia** - First class integration with the Elysia framework\n- 🔒 **Type-safe** - Full TypeScript support with inferred types\n- ✅ **Validation** - Built-in schema validation using TypeBox\n- 🧩 **Composable** - Create reusable procedures and middleware\n- 📚 **Documentation** - Co-locate your OpenAPI documentation with the handlers\n- 💾 **Caching** - Dependency-based request-level caching\n- 🔗 **tRPC-style** - Familiar procedure-based patterns for type-safe APIs\n\n## Installation\n\n```bash\n# Using npm\nnpm install @luukgoossen/elysia-procedures\n\n# Using yarn\nyarn add @luukgoossen/elysia-procedures\n\n# Using pnpm\npnpm add @luukgoossen/elysia-procedures\n\n# Using bun\nbun add @luukgoossen/elysia-procedures\n```\n\n## Quick Start\n\n```typescript\nimport { Elysia } from \"elysia\";\nimport { createProcedure } from \"@luukgoossen/elysia-procedures\";\nimport { Type } from \"@sinclair/typebox\";\n\n// Create an authentication middleware procedure\nconst authProcedure = createProcedure(\"Ensure Auth\").build(async ({ ctx }) =\u003e {\n  // Check auth header\n  const authHeader = ctx.request.headers.get(\"Authorization\");\n  if (!authHeader) {\n    throw new Error(\"Unauthorized\");\n  }\n\n  // Return user data to be added to context\n  return {\n    user: {\n      id: \"123\",\n      name: \"John Doe\",\n      role: \"admin\",\n    },\n  };\n});\n\n// Create a procedure that requires authentication\nconst userProcedure = createProcedure(\"With User Profile\", authProcedure)\n  .params(\n    Type.Object({\n      userId: Type.String(),\n    })\n  )\n  .query(\n    Type.Object({\n      include: Type.Optional(Type.String()),\n    })\n  )\n  .build(({ ctx, params, query }) =\u003e {\n    // ctx.user is available because of the auth middleware\n    console.log(`User ${ctx.user.name} is accessing profile ${params.userId}`);\n\n    return {\n      success: true,\n    };\n  });\n\n// Create an API endpoint action with our procedure\nconst getUserAction = userProcedure\n  .createAction(\"Get User\")\n  .output(\n    Type.Object({\n      id: Type.String(),\n      name: Type.String(),\n      email: Type.String(),\n      role: Type.String(),\n    })\n  )\n  .build(({ ctx, params }) =\u003e {\n    // Fetch user data based on params.userId\n    return {\n      id: params.userId,\n      name: \"Jane Doe\",\n      email: \"jane@example.com\",\n      role: \"user\",\n    };\n  });\n\n// Get the result of the action\nconst user = await getUserAction.run(context, { params, query, body });\n```\n\n## Usage\n\n### Creating a Basic Procedure\n\nA procedure is a reusable foundation for your API endpoints. It can define common parameters, validation schemas, and middleware.\n\n```typescript\nimport { createProcedure } from \"@luukgoossen/elysia-procedures\";\nimport { Type } from \"@sinclair/typebox\";\n\n// Create a basic procedure\nconst baseProcedure = createProcedure(\"Basic Procedure\").build(({ ctx }) =\u003e {\n  console.log(\"Request received:\", ctx.request.url);\n  return { requestTime: new Date() };\n});\n```\n\n### Adding Schema Validation\n\nYou can add TypeBox schemas to validate parameters, query strings, and request bodies:\n\n```typescript\nconst productProcedure = createProcedure(\"Ensure Product\", baseProcedure)\n  .params(\n    Type.Object({\n      productId: Type.String(),\n    })\n  )\n  .query(\n    Type.Object({\n      currency: Type.Optional(Type.String({ default: \"USD\" })),\n      format: Type.Optional(Type.Enum({ json: \"json\", xml: \"xml\" })),\n    })\n  )\n  .body(\n    Type.Object({\n      includeDetails: Type.Boolean(),\n    })\n  )\n  .build(({ params, query, body, ctx }) =\u003e {\n    // All inputs are validated and typed\n    console.log(\n      `Fetching product ${params.productId} in ${query.currency} format`\n    );\n\n    return {\n      productDetails: true,\n    };\n  });\n```\n\n### Creating Actions\n\nActions represent the actual API endpoints built from procedures:\n\n```typescript\nconst getProductAction = productProcedure\n  .createAction(\"Get Product\")\n  .output(\n    Type.Object({\n      id: Type.String(),\n      name: Type.String(),\n      price: Type.Number(),\n      details: Type.Optional(\n        Type.Object({\n          description: Type.String(),\n          specifications: Type.Array(Type.String()),\n        })\n      ),\n    })\n  )\n  .build(({ params, query, body, ctx }) =\u003e {\n    // Fetch product from database\n    return {\n      id: params.productId,\n      name: \"Amazing Product\",\n      price: 99.99,\n      details: body.includeDetails\n        ? {\n            description: \"This is an amazing product\",\n            specifications: [\"Spec 1\", \"Spec 2\"],\n          }\n        : undefined,\n    };\n  });\n```\n\n## Integrating with Elysia\n\nThis library has first class support for integrating with the Elysia framework through the action.handle function, which expects an Elysia context, and action.docs which returns Elysia-formatted documentation defining the input and output schemas in a type-safe way.\n\nIt also hooks into Elysia's OpenTelemetry plugin to add tracing to procedure and action runs, providing step by step information about the executed chain.\n\n```typescript\nimport { Elysia } from \"elysia\";\n\nconst app = new Elysia()\n  .get(\"/products/:productId\", getProductAction.handle, getProductAction.docs)\n  .post(\n    \"/products/:productId/update\",\n    updateProductAction.handle,\n    updateProductAction.docs\n  )\n  .listen(3000);\n```\n\n## Caching\n\nThis library supports request-level caching to ensure that procedures are executed only once per http request. To enable caching for a procedure, you can supply an array of dependencies to the procedure builder.\n\n```typescript\nimport { createProcedure } from \"@luukgoossen/elysia-procedures\";\nimport { Type } from \"@sinclair/typebox\";\n\n// Create a basic procedure\nconst baseProcedure = createProcedure(\"Basic Procedure\")\n  .cache(() =\u003e [])\n  .build(async ({ ctx }) =\u003e {\n    console.log(\"Request received:\", ctx.request.url);\n\n    // simulate a long-running process\n    await new Promise((resolve) =\u003e setTimeout(resolve, 1000));\n\n    return { requestTime: new Date() };\n  });\n```\n\nAny array will enable caching for the procedure, but if input variables might change between different calls to the same procedure for the same request, it is important to include their keys in the array.\n\n```typescript\nimport { createProcedure } from \"@luukgoossen/elysia-procedures\";\nimport { Type } from \"@sinclair/typebox\";\n\n// Create a basic procedure\nconst baseProcedure = createProcedure(\"Basic Procedure\")\n  .params(\n    Type.Object({\n      productId: Type.String(),\n    })\n  )\n  .cache(({ params }) =\u003e [params.productId])\n  .build(async ({ ctx }) =\u003e {\n    console.log(\"Request received:\", ctx.request.url);\n\n    // simulate a long-running process\n    await new Promise((resolve) =\u003e setTimeout(resolve, 1000));\n\n    return { requestTime: new Date() };\n  });\n```\n\n## Telemetry\n\nThis package supports telemetry tracing. Both `@sentry/bun` and `@elysiajs/opentelemetry` are defined as optional peer dependencies. If either one is installed, telemetry traces will be made available. If both are installed, `@sentry/bun` takes priority over `@elysiajs/opentelemetry`.\n\n## Acknowledgments\n\n- [Elysia](https://elysiajs.com/) - The fast, and friendly Bun web framework\n- [TypeBox](https://github.com/sinclairzx81/typebox) - JSON Schema Type Builder with Static Type Resolution\n- [tRPC](https://trpc.io/) - End-to-end typesafe APIs made easy, inspiration for the procedure patterns\n- [ZSA](https://zsa.vercel.app/) - Validation library that inspired aspects of the middleware approach\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluukgoossen%2Felysia-procedures","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fluukgoossen%2Felysia-procedures","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluukgoossen%2Felysia-procedures/lists"}