{"id":10883,"library":"fets","title":"feTS HTTP Framework","description":"feTS (Fetch API + TypeScript) is a modern TypeScript HTTP framework designed for building performant and type-safe REST APIs. It prioritizes end-to-end type-safety, ease of setup, and a superior developer experience by leveraging the Web Fetch API standards. The framework is currently stable at version 0.8.6 and maintains an active development pace with frequent patch releases and minor version updates every few months, incorporating bug fixes, dependency upgrades, and new features. A key differentiator is its deep integration with TypeScript, coupled with `@sinclair/typebox` for defining robust schemas. This approach enables automatic runtime validation and OpenAPI specification generation, significantly reducing common API development pitfalls and ensuring consistent type adherence across the entire application stack, from client to server. It's built for Node.js environments and requires version 16.0.0 or higher.","status":"active","version":"0.8.6","language":"javascript","source_language":"en","source_url":"https://github.com/ardatan/fets","tags":["javascript","typescript"],"install":[{"cmd":"npm install fets","lang":"bash","label":"npm"},{"cmd":"yarn add fets","lang":"bash","label":"yarn"},{"cmd":"pnpm add fets","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core HTTP server implementation, providing the underlying Web Fetch API compatible server environment.","package":"@whatwg-node/server","optional":false},{"reason":"Used for defining JSON schemas, which are critical for runtime validation, type inference, and OpenAPI specification generation.","package":"@sinclair/typebox","optional":false}],"imports":[{"note":"feTS is primarily an ESM-first library, especially for Node.js >=16.0.0 environments. Avoid CommonJS `require` syntax.","wrong":"const { createServer } = require('fets')","symbol":"createServer","correct":"import { createServer } from 'fets'"},{"note":"Routes are typically created using `createRouter` and integrated with `createServer`.","wrong":"import createRouter from 'fets/router'","symbol":"createRouter","correct":"import { createRouter } from 'fets'"},{"note":"TypeBox's `Type` object is fundamental for defining schemas for requests, responses, and parameters, enabling type-safety and validation.","symbol":"Type","correct":"import { Type } from '@sinclair/typebox'"}],"quickstart":{"code":"import { createServer, createRouter, Response } from 'fets';\nimport { Type } from '@sinclair/typebox';\n\nconst userSchema = Type.Object({\n  id: Type.String(),\n  name: Type.String(),\n});\n\nconst router = createRouter()\n  .get(\n    '/greet/:name',\n    {\n      parameters: Type.Object({\n        name: Type.String({ description: 'The name to greet' }),\n      }),\n      responses: {\n        200: Type.String(),\n      },\n    },\n    ({ params }) => Response.json(`Hello, ${params.name}!`)\n  )\n  .post(\n    '/users',\n    {\n      body: userSchema,\n      responses: {\n        201: userSchema,\n      },\n    },\n    async ({ body }) => {\n      console.log('Received user:', body);\n      // In a real app, you'd save this to a database\n      return new Response(JSON.stringify({ ...body, id: 'new-id-' + Math.random().toString(36).substring(7) }), {\n        status: 201,\n        headers: { 'Content-Type': 'application/json' },\n      });\n    }\n  );\n\nconst server = createServer({\n  router,\n});\n\nserver.listen(4000, () => {\n  console.log('feTS server running on http://localhost:4000');\n  console.log('Try: curl http://localhost:4000/greet/World');\n  console.log('Try: curl -X POST -H \"Content-Type: application/json\" -d \\'{\"name\":\"Alice\"}\\' http://localhost:4000/users');\n});\n","lang":"typescript","description":"This quickstart demonstrates creating a basic feTS server with a GET route using path parameters and a POST route with a JSON body, showcasing TypeBox schema integration for type-safety and validation."},"warnings":[{"fix":"Upgrade to `fets@0.8.6` or higher to correctly respect `Type.Optional` for request bodies in OpenAPI spec generation and validation. Ensure your TypeBox schemas accurately reflect whether a request body is truly optional.","message":"Previously, the OpenAPI plugin hardcoded `requestBody.required = true` for all JSON and formData request bodies, even if they were defined as optional using TypeBox's `Type.Optional` modifier. This meant that clients making requests without a body to an endpoint expecting an optional body would still receive a validation error indicating a missing body.","severity":"breaking","affected_versions":"<0.8.6"},{"fix":"Review and update your TypeBox schemas and the types used in your route handlers to match the stricter parameter typing. Ensure all request parameters strictly conform to their schema definitions.","message":"Version 0.8.1 introduced more strict typing on request parameters. Existing code that previously passed type checks for request parameters (path, query, headers, body) might now yield TypeScript errors if the types are not precisely aligned with the defined TypeBox schemas.","severity":"breaking","affected_versions":">=0.8.1"},{"fix":"Ensure your project is configured for ESM. Use `import` statements for all feTS modules and ensure your `package.json` includes `\"type\": \"module\"` or uses `.mjs` file extensions for your source files.","message":"feTS is designed for modern Node.js environments (>=16.0.0) and largely expects an ESM (ECMAScript Modules) setup. Using CommonJS `require()` syntax for imports can lead to `ReferenceError: require is not defined` or similar module resolution issues.","severity":"gotcha","affected_versions":">=0.7.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Change `const { symbol } = require('package')` to `import { symbol } from 'package'` for all module imports. Ensure your `package.json` has `\"type\": \"module\"`.","cause":"Attempting to use CommonJS `require()` syntax in a feTS project, which is typically configured for ESM.","error":"ReferenceError: require is not defined"},{"fix":"Carefully review your TypeBox schemas and the corresponding TypeScript types in your route handlers. Ensure that the shapes of the data being sent, received, or returned precisely match the defined schemas.","cause":"Mismatch between the data structure provided to a feTS route handler (e.g., body, params) or returned from it, and the TypeBox schema defined for that route.","error":"Argument of type '...' is not assignable to parameter of type '...' (TypeScript error)"},{"fix":"If the request body is genuinely optional, ensure your TypeBox schema for the request body is wrapped with `Type.Optional(Type.Object(...))` and you are on `fets@0.8.6` or higher. Otherwise, provide the required request body in your client request.","cause":"Sending a request to an endpoint with a TypeBox schema that defines the request body as `Type.Object(...)` without `Type.Optional(...)` wrapper, but the request does not include a body.","error":"Request body is required but not provided (during OpenAPI validation or client request)"}],"ecosystem":"npm"}