-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Migrating to TypeSpec
This guide helps service teams migrate their JavaScript SDK generation from OpenAPI specifications and AutoRest to TypeSpec. The migration process involves updating how your SDK is generated, but should not result in breaking changes to the public API surface of your SDK.
We expect to complete this guide by end of August 2025. While this guide is being written, feel free to reach out to Maor Leger for support.
This guide is written for service teams who are migrating a high-level client (i.e. a client library with a hand-authored convenience layer) from OpenAPI to TypeSpec.
TypeSpec is Microsoft's new API specification language that provides better tooling, type safety, and developer experience compared to OpenAPI specifications. When you migrate from AutoRest to TypeSpec:
- Your public SDK API should remain the same - this is not a breaking change for your customers
- The generation process changes - you'll use TypeSpec definitions instead of OpenAPI/Swagger files
- Build scripts and configuration update - new tooling replaces AutoRest
- Internal generated code structure changes - but your hand-written client code adapts with minimal changes
Before starting the migration, ensure you have:
- TypeSpec definitions ready: Your service's TypeSpec definitions should be complete and merged into the main branch of the Azure REST API specs repository
-
Local development environment:
- Node.js LTS version
- Local clone of your fork of azure-sdk-for-js
- Local clone of your fork of azure-rest-api-specs
- Understanding of your current SDK: Know which packages in azure-sdk-for-js belong to your service
Install the TypeSpec client generator CLI globally:
npm install -g @azure-tools/[email protected]
For more information on tsp-client, see the TypeSpec Client Generator CLI documentation
In your package directory (e.g., sdk/your-service/your-package
), add the tsp-location.yaml
file that points to your TypeSpec definitions in the azure-rest-api-specs repository.
An example tsp-location.yaml
file looks like this:
directory: specification/ai/Azure.AI.Projects
commit: a720ec94da68a0d77a691ddd563a4528883638ee
repo: Azure/azure-rest-api-specs
After initialization, your package will have a new structure:
sdk/your-service/your-package/
├── src/
│ ├── generated/
│ │ ├── src/ # Generated TypeScript code
│ │ │ ├── api/
│ │ │ ├── models/
│ │ │ ├── index.ts
│ │ │ └── yourServiceClient.ts
│ │ └── tsp-location.yaml
│ ├── index.ts # Your public exports
│ ├── yourClient.ts # Your hand-written client code
│ └── ... # Other hand-written files
├── package.json
└── ...
Key differences from AutoRest:
- Generated code is now in
src/generated/src/
instead ofsrc/generated/
- The
tsp-location.yaml
file replaces previous AutoRest configuration - Generated models and client interfaces follow TypeScript conventions
You'll need to update your hand-written client code to import from the new generated structure:
Before (AutoRest):
import { YourServiceClient } from "./generated/yourServiceClient.js";
import { SomeModel } from "./generated/models/index.js";
After (TypeSpec):
import { YourServiceClient } from "./generated/src/yourServiceClient.js";
import { SomeModel } from "./generated/src/models/index.js";
Replace your AutoRest generation script with a TypeSpec generation script:
Before (AutoRest):
{
"scripts": {
"generate": "autorest --typescript swagger/README.md"
}
}
After (TypeSpec):
{
"scripts": {
"generate:client": "tsp-client update -d -o src/generated --emitter-options=\"generate-metadata=false;generate-test=false\""
}
}
The emitter options disable metadata and test generation for HLCs.
skipping metadata generation in tspconfig.yaml must be passed in the command line and not in the
tspconfig.yaml
file. This is tracked in https://github.com/Azure/azure-rest-api-specs/issues/31610
Delete the following files that are no longer needed:
-
swagger/README.md
(or similar AutoRest configuration) - Any custom AutoRest configuration files
- Generated files from the old structure (they'll be regenerated in the new location)
-
Generate the code:
cd sdk/your-service/your-package npm run generate:client
-
Install dependencies:
rush update
-
Build the package:
rush build -t .
-
Run tests:
rushx test
-
Validate the API surface: Use API Extractor to ensure your public API hasn't changed unexpectedly.
If the generated code doesn't exactly match your needs, you may need to:
- Update your TypeSpec definitions in azure-rest-api-specs
-
Use emitter customizations in your
tspconfig.yaml
- Apply post-generation transformations (though this should be rare)
All imports from generated code need to be updated to include the /src
path segment:
// Old
import { Client } from "./generated/client.js";
// New
import { Client } from "./generated/src/client.js";
TypeSpec may generate slightly different model names or structures. Review the generated models/
directory and update your code accordingly.
The generated client constructor may have different parameter names or types. Compare the old and new generated client interfaces.
- Replace
@azure/core-client
with@azure-rest/core-client
in yourpackage.json
- Migrate
@azure/[email protected]
to@azure-rest/[email protected]
following the migration guide
If the generated models do not match convenience / hand-authored models, you may need to adjust your code to accommodate the new structures.
See mapPagedAsyncIterable as an example of a function that can be used to map generated models to your expected structures.
- Never modify files in
src/generated/
- they will be overwritten - Keep all customizations in your hand-written client files
- Use TypeScript interfaces and type assertions to bridge any gaps
- Update your package version according to Azure SDK versioning guidelines
- Add changelog entries describing the migration (usually marked as internal changes)
- Coordinate with the Azure SDK team for any breaking changes
- Ensure all existing tests pass after migration
- Add tests for any new functionality exposed by TypeSpec
- Consider adding integration tests to validate against live services
Problem: Cannot find generated types after migration.
Solution: Check that imports point to ./generated/src/
instead of ./generated/
.
Problem: TypeScript compilation errors after migration.
Solution: Run rush update
to ensure dependencies are installed, then check import statements.
Problem: Generated API doesn't match expectations.
Solution: Review your TypeSpec definitions and ensure they're complete. Check emitter options in tspconfig.yaml
.
Problem: npm run generate:client
fails.
Solution: Ensure @azure-tools/typespec-client-generator-cli
is installed globally and tsp-location.yaml
exists.
If you encounter issues during migration:
-
Check existing documentation:
-
Consult with the team:
- Post in the TypeSpec Discussion Teams channel
- Tag
@DPG TypeScript
for JavaScript/TypeScript-specific questions
-
File issues: