This page covers all automated code generation steps used across the Immich repository: how the OpenAPI specification is produced from server source code, how client SDKs are generated from that spec, how SQL query files are generated from repository code, and how the Flutter mobile app uses build_runner to generate routing, database, state management, and i18n code.
For a description of how the generated TypeScript and Dart SDKs are used at runtime by clients, see API and SDK Generation. For the i18n system's runtime behavior on web and mobile, see Internationalization.
All generated artifacts in this repository follow one of two patterns:
Code Generation Pipeline
Sources: server/package.json32-33 open-api/typescript-sdk/src/fetch-client.ts1-6 mobile/openapi/README.md1-8 server/src/queries/sync.repository.sql1 mobile/pubspec.yaml90-116
The OpenAPI spec is generated by running the NestJS application in a special mode that introspects all registered modules and emits a JSON document.
| Decorator | Package | Purpose |
|---|---|---|
@ApiTags() | @nestjs/swagger | Groups endpoints in the spec |
@ApiOperation() | @nestjs/swagger | Documents endpoint summary and description |
@ApiProperty() | @nestjs/swagger | Documents DTO fields and types |
@ExtraModel() | src/dtos/sync.dto.ts | Registers models not directly in a controller return type |
The @ExtraModel() decorator is defined in server/src/dtos/sync.dto.ts54-58 and applied to sync DTO classes like SyncUserV1, SyncAssetV1, SyncPartnerV1, etc. These classes appear as discriminated union members in the sync stream response and would otherwise be omitted from the spec's components/schemas section.
pnpm run sync:open-api
# runs: node ./dist/bin/sync-open-api.js
The output is written to open-api/immich-openapi-specs.json. This file is committed to the repository and is the single authoritative source for all SDK generation.
Sources: server/package.json32 server/src/dtos/sync.dto.ts52-59 open-api/immich-openapi-specs.json1-10
The TypeScript SDK is published as the @immich/sdk workspace package located at open-api/typescript-sdk/.
oazapfts reads open-api/immich-openapi-specs.json and generates typed fetch wrappers. The primary output file is open-api/typescript-sdk/src/fetch-client.ts, which carries the header:
DO NOT MODIFY - This file has been generated using oazapfts.
The file exports:
AssetResponseDto, AlbumResponseDto)getAssetInfo(), createAlbum())defaults object with base URL /api| Field | Value |
|---|---|
| Package name | @immich/sdk |
| Main entry | ./build/index.js |
| Types entry | ./build/index.d.ts |
| Build command | tsc |
| Runtime dependency | @oazapfts/runtime |
The @immich/sdk package is referenced as a workspace:* dependency in:
web/package.json — SvelteKit web applicationcli/package.json — @immich/cli command-line toole2e/package.json — end-to-end test suiteSDK Consumer Relationships
Sources: open-api/typescript-sdk/package.json open-api/typescript-sdk/src/fetch-client.ts1-16 web/package.json29 cli/package.json17 e2e/package.json32
The Dart SDK is generated into mobile/openapi/ and is consumed by the Flutter app as a local path dependency.
| Property | Value |
|---|---|
| Tool | OpenAPI Generator |
| Generator version | 7.8.0 |
| Build package | org.openapitools.codegen.languages.DartClientCodegen |
| Target Dart version | ≥ 2.12 |
The generator reads open-api/immich-openapi-specs.json and produces a complete Dart library under mobile/openapi/.
The entry point mobile/openapi/lib/api.dart is marked AUTO-GENERATED FILE, DO NOT MODIFY! and assembles the library using part directives:
| Directory | Contents |
|---|---|
mobile/openapi/lib/api/ | One file per API tag (e.g., assets_api.dart, albums_api.dart) |
mobile/openapi/lib/model/ | One file per schema (e.g., asset_response_dto.dart, sync_entity_type.dart) |
mobile/openapi/lib/auth/ | Authentication helper classes |
mobile/openapi/lib/api_client.dart | ApiClient class — HTTP dispatch and serialization |
mobile/openapi/lib/api_helper.dart | QueryParam and parameterToString utilities |
The ApiClient class in mobile/openapi/lib/api_client.dart13-165 handles HTTP method dispatch, multipart uploads, and JSON deserialization. The fromJson static method contains a large switch statement that maps string type names to fromJson() constructors for each generated model class.
The openapi package is referenced in mobile/pubspec.yaml63-64:
The analyzer section excludes the generated directory from static analysis mobile/pubspec.yaml159-162:
Dart SDK Structure
Sources: mobile/openapi/README.md mobile/openapi/lib/api.dart mobile/openapi/lib/api_client.dart13-50 mobile/pubspec.yaml63-64 mobile/pubspec.yaml159-162
Repository query methods use a custom @GenerateSql decorator to produce formatted SQL files. These files document the exact SQL that Kysely will emit at runtime.
The @GenerateSql decorator is imported from src/decorators and applied to repository methods. It accepts a params array of dummy argument objects and an optional stream flag.
Example from server/src/repositories/sync.repository.ts142-152:
The dummy parameter constants (e.g., dummyCreateAfterOptions, dummyQueryOptions) use DummyValue.UUID placeholders so that the generator can call each method and let Kysely compile the query to SQL.
pnpm run sync:sql
# runs: node ./dist/bin/sync-sql.js
SQL files are written to server/src/queries/. Each file corresponds to one repository class and begins with:
-- NOTE: This file is auto generated by ./sql-generator
Each query is preceded by a comment naming it RepositoryClass.subclass.methodName. Example from server/src/queries/sync.repository.sql1-15:
These SQL files are committed to the repository and serve as a readable audit of all database queries without executing the application.
SQL Generation Flow
Sources: server/package.json33 server/src/repositories/sync.repository.ts142-155 server/src/queries/sync.repository.sql1-15
The Flutter mobile app uses build_runner to orchestrate multiple Dart code generators. All generators are listed as dev_dependencies in mobile/pubspec.yaml90-116
| Generator Package | Annotation / Input | Output |
|---|---|---|
drift_dev | Drift table schema classes | Type-safe database access code |
riverpod_generator | @riverpod function annotations | AsyncNotifier, Provider subclasses |
auto_route_generator | @AutoRouterAnnotation, @RoutePage | AppRouter and route guard classes |
isar_generator | @Collection Isar schema classes | IsarCollection<T> access methods |
pigeon | Pigeon message definition files | Platform channel Swift/Kotlin + Dart stubs |
All generators are run via:
flutter pub run build_runner build
or in watch mode:
flutter pub run build_runner watch
build_runner discovers all generators registered in pubspec.yaml and processes annotated source files in dependency order. Generated files are written alongside their source files with a .g.dart or .freezed.dart suffix, depending on the generator.
The mobile app uses easy_localization with code generation to produce a type-safe LocaleKeys class from the en.json translation source file. This class provides compile-time string constants for every translation key, preventing typos in key names. For details on the i18n system and the en.json format, see Internationalization.
Mobile build_runner Generator Map
Sources: mobile/pubspec.yaml90-116
| Artifact | Source | Tool | Output Location | Consumers |
|---|---|---|---|---|
immich-openapi-specs.json | NestJS controllers + DTOs | sync-open-api.js | open-api/ | oazapfts, openapi-generator |
@immich/sdk (fetch-client.ts) | immich-openapi-specs.json | oazapfts | open-api/typescript-sdk/ | web, CLI, e2e |
Dart openapi package | immich-openapi-specs.json | openapi-generator v7.8.0 | mobile/openapi/ | Flutter app |
*.sql query files | @GenerateSql-annotated repository methods | sync-sql.js | server/src/queries/ | Audit / review |
| Drift DB code | Drift table schema .dart | drift_dev | alongside source | Flutter app |
| Riverpod providers | @riverpod annotations | riverpod_generator | alongside source | Flutter app |
| Auto-route router | @RoutePage annotations | auto_route_generator | alongside source | Flutter app |
| Isar collections | @Collection annotations | isar_generator | alongside source | Flutter app |
| Platform channels | Pigeon definitions | pigeon | alongside source | Flutter app |
LocaleKeys | en.json | easy_localization codegen | alongside source | Flutter app |
Sources: server/package.json32-33 open-api/typescript-sdk/package.json mobile/openapi/README.md1-8 mobile/pubspec.yaml90-116 server/src/queries/sync.repository.sql1
Refresh this wiki
This wiki was recently refreshed. Please wait 2 days to refresh again.