{"id":17161,"library":"aspida","title":"Aspida","description":"Aspida is a TypeScript-friendly HTTP client wrapper designed for both browser and Node.js environments. It streamlines API client generation by enabling developers to define API endpoint types through a convention-over-configuration approach, leveraging a directory structure and `DefineMethods` type aliases. This approach significantly enhances type safety for API interactions at compile time, eliminating the need for manual client creation. Aspida supports integration with popular HTTP clients like Axios, Fetch, and Node-Fetch via official adapter packages. The current stable version is 1.14.0, and the project demonstrates an active release cadence with frequent updates. Its key differentiators include robust type inference for paths, query parameters, headers, request bodies, and responses, comprehensive support for `FormData` and `URLSearchParams`, and a unique workflow that generates a fully type-safe client based on a filesystem-defined API structure.","status":"active","version":"1.14.0","language":"javascript","source_language":"en","source_url":"https://github.com/aspida/aspida","tags":["javascript","typescript","xhr","http","ajax"],"install":[{"cmd":"npm install aspida","lang":"bash","label":"npm"},{"cmd":"yarn add aspida","lang":"bash","label":"yarn"},{"cmd":"pnpm add aspida","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required to use Axios as the underlying HTTP client for making requests.","package":"@aspida/axios","optional":false},{"reason":"The actual HTTP client library utilized by the `@aspida/axios` adapter.","package":"axios","optional":false}],"imports":[{"note":"This is a type-only import for defining API endpoint methods.","wrong":"const { DefineMethods } = require('aspida');","symbol":"DefineMethods","correct":"import type { DefineMethods } from 'aspida';"},{"note":"The `api` symbol is the generated client entry point from your `api` directory. The path depends on your project structure.","wrong":"const api = require('../api/$api');","symbol":"api","correct":"import api from '../api/$api';"},{"note":"This imports the adapter factory function for Axios. Use `@aspida/fetch` or `@aspida/node-fetch` for other HTTP clients.","wrong":"const aspida = require('@aspida/axios');","symbol":"aspida","correct":"import aspida from '@aspida/axios';"}],"quickstart":{"code":"import aspida from '@aspida/axios';\nimport api from '../api/$api'; // This file is generated by 'npm run api:build'\n\n// Ensure this directory structure is created and 'aspida' command is run:\n// api/\n// ├── v1/\n// │   ├── users/\n// │   │   ├── index.ts\n// │   │   └── _userId@number/\n// │   │       └── index.ts\n// package.json: { \"scripts\": { \"api:build\": \"aspida\" } }\n\n// Example: api/v1/users/index.ts\n// import type { DefineMethods } from \"aspida\";\n// type User = { id: number; name: string; };\n// export type Methods = DefineMethods<{\n//   get: { query?: { limit: number; }; resBody: User[]; };\n//   post: { reqBody: { name: string; }; resBody: User; };\n// }>;\n\n(async () => {\n  const userId = 0;\n  const limit = 10;\n  const client = api(aspida()); // Initialize the client with the Axios adapter\n\n  try {\n    // Example: POST /v1/users\n    const newUser = await client.v1.users.post({ body: { name: 'aspida-user' } });\n    console.log('Created user:', newUser.body);\n\n    // Example: GET /v1/users?limit=10\n    const users = await client.v1.users.get({ query: { limit } });\n    console.log('Users list:', users.body);\n\n    // Example: GET /v1/users/0\n    const userById = await client.v1.users._userId(userId).$get();\n    console.log('User by ID:', userById.body);\n\n  } catch (error) {\n    console.error('API request failed:', error);\n  }\n})();","lang":"typescript","description":"Demonstrates how to install Aspida with the Axios adapter, define API endpoints, generate type-safe client code, and make various HTTP requests using the generated client."},"warnings":[{"fix":"Ensure `aspida` is listed in your project's `dependencies` or `devDependencies` (`npm install aspida` or `yarn add aspida`).","message":"Aspida moved the core `aspida` package to a peerDependency in v1.14.0. This means you must explicitly install `aspida` alongside any `@aspida/*` adapter packages. Previously, it might have been implicitly installed.","severity":"breaking","affected_versions":">=1.14.0"},{"fix":"Review and update your import paths for generated files (e.g., `../api/$api` might change if the postfix convention affects the top-level generated file directly, or internal generated types). Re-run `npm run api:build` and inspect the generated `$api.ts` file for new import patterns.","message":"Starting with v1.14.0, import names for generated client files changed their postfix to a hash (`#`). This could affect existing import statements that relied on the previous naming convention for generated type definition files.","severity":"breaking","affected_versions":">=1.14.0"},{"fix":"Add `\"api:build\": \"aspida\"` to your `package.json` scripts and run `npm run api:build` before starting your application development or build process.","message":"The Aspida CLI requires a build step (`npm run api:build`) to generate the `$api.ts` type definition file based on your `api` directory structure. Forgetting this step or not having it configured will result in missing module errors.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always specify the type of path variables explicitly using the `@type` postfix (e.g., `_id@string`, `_postId@number`) in your API directory structure.","message":"When defining path variables, specifying the type (e.g., `_userId@number`) is crucial. If omitted (e.g., `_userId/`), the path variable type defaults to `number | string`, which might be less specific than intended and lead to weaker type checking.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Ensure you have `\"api:build\": \"aspida\"` in your `package.json` scripts, then run `npm run api:build`. Verify the import path `../api/$api` matches the location where `aspida` generates the file.","cause":"The Aspida API client definition file `$api.ts` has not been generated, or the import path is incorrect.","error":"Cannot find module '../api/$api' or its corresponding type declarations."},{"fix":"Ensure you are initializing the client correctly with `const client = api(aspida());`. Make sure `@aspida/axios` (or your chosen adapter) is installed and imported as `aspida`.","cause":"The `api` object imported from the generated `$api.ts` is not being called as a factory function with an Aspida adapter, or the adapter itself is missing/incorrect.","error":"TypeError: api is not a function"},{"fix":"Double-check your `api` directory structure against how you are accessing the client (e.g., `client.v1.users`). Re-run `npm run api:build` to ensure the client reflects the latest directory definitions.","cause":"This typically means there's a mismatch between the expected API structure in your code and what was generated by Aspida, or the generated `$api.ts` file is outdated.","error":"Property 'v1' does not exist on type '(...)'"}],"ecosystem":"npm","meta_description":null}