Skip to content

Client Options

This page documents how to use the @clientOption decorator to pass language-specific configuration options to emitters. For an overview of the setup, please visit the setup page.

The @clientOption decorator allows spec authors to pass arbitrary key-value options to specific language emitters. This enables fine-grained control over code generation behavior that may vary between languages.

@clientOption(name: string, value: unknown, scope?: string)
ParameterTypeDescription
namestringThe name of the option to set
valueunknownThe option value. Primitive, array, object, and nested values are supported; the consuming emitter determines the expected shape.
scopestring (syntax optional)The target language scope. Every use must provide an explicit scope; omitting it produces a decorator-requires-scope warning.

The declaration keeps scope syntactically optional so TCGC can report a targeted diagnostic for legacy unscoped uses. New and updated specifications must always provide it.

Apply the decorator to models, operations, enums, properties, namespaces, or interfaces with a language-specific scope:

client.tsp
import "@azure-tools/typespec-client-generator-core";
using Azure.ClientGenerator.Core;
#suppress "@azure-tools/typespec-client-generator-core/client-option"
@clientOption("enableFeatureFoo", true, "python")
model MyModel {
id: string;
}
# The Python emitter can read this option from the model's decorators array
# and apply the appropriate code generation behavior

You can apply multiple @clientOption decorators to the same target:

client.tsp
#suppress "@azure-tools/typespec-client-generator-core/client-option"
@clientOption("enableFeatureFoo", true, "python")
@clientOption("customSerializerMode", "strict", "python")
model MyModel {
id: string;
}

The decorator supports arbitrary values, including primitives, arrays, objects, and nested combinations:

client.tsp
#suppress "@azure-tools/typespec-client-generator-core/client-option"
@clientOption("booleanOption", true, "python")
model BoolExample {
id: string;
}
#suppress "@azure-tools/typespec-client-generator-core/client-option"
@clientOption("stringOption", "customValue", "csharp")
model StringExample {
id: string;
}
#suppress "@azure-tools/typespec-client-generator-core/client-option"
@clientOption("numericOption", 42, "java")
model NumericExample {
id: string;
}
#suppress "@azure-tools/typespec-client-generator-core/client-option"
@clientOption("structuredOption", #{ mode: "strict", retries: #[1, 2, 3] }, "python")
model StructuredExample {
id: string;
}

TCGC provides the getClientOptions helper function to extract an option by name from any decorated SDK type.

Section titled “Using the getClientOptions Helper (Recommended)”
import { getClientOptions } from "@azure-tools/typespec-client-generator-core";
// Get one client option from a model
const sdkModel = context.sdkPackage.models.find((m) => m.name === "MyModel");
const enableFeatureFoo = getClientOptions(sdkModel, "enableFeatureFoo");
if (enableFeatureFoo === true) {
// Generate the feature supported by this emitter.
}

The function returns the option value as unknown, or undefined when the named option isn’t present. Narrow or validate the value before using it, then call it once for each option key your emitter supports.

The helper works with any decorated SDK type:

// Models
const modelOption = getClientOptions(sdkModel, "enableFeatureFoo");
// Enums
const enumOption = getClientOptions(sdkEnum, "enableFeatureFoo");
// Operations/Methods
const methodOption = getClientOptions(sdkMethod, "enableFeatureFoo");
// Properties
const propertyOption = getClientOptions(sdkProperty, "enableFeatureFoo");
// Clients
const clientOption = getClientOptions(sdkClient, "enableFeatureFoo");

If you need more control, you can also filter the decorators array directly:

const sdkModel = context.sdkPackage.models.find((m) => m.name === "MyModel");
const clientOptionDecorators = sdkModel.decorators.filter(
(d) => d.name === "Azure.ClientGenerator.Core.@clientOption",
);
for (const decorator of clientOptionDecorators) {
const optionName = decorator.arguments.name; // e.g., "enableFeatureFoo"
const optionValue = decorator.arguments.value; // e.g., true
const scope = decorator.arguments.scope; // e.g., "python"
}
Option NameValue TypeTargetLanguagesDescription
omitSlashFromEmptyRoutebooleanOperation, Interface, NamespaceAllWhen true, operations with empty routes (path "/") will use "" instead. Only affects empty routes.
#suppress "@azure-tools/typespec-client-generator-core/client-option" "legacy storage usage"
@clientOption("omitSlashFromEmptyRoute", true, "python")
@put
op createBlob(): void;
  1. Always specify a scope: The decorator is designed for language-specific behavior. Omitting the scope produces an additional warning.

  2. Suppress the warning intentionally: Use #suppress "@azure-tools/typespec-client-generator-core/client-option" to acknowledge that you’re using this advanced feature.

  3. Document usage: When using client options, document why they’re needed so future maintainers understand the intent.

  4. Prefer standard decorators: Use standard TCGC decorators like @clientName, @access, @usage, etc. when they can achieve the desired behavior. Reserve @clientOption for cases where no standard decorator exists.

  5. Coordinate with emitter teams: Before using a client option, verify with the target language emitter team that the option is supported and understand its behavior.