Protobuf to Angular Client Generator
@metaengine/protobuf-angularConvert Protobuf 3 to Angular gRPC-Web services and message types with inject() DI, interceptors, gRPC-native error handling, and the new Angular 22 @Service() decorator. Idiomatic Angular 19+ over the Connect protocol.
Pick your registry
The same generator, published to every ecosystem we support. Install however your project expects.
Drive it from the CLI or programmatically
npm ships a zero-config CLI. NuGet ships the same generator as a C# fluent API — same options, same output.
After install, point the CLI at your schema. It writes the generated tree to your chosen output directory.
npx @metaengine/protobuf-angular <input> <output> [options]Generates Angular gRPC-Web services and message types from Protobuf 3 .proto files.
npx @metaengine/protobuf-angular service.proto ./src/app/apinpx @metaengine/protobuf-angular service.proto ./src/app/api \
--provided-in root \
--inject-function \
--error-handling \
--documentationnpx @metaengine/protobuf-angular service.proto ./src/app/api \
--service-decorator \
--documentationnpx @metaengine/protobuf-angular service.proto ./src/app/api \
--bearer-auth API_TOKEN \
--timeout 30 \
--error-handlingEvery knob, documented
Every option is available on the C# fluent API as a method, and most are also exposed as CLI flags. Cross-cutting auth, headers, retries and timeouts apply across frameworks.
Angular Options
7WithBaseUrlToken(string)Injection token name for base URL (default: "BASE_URL")WithInjectFunction()Use inject() instead of constructor DI (Angular 14+)WithProvidedIn(string)Injection scope ("root", "platform", "any")WithServiceDecorator()Emit the Angular 22 @Service() decorator instead of @Injectable — a root-provided singleton that auto-enables inject() DI (mutually exclusive with WithProvidedIn, last wins)WithServiceDecorator(x => x.ComponentScoped())Angular 22 @Service({ autoProvided: false }) — a manually-provided, component/route-scoped serviceWithInterceptors()Generate interceptor infrastructure (ApiMiddleware type + provideApiInterceptors factory) so auth / headers live in interceptorsWithResponseDateTransformation()Convert google.protobuf.Timestamp fields in responses to Date objects
Auth · Headers · Resilience
9WithErrorHandling()Enable gRPC-native error handling keyed on gRPC status codes (NOT_FOUND / PERMISSION_DENIED → null · INVALID_ARGUMENT / FAILED_PRECONDITION → error body · UNAUTHENTICATED / INTERNAL / UNAVAILABLE → throw)WithErrorHandling(grpc => grpc...)Tune the gRPC taxonomy: ReturnNullForCodes(...) · ReturnErrorForCodes(...) · ThrowForCodes(...) · MapGrpcCode(code, behavior). Overrides merge on top of the defaultsWithBearerAuth()Bearer token from env var (default API_TOKEN) — adds Authorization headerWithBearerAuth(string)Bearer token from a specific env var nameWithBearerAuth(string, string)Bearer token with custom header nameWithBasicAuth(string, string)HTTP Basic auth from username + password env varsWithCustomHeader(string, string)Static header from env var. Repeatable (e.g. X-Tenant-ID ← TENANT_ID)WithTimeout(double)Request timeout in seconds, emitted as a grpc-timeout header on every callWithTimeout(double?, double?, double?, double?)Granular timeout: connect · read · write · pool
Protobuf Options
5WithDocumentation()Generate JSDoc comments from .proto field and service descriptionsWithTypeFilter(Func)Filter extracted proto types before registration — only types returning true are generatedWithTypeMapping(string, Type)Override the TS mapping for a protobuf well-known type by fully-qualified name (e.g. google.protobuf.Timestamp → string)WithMethodNames(Func)Custom method naming ruleWithOptionsObjectThreshold(int)Parameter count for options object (default: 4)
TypeScript Output
1WithTypesBarrel()Emit an index.ts barrel per folder plus a root index.ts re-exporting everything
Naming Transformations
3Types(Func)Transform type namesPaths(Func)Transform output pathsFileNames(Func)Transform file names
File Management
5CleanDestination()Clean output directory before generationAlwaysOverwrite()Always overwrite existing filesOnlyWhenModelChanged()Update only when model changesOnlyWhenNew()Write only new files, preserve existingCleanDirectories(...)Clean specific subdirectories
Diagnostics
2Verbose()Enable verbose loggingWithLogger(Action<string>)Route generation log output to a custom sink