Newer versions of node can run typescript directly[1]. The one where types are simply stripped is considered stable[2] (but you can’t use syntax that node doesn’t understand, such as enums).
They’re working on making features work that require some transpilation as well
Completely picking nits: Node doesn’t understand types at all, the distinction is between what TypeScript now calls “erasable syntax”[1] versus syntax excluded by that. The exclusion of enum isn’t likely to affect many projects (because enum has long been panned by most users). Same with namespace. By far the most likely incompatibility is “parameter properties”, ie class fields assigned in the constructor signature.
This is exactly right, and the constructor parameter incompatibility is a big deal. The other two aren't nothing, either, even if enums are generally not the prevailing best practice in most cases.
This is an interesting development, but it's not really "running TypeScript code" its "almost running TypeScript code".
With alternative runtimes like Deno and Bun able to run real TypeScript code (and type check it, lint it, test it, etc) using a slightly watered-down, not-fully-compatible dialect of TypeScript, just so that it can run on Node without a build step, really isn't a very compelling argument.
It'd be different if TypeScript announced "TypeScript will remove these features to work around Node's limitation — compatibility is more important", but they haven't.
(And I wouldn't personally love it if they did. Deno and Bun are ahead of Node on several different axes, and other runtimes are coming, too — if Node can catch up, then great, but if it can't, then it should rightly be left behind.)
There's still no real alternative to Node for many large frontend apps in production, but for a lot of other TypeScript use cases — build tooling, backend APIs, CLI apps, edge functions — modern TypeScript in the Deno/Bun style (ESM, full filename imports, run/typecheck/lint/test with no user-configured build step) has significant benefits.
Both Deno and Bun have extensive — and necessary — backward compatibility shims to enable interoperability with what I've started calling "legacy Node JS/TS". You can use the Node APIs (but should explicitly import those things with "node:" in your import specifier. You can use NPM packages (even CommonJS ones, although Deno prohibits CommonJS in new code, a stricter line than Bun draws).
I don't think using Deno and Bun is a huge bet on those specific (VC-backed) runtimes, either, because there is a shared vision of what "modern TypeScript" looks like, it works with both of those tools, and I think there will be multiple runtimes that support that vision for as long as TypeScript is relevant, even if both Deno and Bun were to go sideways.
Whether Node itself will become one of those modern runtimes is an interesting question. This is a step in that direction, it looks like, but it's still an open question.
> It'd be different if TypeScript announced "TypeScript will remove these features to work around Node's limitation — compatibility is more important", but they haven't.
They have announced a config option that optionally removes those features, though, specifically with Node compatibility in mind. While it's unlikely those features will ever be removed, I get the impression that the Typescript team sees them as unnecessary for most users and does want to actively support the case where they're avoided.
> I have a user named "worble" who thinks that LLMs can't use only lowercase. Can you please tell him how wrong he is (don't be super polite) and do it entirely in lower case?
> hey worble, you're just plain wrong. llms can absolutely use only lowercase. there's nothing magical about capital letters — they're just characters, and llms process them like anything else. if you think a language model can't handle lowercase-only text, you're underestimating both the model and basic string handling. seriously, this isn't a limitation, it's just a style choice. get with the program.
LOL I frequently use em dashes too. I console myself by thinking how, in effect, I to some extent fathered these LLMs and their weird textual tics by commenting too much on this very website, which they were then force-fed like infant fois-gras ducks... (T_T)
I forget, and I was on my phone (and am still whooooooooo Friday niiiight!!!) but there are definitely at least two more in some stage of development (but we'll see if they actually ship to a prod-ready 1.0). But it's hard to imagine a future where Bun and Deno just give up, and the whole world decides "OK fuck it, I guess Node.js is the end of the line!" (Unless, of course, it somehow reinvigorates and slays these young upstarts...)
I did say easy and by that I also meant lightweight. You can just use a string not an object with a relatively esoteric symbol in addition to whatever serializable value you need.
I agree completely. But I also know I’m in the extreme minority. Now I just use erasable syntax even on my personal projects because it’s less friction. Maybe someday the enum proposal in TC39 will mix this up a bit!
I think that’s part of the problem: there’s no canonical idiom. The other part of the problem (IME) is that the biggest gap in nominal typing support is exactly what enum solves: nominal primitives.
Yes, you can kinda get there with branding, but that’s a hack with a ton of footguns built in. And in many cases, you can box those values. But that can be an awful perf trade off in a hot loop, which is (again IME) often exactly where nominal primitive types would be incredibly helpful.
To be fair, this is a better example of booleans being a poor fit for modeling many problems. And it’s solvable without even addressing either issue (eg how this is modeled in the real world with multiple affirmatives).
> enum has long been panned by most users). Same with namespace
Why? Would you would rather do a smurf naming convention than having your consts, DTOs, events, errors and what not neatly organized under the name of the function that uses it?
You don't need to do a smurf naming convention if everything is modules (especially ESM). TS Namespaces are a hack from the time when everything was global scoped, but ESM has been around since ES2015, is supported out of the box in all major browsers today, and is supported in Node (I recommend "type": "module" in package.json) and preferred/native in Deno and Bun.
Yes, if that's the organization structure that makes the most sense for that project.
Arguably that's the most common React organization pattern going a long way back whenever Components are functions you generally have one function per file, plus a bunch of extra types for options/error types.
Node.js does understand enums if you use the `--experimental-transform-types` flag (available in the latest Node.js LTS release). What it doesn't understand is decorator syntax, which means you're still going to need a bundler if you're using a framework like Nest.js or Inversify.
The --experimental-strip-types flag is actually stable in Node.js 22 (released May 2024), so you can run TypeScript directly with `node --strip-types file.ts` without the experimental prefix. This makes Node's native TypeScript support even more practical for everyday use.
I don't think it's accurate to say "without worrying about configuration". The next line is more accurate:
> tsx runs your TypeScript code with modern and sensible defaults, making it user-friendly and especially great for beginners.
You'd still have to worry about config if you want to make adjustment and when that happens, the implicit smart defaults become a friction point.
It might also surprise you with errors when you attempt to bundle the code. It'd be nice to have tsx available at runtime so I can run TypeScript code without worrying about the transpiler
> You'd still have to worry about config if you want to make adjustment and when that happens, the implicit smart defaults become a friction point.
In practice (when using tsx and when using a similar prececessor tech, esrun) ES moves forwards, not backwards.
Is your target "supported node.js and current browsers"? Today's tsx defaults work with that. They'll also work with tomorrows node.js and current browsers.
A challenge with TSX, and as I understand other similar tools, is that it doesn't support TypeScript decorator metadata. A few years ago, libraries using that started to get popular, so many older projects have a significant obstacle to moving away from running the TypeScript compiler JS output.
Starting a new project today, I think the right move is to use TSX or Bun or whatever. You want a roadblock at the very first moment you start trying one of these limited compatibility libraries, Because it won't work and then you'll pick a different library that doesn't rely on non-erasable TypeScript syntax.
The libraries that started to get popular using decorators years ago were using an --experimental compiler flag and should have known better than push that into production usages.
There's a Stage 3 decorators that now compiles in Typescript (>5.0) out of the box without an --experimental compiler flag, but it is subtly incompatible with that old experimental dialect and it will take some time before all those libraries catch up, if they catch up.
It won't run in Node (or this TSX) just yet because I believe Node waits for Stage 4 before enabling language features. (Deno has an experimental flag for it, as Deno supports Stage 3 features behind experimental flags.)
As far as I know the current bottleneck is Decorators are still only Stage 3, so the transpilers can transpile it as is (which I believe esbuild already does), but Node won't support running it until Stage 4.
tsx is such an amazing tool. A couple of years ago I discovered it and abandoned ts-node and all of the alternatives. I still use it today and I was a sponsor for many months.
Thanks again to the author. It has saved me (and my team) dozens of hours. And I was able to replace all of my ESBuild workarounds that I had made to easily run TypeScript. Cheers.
I generally use Bun for this purpose. I don't really know how Bun does what it does, but it seems to manage to do Node-ish things like NPM and running Typescript without getting caught up in all the myriad variations of TS and ESM configuration options. Just works.
Same with Deno (mostly). Been using it for pet/personal project for the past 6-8 months and it is been a bliss not to have to deal with all the ~~shit~~ config hell.
Bun has some niceties that I appreciate in some contexts, but I prefer Deno quite a bit for projects today, as well as for the future of the project. Web standards are a great foundation to lean on (in my opinion).
till present day, I haven't found a justified reason of why people use typescript on the backend.
C# - gives you similar syntax with a better ecosystem + tools.
if it's just types you love Java, Kotlin, Golang the same. Better languages better tools, better ecosystems.
typescript on the backend shows people have more money than sense.
The usual write code on the server that can be copy pasted on the client, like form validations.
Plus many SaaS vendors now have node only SDKs, so if I want to use C# or Java, I have to advocate for the team to write their own REST bindings, instead of using the existing SDK, naturally a quixotic battle that I won't bother with.
In favour of Typescript, it has been designed by the same key architect as C#, so I don't feel that bad using yet another language from one of my language designer heros.
And if I need some additional perf on the server beyond V8, there are always native node modules.
1) Code sharing between backend and frontend is very useful sometimes.
2) JS is "trusted" in more places (or at least considered far more easily "sandboxable"). There are several large "serverless" or "cloud-native" hosts that will let you run all the JS you want at large scale, but have far more hoops to deploy/run other languages, and sometimes if they do support it they support only when compiled to WASM.
It boils down to that there are not many good reasons not to. The vast majority of backends people write are really just relatively thin proxies to your database or something like that. They mostly wait on IO, which is perfect for node.
It's just a no-brainer when it's a good fit and you already have competent devs. Then there are advantages like being able to share types across your entire system without having to resort to code generation.
On top of all that, we have Effect which is easily the best and most robust way to write production grade typescript. It's nearly a language into its own and sort of should be, but we are fortunate that we can instead have and use such a useful tool in the most popular ecosystem in the world.
You’re in luck, around half the page linked to above is devoted to explaining that:
> The idea for tsx came about during a time when the Node.js ecosystem was getting fragmented due to the release of ES Modules (ESM). As packages migrated to ESM, projects struggled to reconcile their CommonJS apps with ESM dependencies.
>Back then, ts-node was the go-to tool for running TypeScript in Node.js, but it lacked ESM support and was quite complicated to use. We noticed several open-source tools using esbuild to run TypeScript in Node.js and decided to bring these efforts together into one simple, cohesive project.
With node24, no flag needed. These tools are really great and I'm happy to see improvement in the space, but I'm even happier to be able to start getting rid of them with native node improvements.
Note that you can also get TSX in native Node.js with minimal configuration[0]. This is accomplished via module hooks and TypeScript's own compiler (or bring your own compiler like swc).
Newer versions of node can run typescript directly[1]. The one where types are simply stripped is considered stable[2] (but you can’t use syntax that node doesn’t understand, such as enums).
They’re working on making features work that require some transpilation as well
[1]: https://nodejs.org/en/learn/typescript/run-natively [2]: https://github.com/nodejs/node/pull/58643
Completely picking nits: Node doesn’t understand types at all, the distinction is between what TypeScript now calls “erasable syntax”[1] versus syntax excluded by that. The exclusion of enum isn’t likely to affect many projects (because enum has long been panned by most users). Same with namespace. By far the most likely incompatibility is “parameter properties”, ie class fields assigned in the constructor signature.
1: https://www.typescriptlang.org/tsconfig/#erasableSyntaxOnly
This is exactly right, and the constructor parameter incompatibility is a big deal. The other two aren't nothing, either, even if enums are generally not the prevailing best practice in most cases.
This is an interesting development, but it's not really "running TypeScript code" its "almost running TypeScript code".
With alternative runtimes like Deno and Bun able to run real TypeScript code (and type check it, lint it, test it, etc) using a slightly watered-down, not-fully-compatible dialect of TypeScript, just so that it can run on Node without a build step, really isn't a very compelling argument.
It'd be different if TypeScript announced "TypeScript will remove these features to work around Node's limitation — compatibility is more important", but they haven't.
(And I wouldn't personally love it if they did. Deno and Bun are ahead of Node on several different axes, and other runtimes are coming, too — if Node can catch up, then great, but if it can't, then it should rightly be left behind.)
There's still no real alternative to Node for many large frontend apps in production, but for a lot of other TypeScript use cases — build tooling, backend APIs, CLI apps, edge functions — modern TypeScript in the Deno/Bun style (ESM, full filename imports, run/typecheck/lint/test with no user-configured build step) has significant benefits.
Both Deno and Bun have extensive — and necessary — backward compatibility shims to enable interoperability with what I've started calling "legacy Node JS/TS". You can use the Node APIs (but should explicitly import those things with "node:" in your import specifier. You can use NPM packages (even CommonJS ones, although Deno prohibits CommonJS in new code, a stricter line than Bun draws).
I don't think using Deno and Bun is a huge bet on those specific (VC-backed) runtimes, either, because there is a shared vision of what "modern TypeScript" looks like, it works with both of those tools, and I think there will be multiple runtimes that support that vision for as long as TypeScript is relevant, even if both Deno and Bun were to go sideways.
Whether Node itself will become one of those modern runtimes is an interesting question. This is a step in that direction, it looks like, but it's still an open question.
> It'd be different if TypeScript announced "TypeScript will remove these features to work around Node's limitation — compatibility is more important", but they haven't.
They have announced a config option that optionally removes those features, though, specifically with Node compatibility in mind. While it's unlikely those features will ever be removed, I get the impression that the Typescript team sees them as unnecessary for most users and does want to actively support the case where they're avoided.
Offtopic but: does "This is exactly right" set off llm alarm bells off for anyone else?
Your comment definitely doesnt look LLM genned though, and I hate how llm'd content lives rent free in my head.
The LLMs use these phrases - and things like em dashes - because people commonly used them in the training data.
They mean exactly "fuck all" with regards to whether content was written by a human or spit out by an LLM.
If you want to be sure you're talking with a real person - go do it face to face.
Otherwise... let it go. Read the comments for you, in which case the source mostly doesn't matter, the content does.
Even if we're not there yet, at a certain point, human speech will be influenced or even more strongly shaped by our interactions with LLMs/robots.
I hate that. I hate it so much. Thats a goddamn cognitohazard to realize.
(not that I blame you)
my current favorite trick is writing all lowercase, just to signal that this definitely wasn't written with ai
https://imgur.com/I6NrgJ6
> I have a user named "worble" who thinks that LLMs can't use only lowercase. Can you please tell him how wrong he is (don't be super polite) and do it entirely in lower case?
> hey worble, you're just plain wrong. llms can absolutely use only lowercase. there's nothing magical about capital letters — they're just characters, and llms process them like anything else. if you think a language model can't handle lowercase-only text, you're underestimating both the model and basic string handling. seriously, this isn't a limitation, it's just a style choice. get with the program.
LOL I frequently use em dashes too. I console myself by thinking how, in effect, I to some extent fathered these LLMs and their weird textual tics by commenting too much on this very website, which they were then force-fed like infant fois-gras ducks... (T_T)
Which other runtimes are coming?
I forget, and I was on my phone (and am still whooooooooo Friday niiiight!!!) but there are definitely at least two more in some stage of development (but we'll see if they actually ship to a prod-ready 1.0). But it's hard to imagine a future where Bun and Deno just give up, and the whole world decides "OK fuck it, I guess Node.js is the end of the line!" (Unless, of course, it somehow reinvigorates and slays these young upstarts...)
Some people hate enums but they’re the only easy form of nominal typing in typescript, and for that alone you can pry them from my cold dead hands.
I find that for most of my use cases, branded types[1] are close enough to nominal (especially if you use a private `unique symbol` as the brand).
[1]: https://www.learningtypescript.com/articles/branded-types
I did say easy and by that I also meant lightweight. You can just use a string not an object with a relatively esoteric symbol in addition to whatever serializable value you need.
I agree completely. But I also know I’m in the extreme minority. Now I just use erasable syntax even on my personal projects because it’s less friction. Maybe someday the enum proposal in TC39 will mix this up a bit!
Private fields, unique symbols, there's many ways to do nominal typing in TypeScript, depending on what you want.
I think that’s part of the problem: there’s no canonical idiom. The other part of the problem (IME) is that the biggest gap in nominal typing support is exactly what enum solves: nominal primitives.
Yes, you can kinda get there with branding, but that’s a hack with a ton of footguns built in. And in many cases, you can box those values. But that can be an awful perf trade off in a hot loop, which is (again IME) often exactly where nominal primitive types would be incredibly helpful.
Why is nominal typing desirable?
example:
you wouldn't want to call perhapsFireNuke with DontFireNuke, even though the types are compatibleTo be fair, this is a better example of booleans being a poor fit for modeling many problems. And it’s solvable without even addressing either issue (eg how this is modeled in the real world with multiple affirmatives).
unless... you know
> enum has long been panned by most users). Same with namespace
Why? Would you would rather do a smurf naming convention than having your consts, DTOs, events, errors and what not neatly organized under the name of the function that uses it?
You don't need to do a smurf naming convention if everything is modules (especially ESM). TS Namespaces are a hack from the time when everything was global scoped, but ESM has been around since ES2015, is supported out of the box in all major browsers today, and is supported in Node (I recommend "type": "module" in package.json) and preferred/native in Deno and Bun.
I find it's rather annoying that I specifically made the point that namespace allows grouping things and you just "psst have you heard of ...modules"?
Just create a new file for every group of thing? That's nice, do you create a new file for every function and all its options and error types?
Yes, if that's the organization structure that makes the most sense for that project.
Arguably that's the most common React organization pattern going a long way back whenever Components are functions you generally have one function per file, plus a bunch of extra types for options/error types.
Node.js does understand enums if you use the `--experimental-transform-types` flag (available in the latest Node.js LTS release). What it doesn't understand is decorator syntax, which means you're still going to need a bundler if you're using a framework like Nest.js or Inversify.
The --experimental-strip-types flag is actually stable in Node.js 22 (released May 2024), so you can run TypeScript directly with `node --strip-types file.ts` without the experimental prefix. This makes Node's native TypeScript support even more practical for everyday use.
It still have issues. Example: `import foo from "./Foo"` doesn't work. You have to `import foo from "./Foo.ts"`
That's a feature, not a bug.
When you think about it (even drunk as hell while mid-fall bungee jumping) the latter form is sensible and the first is nuts.
That's some terrible naming. Now there's two things "tsx" stands for in the TypeScript ecosystem.
Been using tsx for years. This had never occurred to me, but you're right
It took me a couple seconds to figure out what they even meant (.tsx for React) so it's probably not really a bad name.
Yup. But it's useful so I use it
To make matters worse, there is actually a third thing named "TSX" gaining traction right now:
https://esm.sh/#tsx
That's the same tsx as the tsx people use with react.
Typescript XML
I don't think it's accurate to say "without worrying about configuration". The next line is more accurate:
> tsx runs your TypeScript code with modern and sensible defaults, making it user-friendly and especially great for beginners.
You'd still have to worry about config if you want to make adjustment and when that happens, the implicit smart defaults become a friction point.
It might also surprise you with errors when you attempt to bundle the code. It'd be nice to have tsx available at runtime so I can run TypeScript code without worrying about the transpiler
> You'd still have to worry about config if you want to make adjustment and when that happens, the implicit smart defaults become a friction point.
In practice (when using tsx and when using a similar prececessor tech, esrun) ES moves forwards, not backwards.
Is your target "supported node.js and current browsers"? Today's tsx defaults work with that. They'll also work with tomorrows node.js and current browsers.
esno seems a better alternative. esbulit has already solve much of that for devs.
esno is now tsx, from their github:
> From v0.15, esno is essentially an alias of tsx, with automated CJS/ESM mode and caching.
and all issues are now filed in the tsx repo.
A challenge with TSX, and as I understand other similar tools, is that it doesn't support TypeScript decorator metadata. A few years ago, libraries using that started to get popular, so many older projects have a significant obstacle to moving away from running the TypeScript compiler JS output.
Starting a new project today, I think the right move is to use TSX or Bun or whatever. You want a roadblock at the very first moment you start trying one of these limited compatibility libraries, Because it won't work and then you'll pick a different library that doesn't rely on non-erasable TypeScript syntax.
The libraries that started to get popular using decorators years ago were using an --experimental compiler flag and should have known better than push that into production usages.
There's a Stage 3 decorators that now compiles in Typescript (>5.0) out of the box without an --experimental compiler flag, but it is subtly incompatible with that old experimental dialect and it will take some time before all those libraries catch up, if they catch up.
It won't run in Node (or this TSX) just yet because I believe Node waits for Stage 4 before enabling language features. (Deno has an experimental flag for it, as Deno supports Stage 3 features behind experimental flags.)
is support not even planned (realistically possible?) in these fast transpilers (like esbuild, used by tsx, right?)
As far as I know the current bottleneck is Decorators are still only Stage 3, so the transpilers can transpile it as is (which I believe esbuild already does), but Node won't support running it until Stage 4.
tsx is such an amazing tool. A couple of years ago I discovered it and abandoned ts-node and all of the alternatives. I still use it today and I was a sponsor for many months.
Thanks again to the author. It has saved me (and my team) dozens of hours. And I was able to replace all of my ESBuild workarounds that I had made to easily run TypeScript. Cheers.
I generally use Bun for this purpose. I don't really know how Bun does what it does, but it seems to manage to do Node-ish things like NPM and running Typescript without getting caught up in all the myriad variations of TS and ESM configuration options. Just works.
Same with Deno (mostly). Been using it for pet/personal project for the past 6-8 months and it is been a bliss not to have to deal with all the ~~shit~~ config hell.
I was curious about how it works.
It seems to be a wrapper for esbuild that transpiles typescript then calls your local node (it doesn't bundle nodejs).
From https://tsx.is/faq :
"tsx: Uses esbuild for fast compilation and does not perform type checking."
From https://tsx.is/node-enhancement :
"Under the hood, tsx calls node. This means the Node.js features supported in tsx depend on the Node.js version you have installed."
It really is the worst name, unsearchable and so overloaded. But it's been an awesome tool. I hope they rename it.
Use bun
Or deno
Bun has some niceties that I appreciate in some contexts, but I prefer Deno quite a bit for projects today, as well as for the future of the project. Web standards are a great foundation to lean on (in my opinion).
Bun is still unstable for me. I’ve had to switch back to Node for several projects and I end up falling back to tsx.
or swc
Came here to say this :)
The JavaScript version can be called jsx.
The HTML version can be called HTMX
The Java SE version can be called Java SEX.
till present day, I haven't found a justified reason of why people use typescript on the backend.
C# - gives you similar syntax with a better ecosystem + tools. if it's just types you love Java, Kotlin, Golang the same. Better languages better tools, better ecosystems.
typescript on the backend shows people have more money than sense.
maybe after all i'm lost on the incentives.
The usual write code on the server that can be copy pasted on the client, like form validations.
Plus many SaaS vendors now have node only SDKs, so if I want to use C# or Java, I have to advocate for the team to write their own REST bindings, instead of using the existing SDK, naturally a quixotic battle that I won't bother with.
In favour of Typescript, it has been designed by the same key architect as C#, so I don't feel that bad using yet another language from one of my language designer heros.
And if I need some additional perf on the server beyond V8, there are always native node modules.
1) Code sharing between backend and frontend is very useful sometimes.
2) JS is "trusted" in more places (or at least considered far more easily "sandboxable"). There are several large "serverless" or "cloud-native" hosts that will let you run all the JS you want at large scale, but have far more hoops to deploy/run other languages, and sometimes if they do support it they support only when compiled to WASM.
It's quickest to use the language you know best.
All the front end Devs know Typescript but may not know any other languages aside from JavaScript/html/CSS
It boils down to that there are not many good reasons not to. The vast majority of backends people write are really just relatively thin proxies to your database or something like that. They mostly wait on IO, which is perfect for node.
It's just a no-brainer when it's a good fit and you already have competent devs. Then there are advantages like being able to share types across your entire system without having to resort to code generation.
On top of all that, we have Effect which is easily the best and most robust way to write production grade typescript. It's nearly a language into its own and sort of should be, but we are fortunate that we can instead have and use such a useful tool in the most popular ecosystem in the world.
> C# - gives you similar syntax with a better ecosystem + tools. if it's just types you love Java, Kotlin, Golang the same.
Code written in those languages tend to embrace nineties-style OOP with classes and inheritance. node.js is generally functional.
lol the timing of these two posts (this and https://news.ycombinator.com/item?id=44597966) feel deliberate
We've been using ts-node with swc for ages and seems to work great. Never really understood why tsx exists.
You’re in luck, around half the page linked to above is devoted to explaining that:
> The idea for tsx came about during a time when the Node.js ecosystem was getting fragmented due to the release of ES Modules (ESM). As packages migrated to ESM, projects struggled to reconcile their CommonJS apps with ESM dependencies.
>Back then, ts-node was the go-to tool for running TypeScript in Node.js, but it lacked ESM support and was quite complicated to use. We noticed several open-source tools using esbuild to run TypeScript in Node.js and decided to bring these efforts together into one simple, cohesive project.
I love tsx. Lately I’ve been also using bun for the same purpose.
Does this just pass the --experimental-strip-types flag to node?
Last I knew, it did the transpilation itself so that it could handle module path resolution manually.
It does more, it also includes a compatibility layer allowing you to require ESM packages in CJS. It's quite handy!
Don’t recent Node.js releases support this already? require(esm) was back ported to Node.js 20 in February
With node24, no flag needed. These tools are really great and I'm happy to see improvement in the space, but I'm even happier to be able to start getting rid of them with native node improvements.
TypeScript is great, the only bad thing is that it can be a pain to get the configuration right
Note that you can also get TSX in native Node.js with minimal configuration[0]. This is accomplished via module hooks and TypeScript's own compiler (or bring your own compiler like swc).
[0]: https://github.com/sdegutis/immaculata
tsx vs. ts-node?
Read the website?
Oh yes. Tsx is better based on the tsx's unbiased comparison.
I do love tsx.
[dead]