Skip to content

Deprecate, remove less-used --module targets (AMD, SystemJS, UMD) #62199

Description

For the sake of simplicity, TypeScript 7.0 will not implement support for the following --module options:

  • amd
  • umd
  • systemjs

We believe most new code should use ECMAScript modules as that is the standard, as well as the common interface between bundlers and other tools. ECMAScript modules can largely serve the use-cases that these formats served, provided a mix of bundlers, import maps, or both).

In TypeScript 6.0, these options will be deprecated. TypeScript will issue an error if you use them unless you enable the ignoreDeprecations flag.

In TypeScript 7.0, the options will not be recognized, and the defaults will be --module esnext with --moduleResolution bundler.

Activity

  1. changed the title [-]Deprecate, remove less-used `--module` targets[/-] [+]Deprecate, remove less-used `--module` targets (AMD, SystemJS, UMD)[/+] on Aug 5, 2025
  2. Renegade334 commented on Aug 6, 2025

    @Renegade334
    Contributor

    Presumably allowUmdGlobalAccess should also go on the deprecation pile? It's not been mentioned so far.

    Ditto for export as namespace ...?

  3. DanielRosenwasser commented on Aug 6, 2025

    @DanielRosenwasser
    MemberAuthor

    Those are technically independent of the module format. export as namespace is not a problem per se. Best I can tell, both have already been ported to TS 7.0.

    https://github.com/microsoft/typescript-go/blob/16953b75a0d1521fe7e7e2cdd91ecbb3e2d732b2/internal/checker/checker.go#L1742-L1749

    We could discuss it.

  4. jakebailey commented on Aug 6, 2025

    @jakebailey
    Member

    Yeah, I think both are unrelated to the targets, just since they both affect script (non-module file) behavior.

  5. robpalme commented on Aug 11, 2025

    @robpalme

    and the defaults will be --module esnext with --moduleResolution bundler.

    There is an issue tracking the change to the default --target: #62198

    I don't see corresponding issues for the change to the default --moduleResolution. Please could we get one to enable discussion?

  6. jakebailey commented on Aug 11, 2025

    @jakebailey
  7. DanielRosenwasser commented on Aug 25, 2025

    @DanielRosenwasser
    MemberAuthor

    Rob Palmer (@robpalme) I've updated the language of #62206 slightly to talk about the default moduleResolution in 7.0. What do you think?

  8. robpalme commented on Sep 2, 2025

    @robpalme

    Thank you, Daniel. The deprecations look good. I'd like to address only the new defaults, and here looks like the best place to do so.


    There's an overarching question of what is the design intent of updating the various defaults? I'd suggest there are at least three coherent answers to choose from:

    • Minimize the need for overrides
      • By choosing defaults that represent the modal choice for a specific option.
      • (Note that if this were the only goal, it might result in a total set of defaults that is not optimal for any specific use-case.)
    • Match the loose/inferred project defaults
      • To ensure consistency when users add a tsconfig to a project without one.
    • Make prioritized use-cases work with (close to) zero-config
      • And hopefully provide an easy grow-up path to other use-cases.
      • (This is Rob's preference.)

    The most common use-cases to prioritize might include:

    • Browsers, via direct ESM
    • JS runtimes, starting with Node
    • Further tooling, such as a bundler

    The current suggested defaults for TS 6.0 of module:esnext specifically with moduleResolution:bundler result in the slightly odd situation of them not being ideal for standalone cases such as Node and Browsers. They fail to protect you from writing code that will error in standalone cases - which I infer from Ryan is undesirable. It implies that TypeScript will generally not be used by itself and instead the majority of TypeScript projects will need to be paired with additional tooling that can cope with resolving extensionless imports.

    I would like to instead advocate for prioritizing Node (e.g. by defaulting to module:nodenext) on the basis of it being a more minimal and more compatible starting point. It means both Node and bundler users benefit from safety and simplicity.

    Bundlers (or any higher level starter kit) generally already handle the job of initializing the tsconfig with bundler-optimized defaults meaning it's zero work for them to keep doing so. Vite's default project creator npm create vite@latest emits this tsconfig for Vanilla TS projects. Maybe 6 out of 16 options could go away with TS 6.0 defaults, but it will remain far from zero-config. Whereas Node is on the verge of zero-config.

    Starting with Node-compatible defaults leads to a more logical grow-up story where tsconfig lets you add features gradually and safely with close to zero downside for bundlers. target:esnext is another excellent example of TS 6.0 defaults taking this approach.

  9. DanielRosenwasser commented on Sep 2, 2025

    @DanielRosenwasser
    MemberAuthor

    I think one of the reasons we are drawn to --moduleResolution bundler is that many users are currently on --moduleResolution node10, which ignores exports. For many people using bundlers, this "just works". If users were to use nodenext, they might be broken due to us respecting CJS/ESM differences, but not know exactly why.

    So we can discuss it again, but that's the rationale to the best of my memory.

  10. robpalme commented on Sep 3, 2025

    @robpalme

    Thank you for tagging in Andrew Branch (@andrewbranch) - I was about to do the same because there's bound to be subtlety I can't see yet.

    It sounds like the concern is about folk who today default to --module commonjs and consequently --moduleResolution node who then succeed with a bundler. If those folk upgrade to TS6.0 and get silently switched to --module nodenext, there shouldn't be confusion about CJS/ESM because package.json won't have type:module, so all their code will remain treated as CJS by TS. I would almost worry more about defaulting to --module esnext because it will cause TS to now treat them as ESM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Breaking ChangeWould introduce errors in existing codeCommittedThe team has roadmapped this issueFix AvailableA PR has been opened for this issueSuggestionAn idea for TypeScript

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions