Getting Started
This guide will walk you through installing Apinni, configuring your project, and generating your first type-safe API definitions.
New to Apinni? This guide assumes you have a TypeScript project set up. If you're starting from scratch, create a new TypeScript project first.
System Requirements
- Node.js 18.x or later
- TypeScript 4.5 or later
- Package Manager: npm, Yarn, or pnpm
Installation
Install Apinni as a development dependency in your project:
- npm
- Yarn
- pnpm
npm install @apinni/client-ts --save-dev
yarn add -D @apinni/client-ts
pnpm add -D @apinni/client-ts
TypeScript Configuration
Apinni requires TypeScript decorators to be enabled. Update your tsconfig.json:
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"outDir": "./dist",
"rootDir": "./src"
}
}
Without experimentalDecorators and emitDecoratorMetadata, Apinni cannot process your decorators.
Quick Start
Let's create your first API controller and generate types.
Step 1: Create a Configuration File
Create an apinni.config.ts file in your project root:
- TypeScript
- JavaScript (ESM)
- JavaScript (CommonJS)
import type { ApinniConfig } from '@apinni/client-ts';
export default {
outputPath: './types',
plugins: [],
} satisfies ApinniConfig;
export default {
outputPath: './types',
plugins: [],
};
module.exports = {
outputPath: './types',
plugins: [],
};
Step 2: Create Your First Controller
Create a controller file with Apinni decorators:
import { ApinniController, ApinniEndpoint } from '@apinni/client-ts';
interface User {
id: string;
name: string;
email: string;
}
@ApinniController({ path: '/api/users' })
export class UserController {
@ApinniEndpoint({ path: '/:id', method: 'GET' })
async getUserById(): Promise<User> {
// Your implementation here
return {
id: '123',
name: 'Alice',
email: 'alice@example.com'
};
}
@ApinniEndpoint({ path: '/', method: 'POST' })
async createUser(): Promise<User> {
// Your implementation here
return {
id: '456',
name: 'Bob',
email: 'bob@example.com'
};
}
}
Step 3: Add Scripts to package.json
Add Apinni commands to your package.json:
{
"scripts": {
"types:generate": "apinni generate",
"types:watch": "apinni watch"
}
}
Step 4: Generate Types
Run the generation command:
- npm
- Yarn
- pnpm
npm run types:generate
yarn types:generate
pnpm types:generate
Apinni will generate a type definition file in the ./types directory:
// Auto-generated by Apinni
export interface GetApiUsersByIdResponse {
id: string;
name: string;
email: string;
}
export interface PostApiUsersResponse {
id: string;
name: string;
email: string;
}
export type Api = {
'/api/users/:id': {
GET: {
query: never;
request: never;
responses: {
200: GetApiUsersByIdResponse;
};
};
};
'/api/users': {
POST: {
query: never;
request: never;
responses: {
200: PostApiUsersResponse;
};
};
};
};
// Utility types for type-safe API consumption
export type ApiPaths = '/api/users/:id' | '/api/users';
export type ApiAvailableMethods<T extends ApiPaths> = // ...
// ... more utility types
Success! You've generated your first type-safe API definitions. These types can now be imported and used in your frontend or API clients.
Using Generated Types
Now you can use these types in your client code:
import type { ApiResponsesByStatus, ApiPaths } from '../types/api-types';
// Type-safe API client
async function getUser(id: string) {
type UserResponse = ApiResponsesByStatus<'/api/users/:id', 'GET', '200'>;
const response = await fetch(`/api/users/${id}`);
const data: UserResponse = await response.json();
return data; // Fully typed: { id: string; name: string; email: string }
}
Development Workflow
For the best development experience, run Apinni in watch mode:
- npm
- Yarn
- pnpm
npm run types:watch
yarn types:watch
pnpm types:watch
This will automatically regenerate types whenever you modify your controllers.
Run types:watch alongside your development server for instant type updates as you code.
Configuration Options
Customize Apinni's behavior in your config file:
import type { ApinniConfig } from '@apinni/client-ts';
export default {
// Output directory for generated types
outputPath: './types',
// Glob patterns for files to include
includePatterns: ['src/**/*.controller.ts'],
// Glob patterns for files to exclude
excludePatterns: ['**/*.spec.ts', '**/*.test.ts'],
// Plugins to extend functionality
plugins: [],
} satisfies ApinniConfig;
| Option | Type | Description |
|---|---|---|
outputPath | string | Directory where type files will be generated (default: ./types) |
includePatterns | string[] | Glob patterns for files to process |
excludePatterns | string[] | Glob patterns for files to ignore |
plugins | PluginTypes[] | Array of plugins to extend Apinni's functionality |
Troubleshooting
Types Not Generated
Problem: Running apinni generate doesn't create any files.
Solutions:
- Verify
experimentalDecoratorsandemitDecoratorMetadataare enabled intsconfig.json - Check that your controllers use
@ApinniControllerdecorator - Ensure your files match the
includePatternsin your config - Look for compilation errors in your TypeScript code
Decorator Errors
Problem: Errors about decorators not being found.
Solutions:
- Verify Apinni is installed:
npm list @apinni/client-ts - Check imports:
import { ApinniController } from '@apinni/client-ts' - Avoid named imports with aliases (use the exact decorator names)
- Ensure
reflect-metadatais imported if using runtime decorators
Types Generated in Wrong Directory
Problem: Generated files appear in an unexpected location.
Solutions:
- Check the
outputPathin yourapinni.config.ts - Use absolute paths or paths relative to your project root
- Verify you're running the command from your project root
For more detailed troubleshooting, see the CLI documentation or join our community.
Next Steps
Now that you have Apinni set up, explore more features:
Learn the Core Concepts
- ApinniController - Define base paths for your endpoints
- ApinniEndpoint - Configure individual endpoints
- ApinniDomain - Organize endpoints into domains
- ApinniDisabled - Exclude endpoints from generation
Integrate with Your Stack
- Backend Integration - Use with Express, NestJS, Fastify
- Frontend Integration - Consume types in React, Vue, Angular
- Utility Types - Master the generated utility types
Extend Functionality
- Plugins Overview - Learn about the plugin system
- Creating Plugins - Build custom plugins