Skip to content

Breaking Change Policy

Breaking Change Policy

Versioning Scheme

The TypeSpec Compiler and libraries follow a major, minor, patch versioning scheme according to the following policy:

Breaking Change Philosophy

Existing language syntax and semantics will not change without a major version. The runtime behavior for a given TypeSpec will not change without a major version. TypeSpecs leveraging new or updated features may cause runtime API consumers to fail (e.g. because a new type is unhandled in an emitter or library that it uses) or builds to fail (e.g. because exhaustive unions are no longer exhaustive).

  • The language syntax and semantics for existing language elements will not change within a major version.
  • A spec that builds successfully with a version of the TypeSpec compiler and its libraries will build successfully with a newer version of the compiler and libraries within the same major version.
  • New types and functionality may be added in a minor version release to the compiler or any TypeSpec library.
    • If a spec uses the new type or functionality, existing libraries or emitters may not work with it, and this is not considered a breaking change in the compiler or library that introduced the type. Spec authors should expect that existing specs will continue to work with their workflows, but not that newly-added features will work with their existing workflows every time.
  • TypeScript API types in TypeScript might change in ways that introduce TypeScript type checking errors (e.g. adding a new variant to a union). TypeScript type checking errors in library builds are not considered breaking changes, and library authors working in TypeScript should take care to program defensively as appropriate. More information about TypeScript API guarantees is provided in the section Categories of Breaking Changes below.

Bugs

A bug fix that introduces a technically breaking change will not be considered a breaking change for the purposes of TypeSpec versioning if it is clear that the existing behavior was broken or unintended in the first place.

Categories of Breaking Changes

  • Tier 0 : These are stable core APIs and language features that define fundamental semantics and will not be broken without a major version update. We recommend that library authors depend on these APIs.
  • Tier 1 : These are APIs that have very limited use cases and may be broken without a major version update. We recommend that library authors avoid depending on these APIs.
  • Tier 2 : These are internal APIs intended only for use by the TypeSpec compiler and core libraries. Tier 2 APIs may be changed without a a major version update or even documentation of the change. Consuming these APIs is at your own risk!
  • Tier 3 : These are APIs and language features that don’t describe semantically meaningful information, but provide information that emitters and libraries may choose to use and may introduce changes in emitter output when the features are changed. For example: formatting.
ExampleTierDescription
TypeKits0 TypeKits are the recommend way to expose APIs from a library. TypeKits that are only available through experimental subpaths may be broken without a major version update, but TypeKits that are available by default may be considered highly stable.
Additional library helper functions0 Helper and metadata accessor functions exported from the public surface of the compiler or a TypeSpec library are generally considered stable unless otherwise specified or only exported through an experimental subpath.
TypeSpec AST (Node)1 The TypeSpec abstract syntax tree may change at any time. Note: this is not the same thing as the type graph (Type and its variants), which is a Tier 0 , stable feature; this only applies to Node and its variants. The only sanctioned reason for using the AST is for some syntax based linting rule or writing codefixes. Libraries depend on the abstract syntax tree at their own risk!
Checker2 Direct use of the Program’s type checker instance is considered for internal use only and its API may change at any time.
Symbols2 TypeSpec node symbols (not JavaScript symbols or state keys, rather the internal symbols used to relate TypeSpec types in the parser and type checker) are for internal use only.
Stdout2 TypeSpec does not provide any contract with the output emitted to stdout/stderr. The CLI might change the output at any time. Stderr is used to output progress tracking and should NOT be counted as a failure.
@internal exports2 Any function, class or JS component that is exported but doesn’t have a TypeScript type due to being marked @internal is considered for internal use only and its API may change at any time.
/internals exports2 Any types exported from a sub export with the name /internals is considered for internal use only and its API may change at any time.
/experimental exports2 Any types exported from a sub export with the name /experimental is considered for experimental and its API may change at any time. See experiemental api
Formatter3 Formatting shouldn’t affect the meaning of the language. Changes to the formatting should be taken with consideration, as changes in formatting may introduce significant and unexpected differences in formatted output, but changes to the formatter output are not considered breaking changes for the purposes of issuing a major version change.
Bug fixesSee bugBug fixes will not be considered breaking changes for the purposes of TypeSpec versioning if the existing behavior is clearly broken or unintentional (e.g. if it violates the documented and expected behavior, or if there is no reasonable interpretation of the buggy behavior), even if the change is technically a breaking change. Bug fixes that are technically breaking will be documented as breaking changes in the release notes, but will not introduce a major version revision. However, if a bug’s behavior has become so widely used as to be considered a “feature,” we will consider the impact of the bugfix and make a reasonable determination to the best of our abilities and depending on the non-breaking mitigation strategies we have at our disposal. We will not break behaviors in stable releases that are known to be widely depended upon, even if we believe they are the result of a bug.

Supported Node.js Versions

TypeSpec will support all current, active, and maintenance LTS Node.js releases. We aim to support newly released current LTS versions as soon as possible, and we will provide a six month “grace period” after an LTS release leaves maintenance support before we cease testing it. After we drop support for a maintenance LTS version of Node.js, we may begin using syntax and runtime features that outdated Node.js versions may not support in new minor versions of published packages.

TypeSpec does not guarantee support for any alternative JavaScript engines or runtimes.

Using Experimental APIs Tier 3

TypeSpec compiler and libraries may expose experimental APIs that are not yet stable. These APIs are subject to change without notice. Experimental APIs or types are exported from sub exports with the name /experimental or a sub export (e.g. /experimental/feature).

When those APIs become stable the unstable APIs will be deprecated then removed and users will need to migrate to the stable version.

Emitter output

Emitter output are not guaranteed to be producing the exact same output as the previous version for the same input. A change that is semantically equivalent wouldn’t be considered a breaking change by the emitter.