---
slug: release-notes/typespec-0-67
title: "0.67"
releaseDate: 2025-03-18
version: "0.67"
---

:::caution
This release contains breaking changes. This is the last release before 1.0-rc.0 which was focused on cleaning up deprecated features and APIs.
:::

## Notable changes

### `tsp install` now download and use the configured package manager

In order to detach typespec from any specific package manager, `tsp install` now uses the package manager configured in `packageManager` or `devEngines.packageManager` field of `package.json`. If the field is not present, it defaults to `npm` latest version but will log a warning.

```json title="package.json"
{
  // Use npm 11.2.0 with sha512 checksum verification
  "packageManager": "npm@11.2.0+sha512.3dc9c50ba813a3d54393155a435fe66404b72685ab0e3008f9ae9ed8d81f6104860f07ed2656dd5748c1322d95f3140fa9b19c59a6bba7750fd12285f81866da",
  // Use npm 11.2.0 but skip integrity check
  "packageManager": "npm@11.2.0"
}
```

The field can be automatically set by running `tsp install --save-package-manager`

## Breaking Changes

### All packages

- [#5977](https://github.com/microsoft/typespec/pull/5977) Minimum node version is now 20

### @typespec/compiler

- [#6231](https://github.com/microsoft/typespec/pull/6231) Remove deprecated items:
  - `@deprecated` decorator, use `#deprecated` directive instead

    ```diff lang=tsp
    - @deprecated("Message")
    + #deprecated "Message"
    ```

  - `@service` `versions` support. Either migrate to `@OpenAPI.info` or the versioning library

    ```diff lang=tsp
    - @service({version: "1.0"})
    + @service
    + @OpenAPI.info(#{version: "1.0"})
    ```

  - Removed `@knownValues`. Use a union with a string variant instead

    ```diff lang=tsp
    - enum MyKnownValues {a, b}
    - @knownValues(MyKnownValues)
    - scalar Custom extends string;
    + union Custom {
    +   "a", "b", string
    + };
    ```

  - Removed `@projectedName` Migrate to `@encodedName` instead.

    ```diff lang=tsp
    - @projectedName("json", "nbf")
    + @encodedName("application/json", "nbf")
    notBefore: int32;
    ```

  - CLI configuration value `output-path`, use `output-dir` instead.

  - Support for `cadlMain` in `package.json`. Migrate to `exports["."].tsp` instead.

    ```diff lang=json
    - "cadlMain": "lib/main.tsp",
    + "exports": {
    +   ".": {
    +     "tsp": "lib/main.tsp"
    +   }
    + }
    ```

  - Compiling `.cadl` files, use `.tsp` instead.

  - `decoratorArgMarshalling` flag in `$flags` was removed and support for the `legacy` decorator arg marshalling.

  - Using `@format` on bytes. `@format` can only be used on string where it defines a known pattern for the string.

  - Javascript functions and typescript types:
    - `stringTemplateToString`
    - `CadlLanguageConfiguration`
    - `CadlPrettierPlugin`
    - `NodePackage` -> `PackageJson`
    - `CadlValue` -> `TypeSpecValue`
    - `createCadlLibrary` -> `createTypeSpecLibrary`
    - `setCadlNamespace` -> `setTypeSpecNamespace`
    - `CadlLibrary` -> `TypeSpecLibrary`
    - `SyntaxKind.CadlScript` -> `SyntaxKind.TypeSpecScript`
    - `isCadlValueTypeOf` -> `isTypeSpecValueTypeOf`
    - `cadlTypeToJson` -> `typespecTypeToJson`
    - `checkFormatCadl` -> `checkFormatTypeSpec`
    - `cadlVersion` -> `typespecVersion`
    - `CadlManifest` -> `TypeSpecManifest`
    - `validateDecoratorTargetIntrinsic` -> Use `extern dec` to define the signature of decorators instead
    - `validateDecoratorParamType` -> Use `extern dec` to define the signature of decorators instead
    - `createDecoratorDefinition` -> Use `extern dec` to define the signature of decorators instead
    - `CompilerOptions#emitters` -> Use `emit` and `options` field instead.
      ```diff lang=ts
      - emitters: { "my-emitter": options },
      + emit: ["my-emitter"],
      + options: { "my-emitter": options },
      ```
    - `Type#templateArguments` -> Use `templateMapper` instead.
    - `ModelProperty#default` -> Use `defaultValue` instead.
    - `Union#options` -> Use `variants` instead.
    - `linter` in `createTypeSpecLibrary` -> Use `export const $linter = defineLinter({ ... })` instead.
    - Accessor for removed `@knownValues` decorator
      - `getKnownValues`
    - Accessor for removed `@projectedName` decorator
      - `getProjectedNames`
      - `getProjectedName`
      - `hasProjectedName`

- [#6323](https://github.com/microsoft/typespec/pull/6323) Move AST related APIS to `@typespec/compiler/ast` package. This is to mark a clear separation for the AST types and APIs which are considered for advanced usage and might change at any time.
  - All `*Node` types
  - `exprIsBareIdentifier`
  - `getFirstAncestor`
  - `getIdentifierContext`
  - `getNodeAtPosition`
  - `getNodeAtPositionDetail`
  - `hasParseError`
  - `isImportStatement`
  - `parse`
  - `parseStandaloneTypeReference`
  - `positionInRange`
  - `visitChildren`
- [#6323](https://github.com/microsoft/typespec/pull/6323) Stop exposing APIs that were not meant for external users. Please file issue if you had legitmate use of some of those APIs.
  - `Checker`: The check itself should be used very carefully and its wouldn't be covered under the compatibility guarantees. There is some apis that were explicitly marked as internal while other remained until we provide a better way to do the same thing:
    - `getGlobalNamespaceType();` -> `program.getGlobalNamespaceType();`
    - `resolveTypeReference();` -> `program.resolveTypeReference();`
    - `checkProgram();` This isn't meant to be used by external users.
    - `getLiteralType()` This isn't meant to be used by external users.
    - `resolveRelatedSymbols()` This isn't meant to be used by external users.
    - `resolveCompletions()` This isn't meant to be used by external users.

  - `Program`: Exposed functions on the program are safe to use but a few have been updated to be internal:
    - `mainFile` -> Use `projectRoot` instead.
    - `literalTypes` This isn't meant to be used by external users.
    - `checker`: This is still exposed but to be used carefully, see above.
    - `loadTypeSpecScript`: This isn't meant to be used by external users.
    - `onValidate`: This isn't meant to be used by external users.
    - `reportDuplicateSymbols`: This isn't meant to be used by external users.

  - `logVerboseTestOutput` Internal test util, not meant for external users
  - `validateDecoratorTarget` -> migrate to `extern dec` declaration
  - `validateDecoratorParamCount`: Same as above
  - `altDirectorySeparator`: Internal path utils
  - `directorySeparator`: Internal path utils
  - `isIntrinsicType`: Internal check
  - `getFullyQualifiedSymbolName` Symbols are an internal aspect of the compiler
  - Scanner related APIs:
    - `createScanner`
    - `isComment`
    - `isKeyword`
    - `isModifier`
    - `isPunctuation`
    - `isStatementKeyword`
    - `isTrivia`
    - `skipContinuousIdentifier`
    - `skipTrivia`
    - `skipTriviaBackward`
    - `skipWhiteSpace`
    - `Token`
    - `TokenFlags`
    - `type`DocToken,
    - `type`Scanner,
    - `type`StringTemplateToken,
  - Types
    - `Sym` Symbols are an internal aspect of the compiler
    - `SymbolLinks` Symbols are an internal aspect of the compiler
    - `SymbolTable` Symbols are an internal aspect of the compiler
    - `SymbolFlags` Symbols are an internal aspect of the compiler
    - `MutableSymbolTable` Symbols are an internal aspect of the compiler
    - `ResolutionResult` Internal type used in non exposed resolver
    - `NodeLinks` Internal type used in non exposed resolver
    - `ResolutionResultFlags` Internal type used in non exposed resolver
    - `MetaMemberKey` Unused type
    - `MetaMembersTable` Unused type
    - `Dirent` Unused type

- [#6410](https://github.com/microsoft/typespec/pull/6410) Remove a legacy behavior of resolving package names which wasn't inline with node ESM module resolution.

  For example if you were running tsp compile within your node_modules folder(on a test package) and referencing your emitter by name you might need to change this

  ```diff lang=bash
  -tsp compile . --emit my-emitter
  +tsp compile . ../../  # path to your emitter root instead
  ```

- [#6286](https://github.com/microsoft/typespec/pull/6286) Removed deprecated use of `@discriminator` on union. Migrate to `@discriminated`

  ```diff lang="tsp"
  -@discriminator("type")
  +@discriminated(#{envelope: "none", discriminatorPropertyName: "type"})
  union Pet;
  ```

- [#6327](https://github.com/microsoft/typespec/pull/6327) Remove projection. Projection was an experiemental syntax that was too flawed to be included in 1.0 in that current state.
- [#6388](https://github.com/microsoft/typespec/pull/6388) Remove deprecated type to value conversion. Since the introductions of object values(`#{}`) and array values(`#[]`) using model expressions or tuple where values were expected has been deprecated. It is now an error with a codefix.

  ```diff lang="tsp"
  -@service({title: "My service"})
  +@service(#{title: "My service"})
  ```

- [#6416](https://github.com/microsoft/typespec/pull/6416) Adding new keywords for future use:
  - `statemachine`
  - `macro`
  - `package`
  - `metadata`
  - `env`
  - `arg`
  - `declare`
  - `array`
  - `struct`
  - `record`
  - `module`
  - `mod`
  - `pub`
  - `sub`
  - `typeref`
  - `trait`
  - `this`
  - `self`
  - `super`
  - `keyof`
  - `with`
  - `implements`
  - `impl`
  - `satisfies`
  - `flag`
  - `auto`
  - `partial`
  - `private`
  - `public`
  - `protected`
  - `internal`
  - `sealed`
  - `local`
  - `async`
- [#6258](https://github.com/microsoft/typespec/pull/6258) Removed deprecated legacy visibility APIs and converted all warnings for using string-based visibility modifiers to errors.

  The removed APIs include:
  - `getVisibility`: use `getVisibilityForClass` instead.
  - `getParameterVisibility`: use `getParameterVisibilityFilter` instead.
  - `getReturnTypeVisibility`: use `getReturnTypeVisibilityFilter` instead.

  Furthermore, the legacy signature of `isVisible` that accepts an array of strings has been removed. Please use the new signature that accepts `EnumMember` instead.

  The changed decorators include:
  - `@visibility`
  - `@parameterVisibility`
  - `@returnTypeVisibility`
  - `@withVisibility`
  - `@withDefaultKeyVisibility`

  The `TypeSpec.DefaultKeyVisibility` template also no longer accepts a string as a visibility modifier argument.

  Attempting to pass a string to any of the above decorators or templates will now result in a type-checking error. Please use the `Lifecycle` visibility modifiers instead.

  If you develop a third-party library and you use any custom visibility modifiers, you will need to instead define a visibility class enum. See: [Visibility | TypeSpec](https://typespec.io/docs/language-basics/visibility/).

  **Migration steps**:

  String-based visibilities can be replaced as follows:
  - `"create"`, `"read"`, `"update"`, `"delete"`, and `"query"` can be replaced with `Lifecycle.Create`, `Lifecycle.Read`, `Lifecycle.Update`, `Lifecycle.Delete`, and `Lifecycle.Query` respectively.
  - `@visibility("none")` can be replaced with `@invisible(Lifecycle)`.

  For example:

  ```tsp
  @visibility("create", "read")
  example: string;
  ```

  can be replaced with:

  ```tsp
  @visibility(Lifecycle.Create, Lifecycle.Read)
  example: string;
  ```

  ```tsp
  @visibility("none")
  example: string;
  ```

  can be replaced with:

  ```tsp
  @invisible(Lifecycle)
  example: string;
  ```

  Additionally, `@parameterVisibility` with no arguments has been made an error. Previously, some specifications used it to disable effective PATCH optionality, but that behavior was an unintended side effect. For example:

  ```tsp
  @parameterVisibility
  @patch
  op example(@bodyRoot resource: Resource): Resource;
  ```

  If you wish to disable effective PATCH optionality in `@typespec/http`, preventing it from treating all properties of the request body as effectively optional, you can now do so explicitly:

  ```tsp
  @patch(#{ implicitOptionality: false })
  op example(@bodyRoot resource: Resource): Resource;
  ```

### @typespec/http

- [#6387](https://github.com/microsoft/typespec/pull/6387) Removing deprecated items

- `isContentTypeHeader`
- `setLegacyStatusCodeState`

Moved to internal

- `setStatusCode`
- [#6305](https://github.com/microsoft/typespec/pull/6305) Remove deprecated items:

- `format` option from `@header` and `@query` decorators. Use `explode` option instead.

  ```diff
  -@header(#{ format: "multi"})
  -@query(#{ format: "multi"})
  +@header(#{ explode: true })
  +@query(#{ explode: true })
  ```

- `shared` option from `@route` decorator. Please use `@sharedRoute` instead.

  ```diff
  -@route("/doStuff", { shared: true })
  +@sharedRoute
  +@route("/doStuff")
  ```

- Javascript functions and typescript types:
  - `HeaderOptions.format`
  - `HeaderFieldOptions.format`
  - `QueryOptions.format`
  - `QueryParameterOptions.format`
  - `MetadataInfo.isEmptied`
  - `includeInterfaceRoutesInNamespace`
  - `getAllRoutes` -> `getAllHttpServices`
  - `OperationDetails` -> `HttpOperation`
  - `ServiceAuthentication` -> `Authentication`
  - `HttpOperationParameters.bodyType` -> `body.type`
  - `HttpOperationParameters.bodyParameter` -> `body.parameter`
  - `StatusCode` -> `HttpStatusCodesEntry`

- [#6433](https://github.com/microsoft/typespec/pull/6433) Stop exposing APIs that were not meant for external users. Please file issue if you had legitmate use of some of those APIs.
  - `@includeInapplicableMetadataInPayload` decorator was moved to `Private` namespace and stop exposing the accessor.
  - Functions used in `getHttpOperation` to resolve the finalized view of the http operation but shouldn't be used directly.
    - `resolvePathAndParameters`
  - `validateRouteUnique` internal api used in http library validation
  - Moved custom route producer related APIs to experimental with `unsafe_` prefix. Those APIs are not ready for public use and **will** change in future.
    - `DefaultRouteProducer` -> `unsafe_DefaultRouteProducer`
    - `getRouteProducer` -> `unsafe_getRouteProducer`
    - `setRouteProducer` -> `unsafe_setRouteProducer`
    - `setRouteOptionsForNamespace` -> `unsafe_setRouteOptionsForNamespace`
    - `RouteProducer` -> `unsafe_RouteProducer`
    - `RouteProducerResult` -> `unsafe_RouteProducerResult`
    - `RouteResolutionOptions` -> `unsafe_RouteResolutionOptions`
    - `RouteOptions` -> `unsafe_RouteOptions`
- [#6357](https://github.com/microsoft/typespec/pull/6357) Changed the default content-type resolution behavior as follows:

- As before, if the content-type header is _explicitly_ specified (`@header contentType: valueof string`), the explicit content type is used (this behavior has not changed).
- If the type of an HTTP payload body has a Media Type hint (`@mediaTypeHint`), that media type is preferred as the default content-type for the request.
- The default content-type for `TypeSpec.bytes` has been changed to `application/octet-stream` to avoid serializing the data to base64-encoded JSON.
- The default content-type for all other scalar types has been changed to `text/plain` (previously, it was `application/json`).
- For multipart payloads, the default content-type of the payload has been changed to `multipart/form-data` if the `@multipartBody` parameter has a Model type and `multipart/mixed` if the multipart payload has a tuple type.
  - The content-type of individual parts in the multipart request has been changed to be the same as for HTTP payload bodies and follows the logic described above.

### @typespec/versioning

- [#6327](https://github.com/microsoft/typespec/pull/6327) Remove deprecated versioning projection, switch to the mutator approach

  ```diff lang="tsp"
  // Step 1: Update to retrieve the mutation instead of projections
  -const versions = buildVersionProjections(program, service.type);
  +const versions = getVersioningMutators(program, service.type);

  // Step 2: call mutator instead of projection api
  -const projectedProgram = projectProgram(originalProgram, versionRecord.projections);
  +const subgraph = unsafe_mutateSubgraphWithNamespace(program, [mutator], service.type);
  +subgraph.type // this is the mutated service namespace
  ```

## Deprecations

### @typespec/compiler

- [#6310](https://github.com/microsoft/typespec/pull/6310) Deprecate `@typespec/compiler/emitter-framework` export in favor of a new package `@typespec/asset-emitter`

  ```diff lang=json title=package.json
  "dependencies": {
  +   "@typespec/asset-emitter": "0.67.0"
  }
  ```

  ```diff lang=ts
  -import { TypeEmitter, ... } from "@typespec/compiler/emitter-framework";
  +import { TypeEmitter, ... } from "@typespec/asset-emitter";
  ```

- [#6306](https://github.com/microsoft/typespec/pull/6306) Remove the use of deprecated getDiscriminatedUnion

### @typespec/http

- [#6464](https://github.com/microsoft/typespec/pull/6464) Deprecate implicit multipart body

  ```diff lang=tsp
  op upload(
    @header contentType: "multipart/form-data",
  -  @body body: {
  +  @multipartBody body: {
  -    name: string;
  +    name: HttpPart<string>;
  -    avatar: bytes;
  +    avatar: HttpPart<bytes>;
    }
  ): void;
  ```

### @typespec/openapi3

- [#6305](https://github.com/microsoft/typespec/pull/6305) Related changes based on `http` library deprecation removal.

## Features

### @typespec/compiler

- [#6411](https://github.com/microsoft/typespec/pull/6411) Introduce a new `dryRun` compiler option(`--dry-run` in the cli) that emitters can opt-in to support by setting `capabilities.dryRun` in their `$lib`.
- [#6411](https://github.com/microsoft/typespec/pull/6411) Update `noEmit` compiler option (`--no-emit` cli flag) to prevent emitter to run. A new `dryRun` option has been added to achieve a safer similar result where emitters run but do not write output.
- [#6220](https://github.com/microsoft/typespec/pull/6220) `tsp install` now downloads and uses the configured package manager in `devEngines.packageManager` or `packageManager` field of `package.json`
- [#6357](https://github.com/microsoft/typespec/pull/6357) Add support for `@mediaTypeHint` to apply a hint for default Media/MIME type (Content-Type in HTTP) to a TypeSpec type.

### @typespec/http

- [#6345](https://github.com/microsoft/typespec/pull/6345) Update `BasicAuth` and `BearerAuth` types scheme to use standard name for scheme `Basic`, `Bearer`
- [#6327](https://github.com/microsoft/typespec/pull/6327) Remove reference to delete projection feature

### @typespec/openapi3

- [#6268](https://github.com/microsoft/typespec/pull/6268) `@typespec/versioning` is now an optional dependency.
- [#6286](https://github.com/microsoft/typespec/pull/6286) Remove support for `@discriminator` on union
- [#6327](https://github.com/microsoft/typespec/pull/6327) Remove reference to delete projection feature

### @typespec/protobuf

- [#6327](https://github.com/microsoft/typespec/pull/6327) Remove reference to delete projection feature

### @typespec/html-program-viewer

- [#6327](https://github.com/microsoft/typespec/pull/6327) Remove reference to delete projection feature

### typespec-vscode

- [#6178](https://github.com/microsoft/typespec/pull/6178) Update references to JS emitter
- [#5972](https://github.com/microsoft/typespec/pull/5972) Select multiple emitters to generate multiple codes at one time
- [#6295](https://github.com/microsoft/typespec/pull/6295) Improve the "Create TypeSpec Project" user experience
- [#6015](https://github.com/microsoft/typespec/pull/6015) add openapi3 preview
- [#6123](https://github.com/microsoft/typespec/pull/6123) Support telemetry

## Bug Fixes

### @typespec/compiler

- [#6335](https://github.com/microsoft/typespec/pull/6335) Improvements to the CLI output
- [#6309](https://github.com/microsoft/typespec/pull/6309) Fixed an issue where the `--emit-files` flag on emitters with nested folders was not generating the correct paths to the files.
- [#6292](https://github.com/microsoft/typespec/pull/6292) Fix `tsp init` not respecting default selected emitters

### @typespec/rest

- [#6326](https://github.com/microsoft/typespec/pull/6326) Updates `@autoRoute` behavior to apply same HttpOperationParameter filtering to HttpProperty

### @typespec/openapi3

- [#6289](https://github.com/microsoft/typespec/pull/6289) Fix `utcDateTime` and `offsetDateTime` not using format `http-date` in header by default as the default http encoding defines
- [#6411](https://github.com/microsoft/typespec/pull/6411) Add support for new `dryRun` emitter option
- [#6473](https://github.com/microsoft/typespec/pull/6473) Adds support for `@encode` to specify array encodings for `@query` parameters

### @typespec/protobuf

- [#6411](https://github.com/microsoft/typespec/pull/6411) Add support for new `dryRun` emitter option

### @typespec/json-schema

- [#6411](https://github.com/microsoft/typespec/pull/6411) Add support for new `dryRun` emitter option
