🐧 Unix ServerLocal AI Weekly #2: Agents Everywhere(16.09.2026 um 17:01 Uhr)
🔧 ProgrammierungUbuntu Stonking Stingray Gets Even Rustier(16.09.2026 um 15:56 Uhr)
🕵️ SicherheitslückenUSN-8773-1: GNU Guix vulnerability(16.09.2026 um 13:33 Uhr)
🐧 Unix ServerLocal AI Weekly #2: Agents Everywhere(16.09.2026 um 17:01 Uhr)
🔧 ProgrammierungUbuntu Stonking Stingray Gets Even Rustier(16.09.2026 um 15:56 Uhr)
🕵️ SicherheitslückenUSN-8773-1: GNU Guix vulnerability(16.09.2026 um 13:33 Uhr)

🔧 Programmierung 🕛 vor 6 Monaten 9 Min Lesezeit
0

Native TypeScript with Node

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

Starting with Node 22.18.0 it is possible to run option from TypeScript you can still keep most of your configuration centralized.

  • Don't explicitly check for erasable syntax.






  • CommonJS vs ESM



    Already since version 12 NodeJS has had support for , but it also has a downside; you will need to specify the extension of the file for relative imports. If you're using tsc to build your production code you will end up with multiple .js files, and therefore you will need to explicitly use the .js extension in your relative imports. Even in your TypeScript code, because tsc does not rewrite those imports (. In a nutshell; It checks the extension, then the nearest package.json with a type property, then the --input-type flag, and finally it guesses.



    If you use a bundler then this usually is corrected by the bundler, but this is not the case for native TypeScript. So, you better make an explicit choice and go for one or the other.



    NB This really only is an issue if you want to use code from another file in your codebase. If you only use modules from NodeJS itself then this is simple choice of syntax, and I would recommend to steer the module resolution by using either the extension .mts or .cts. When importing from an (P)NPM package you are dependent of the package maintainers as they how they offer their library; as ESM, as CJS or as both.






    ESM



    The moment you want to introduce relative imports into your script I would recommend using ESM. Not only is it more future-proof, and the syntax is used in the code examples on the TypeScript website, but I have yet to find a nice way to make relative imports work using CommonJS. Since the files that are used via native TypeScript in my repositories are typically grouped in a single folder I tend to add a minimal package.json to that folder to indicate ESM. Of course, this is only relevant if your root package.json explicitly indicates CommonJS usage:




    CODE
    {
    "type": "module"
    }






    Now I can split my code in file - just like I would do for production code -, and for relative imports I add the explicit extension .ts:




    CODE
    import { method } from './method.ts';

    method();






    There is one small extra step to take for this to work properly; we need to tell TypeScript that we're going to use these extensions:




    CODE
    {
    "compilerOptions": {
    "allowImportingTsExtensions": true
    }
    }






    Using a linter like eslint, oxlint or biome you can enforce usage of extensions in imports, or not, per folder.






    CommonJS



    If you decide to use CommonJS as module resolution you can do so via package.json:




    CODE
    {
    "module": "commonjs"
    }






    There is a big caveat for this however; you will still need to include relative paths with an extension when using native TypeScript. Where this will work in plain JavaScript:




    CODE
    const { sum } = require('./sum');

    sum(1, 2);






    This will not work when using native TypeScript. In that situation you are forced to specify the extension:




    CODE
    const { sum } = require('./sum.ts');

    sum(1, 2);









    Mixing "script" files and "production" files



    So you've built a nice script, and you really want to use a class, method or type definition that is also used in the code that is used in your "production" code. This could become problematic if you don't use a bundler or postprocessor. Since you need to specify the .ts - or .mts or .cts - extension on your imports, you will also need to do this on your "production" code. This can become a problem, because TypeScript will not rewrite the extension for you. And that means that the transpiled code will have the extension .js, but files will try to include it using the extension .ts.



    There are three workarounds for this:




    1. Use a bundler to build your production artifact as the bundler will take care of this translation.

    2. Do not mix production code and native TypeScript code.

    3. Use a postprocessor to correct the imports after TypeScript transpilation.






    My setup



    This may sound like a lot of caveats and a lot of stuff to deal with, just so you don't have to introduce a dependency on ts-node/tsx or add a tsc step to your workflow. And you might be right. But I have found that with a "modern" codebase it is just a handful of configurations to make native TypeScript possible.



    It is 2026, so I opt for ESM for module resolution. I think it is the way forward. This means that my ./package.json configures this for the entire codebase:




    CODE
    {
    "type": "module"
    }






    This allows me to use the import from and export syntax, and to use .ts extensions on all my TypeScript files. I try to avoid mixing native TypeScript code and production code by separating them in my filesystem. Typically, the native TypeScript code is for development and/or CI/CD only, and therefore I tend to keep it in a separate scripts folder.



    Because size always matters I use a bundler like esbuild to bundle, minify and tree shake my code. This will minimize my code artifact, and that can mean better performance. Especially on serverless architectures a smaller artifact can lead to much lower cold start times. This also makes that I can configure my linter to always require relative imports to have a .ts extension. I am currently using Biome for linting:




    CODE
    {
    "linter": {
    "rules": {
    "correctness": {
    "useImportExtensions": "error"
    }
    }
    }
    }






    Lastly I configure TypeScript to allow .ts extensions in my imports and - because I use a bundler - I explicitly disable emitting of transpiled code:




    CODE
    {
    "compilerOptions": {
    "noEmit": true,
    "allowImportingTsExtensions": true
    }
    }






    I don't have any additional safeguards in place to prevent TypeScript-only syntax in the code that is run via native TypeScript. These scripts are either used for local development or as an inspection step in a CI pipeline, so if they fail the fallout is not noticable for my production environment.






    tl/dr;



    Since NodeJS version 22 it is possible to have NodeJS run TypeScript code without the need to transpile. This feature is called native TypeScript. It adds a minimal latency and should therefore probably not be used for production purposes, but it allows typing and typesafety in your scripts. When you create larger scripts, and you want to perform relative imports then you are best off switching your entire codebase to ESM due to the requirement of extensions in your relative imports.

    Vollständiger Original-Artikel
    Den kompletten Beitrag mit allen Details direkt auf dev.to lesen.
    ↗ Original-Artikel auf dev.to lesen
    Wie bewertest du diesen Beitrag?
    1 Klick Feedback
    Teilen mit Netzwerk & Team:

    Community-Analysen & Experten-Meinungen 0

    Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
    Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
    Community Pulse: Relevanz-Einschätzung
    1 Klick Experten-Votum
    🔴 Akute Relevanz 0%
    🟡 In Evaluierung 0%
    🟢 Keine Auswirkung 0%
    Spannende Innovation 0%
    Verwandte Story-Cluster & Quellen (Vektor-KI)
    Port 8095 Engine
    2 Quellen
    The AI Era Doesn't Replace Your Skills #visualstudio #vslive
    1 Quelle
    Progress 96 Cargo Ship Docking
    1 Quelle
    AI hot takes: should developers still read code? | S02E03 | The GitHub Podcast
    Ähnliche Beiträge
    🔍 Verwandte News

    Auch interessante Nachrichten Native TypeScript with Node

    Thematisch verwandte Begriffe: Native, TypeScript, with, Node · 6 Treffer

    Laden...

    Videos werden geladen ...

    Laden...

    Beiträge werden geladen ...

    Laden...

    Videos werden geladen ...

    Laden...

    Beiträge werden geladen ...

    Laden...

    Videos werden geladen ...

    Laden...

    Beiträge werden geladen ...

    Laden...

    Videos werden geladen ...

    Laden...

    Beiträge werden geladen ...

    Laden...

    Videos werden geladen ...