[HN Gopher] A Node, TypeScript, TS-Node and ESM experience that ...
       ___________________________________________________________________
        
       A Node, TypeScript, TS-Node and ESM experience that works
        
       Author : khalidx
       Score  : 176 points
       Date   : 2023-11-21 08:44 UTC (14 hours ago)
        
 (HTM) web link (gist.github.com)
 (TXT) w3m dump (gist.github.com)
        
       | austin-cheney wrote:
       | _The experience of using Node.JS with TypeScript, ts-node, and
       | ESM is horrible._
       | 
       | I completely disagree. This has always felt immediately straight
       | forward to me. I suspect this struggle, a struggle I completely
       | don't understand, explains the complexity of hiring for these
       | kinds of jobs. I really felt that to get hired for these jobs you
       | had to be willing to play stupid games and abandon all reason to
       | worship at the pulpit of giant frameworks and third party
       | solutions. Fortunately, I have moved on to something else.
        
         | Yiin wrote:
         | I'd love to see you live stream a process of creating a project
         | consisting of several different apps using same ts config and
         | shared libs folder from scratch using these tools.
        
           | austin-cheney wrote:
           | In my personal projects I use _"type": "module"_ in the
           | package.json.
           | 
           | In my tsconfig.json I use                   {
           | "compilerOptions": {             "alwaysStrict": true,
           | "module": "ES2020",             "moduleResolution": "node",
           | "outDir": "./js/lib",             "noEmit": true,
           | "noImplicitAny": true,             "pretty": false,
           | "strictFunctionTypes": true,             "target": "ES2020",
           | "types": ["node"],             "typeRoots":
           | ["./node_modules/@types"]         },         "exclude": [
           | "js",             "lib/terminal/test/storageTest/temp",
           | "**/node_modules",             "**/.*/"         ],
           | "include": [             "**/*.ts"         ]         }
           | 
           | Internally in your apps never never use relative file system
           | paths.
        
             | khalidx wrote:
             | Is alwaysStrict the same as strict? I think this skips a
             | lot of the strict options that are usually the case for
             | using TypeScript in the first place.
        
               | austin-cheney wrote:
               | According to the TypeScript documentation for
               | tsconfig.json the alwaysStrict option forces the compiled
               | out to strict mode such that the JIT interpreter parses
               | it as such. This happens anyways when using ES6 modules,
               | but it also ensures the TypeScript compiler parses each
               | file in strict mode regardless of having the "use strict"
               | pragma at the top.
               | 
               | https://www.typescriptlang.org/tsconfig#alwaysStrict
        
               | khalidx wrote:
               | I just dug a bit deeper as I couldn't remember the
               | differences. They're not referring to the same things.
               | 
               | "alwaysStrict", which adds "use strict", is different
               | than TypeScript "strict" mode, which constrains the
               | language.
               | 
               | Setting "strict" to "true" enables "alwaysStrict", but
               | not the other way around. I'd remove "alwaysStrict" and
               | go with "strict" as it covers more things.
        
       | rickcarlino wrote:
       | I've found TSX to be a better alternative to ts-node. It seems to
       | have more sensible defaults in 2023.
       | https://github.com/privatenumber/tsx
        
         | lloydatkinson wrote:
         | I was about to say exactly this. If you're writing Node scripts
         | there's no reason to use ts-node as tsx, by default, does the
         | correct thing and works correctly with ES modules.
         | 
         | Of course, Deno offers a better experience for scripts or
         | programs.
        
           | khalidx wrote:
           | I tried `tsx` but it didn't work for some reason (can't
           | remember why right now). Also, if you've been using `ts-node`
           | and feel comfortable with it, this setup should work for you
           | instead of switching your toolchain.
        
             | privatenumber wrote:
             | tsx v4 was released a couple weeks ago which addressed many
             | incompatibility issues. Hope you have a chance to give it
             | another shot :)
        
         | vmfunction wrote:
         | or esno, which is tsx with esbuild.
        
           | lhnz wrote:
           | I'm using `esyes` [0] by Yehuda Katz and the logic is simple
           | and it works very well.
           | 
           | [0] https://github.com/starbeamjs/esyes
        
             | vmfunction wrote:
             | thanks for sharing! Didn't know about this one.
        
           | madeofpalk wrote:
           | tsx is "tsx with esbuild" though?
        
         | domh wrote:
         | I use node-dev which seems to have good ts support. node-dev
         | with --respawn is a good cheap way to watch and rerun ts files
         | on change!
        
         | herpdyderp wrote:
         | Tsx is great but doesn't work in all situations unfortunately.
         | Some broken cases that I remember off the top of my head are
         | Playwright and test coverage.
        
           | privatenumber wrote:
           | Maintainer of tsx here.
           | 
           | tsx should be able to handle Playwright as of v4+, and
           | hopefully the test coverage you're referring to.
           | 
           | Before, it was compiling ESM syntax to CJS as an effort to
           | ease the ecosystem's CJS -> ESM migration, and hiccuping
           | whenever it encountered `eval()`. Now it includes smarter
           | checks to determine if a file needs to be compiled at all and
           | skips processing most dependencies.
           | 
           | Hope it works well for you!
        
             | e1g wrote:
             | Can confirm we use tsx with playwright with no issues.
             | Thanks!
        
             | herpdyderp wrote:
             | I see v4 was published just 12 days ago. I'll have to give
             | it another shot! Thanks!
        
         | bruh2 wrote:
         | Love this project, used it quite a bit. However I always opt
         | for using esno[1] instead, merely because of the name; having
         | two tools share the same name throws me off.
         | 
         | [1] https://github.com/esbuild-kit/esno
        
           | madeofpalk wrote:
           | > From v0.15, esno is essentially an alias of tsx
           | 
           | heh. It really is https://github.com/esbuild-
           | kit/esno/blob/master/esno.js
        
       | quackware wrote:
       | - Why include files, exports, and types in your package.json when
       | you are just using ts-node to transpile on the fly?
       | 
       | - ts-node is much slower than something like esbuild/tsx right?
       | As long as you rely on your ide type checking or run type
       | checking before deploying your app.
        
         | khalidx wrote:
         | The "exports" and other sections are recommended things you'll
         | need in your `package.json` file to support ESM. Sensible
         | defaults. Also just points to an index.ts file (that you'll
         | likely have in your project if you are developing a package).
         | 
         | Also, this project can be compiled with `tsc` or a bundler, of
         | course.
         | 
         | In terms of speed, this should consistently start up an app or
         | CLI in <3 seconds (depending on size of course).
        
       | keb_ wrote:
       | Also see TSM: https://github.com/lukeed/tsm
        
       | WolfOliver wrote:
       | Agree it is a little tricky to get startet. But once configured,
       | it helps a lot
        
       | jna_sh wrote:
       | This is not a guide, it's three config files
        
         | khalidx wrote:
         | You're right, but what guide is easier than "Just add the
         | following files and run npm run dev. You'll be good to go!".
        
           | bilekas wrote:
           | I'm personally against that belief as it doesn't really teach
           | anything. Just adds a list of bootstrapping that you don't
           | understand.
        
             | jenscow wrote:
             | There's only so much spoon-feeding that can be done. We
             | already have so much information at our fingertips.
             | 
             | If people just want to copy+paste it then mark a jira issue
             | as complete, that's up to them.
             | 
             | However, for those of us who want to understand - sometimes
             | it's better to see a working example and pick at it.
        
             | codingdave wrote:
             | I find that almost all devs have a layer at which they
             | don't understand what is going on. Everything we do is
             | built on the shoulders of giants, as evidenced by how
             | little we think about the 0s and 1s that are the actual end
             | result of our work.
             | 
             | So I don't see a problem with any dev having a line of non-
             | understanding as they work. Some peoples lines are lower
             | than others, but we all work that way. So it is all good.
        
               | bilekas wrote:
               | Absolutely, but don't call it a guide. When it's not.
        
         | SPBS wrote:
         | Sometimes the most valuable guide is a working example. Lord
         | knows, there are so many docs out there that keep prattling on
         | and on instead of showing me the code.
        
           | chii wrote:
           | a working example that you don't understand and just copy
           | over and over again into new projects.
           | 
           | This eventually turns into an incantation and magic. It's how
           | crap gets built up and poor decisions get propagated.
        
             | azangru wrote:
             | > a working example that you don't understand and just copy
             | over and over again into new projects.
             | 
             | Once you have a working example, you can go through it line
             | by line and figure out what it is doing.
        
               | Feathercrown wrote:
               | Which the author would be kind to do and post with the
               | example.
        
               | mst wrote:
               | Honestly, I've always preferred to have somebody's
               | example plus the reference documentation.
               | 
               | Learning not only what it does but where it's documented
               | - and having to go look for myself to do so - fixes it in
               | my memory a lot better.
               | 
               | I have a years old set of npm/etc. configs in a project I
               | noodle on occasionally, and when I re-open them to look I
               | remember exactly what they do -because- I started from a
               | boilerplate and then went and learned how all of it
               | works.
               | 
               | That doesn't mean an explanation wouldn't still be
               | helpful for a bunch of people who aren't me, but honestly
               | having the tsconfig commented like that is more than
               | sufficient for -me- to be happy.
        
           | DangitBobby wrote:
           | 99% of the working examples I encounter in JS config don't
           | work by the time I get to them.
        
       | pyrolistical wrote:
       | this setup doesn't work with node test runner.
       | 
       | I had to tsc then node --test the built files.
       | 
       | tsx also is missing the test runner
       | https://github.com/privatenumber/tsx/issues/257
        
         | e1g wrote:
         | With tsx instead of ts-node, it works just fine -
         | node --import=tsx --test __tests__/\*/\*.test.ts
        
           | pyrolistical wrote:
           | Including failed tests?
        
       | ivanjermakov wrote:
       | And if you publush it, imports are going to be from
       | 'pkg/dist/foo'..
        
       | bovermyer wrote:
       | In order to be a guide, I feel like it would need to explain
       | _why_ each thing is there and what it does.
        
       | EdSharkey wrote:
       | A gist, the digital equivalent of scribblings on a stained
       | cocktail napkin, lays bare the great mystery. The great dragon is
       | slain! His precious treasure is of no value whatsoever.
       | 
       | Fellow scrounging raccoons, raise your chipped mugs and cracked
       | cups! Let us toast to our fortune, we truly are the blessed ones.
        
       | w3news wrote:
       | Why not using Node how it is designed, than ESM works great.
       | 
       | For type checking on development, you can do it with ESLint and
       | JSDoc in Typescript modus. You have the same type checking like
       | you have in ts files. You can even import types from typescript
       | files, like .d.ts
       | 
       | Best of both worlds, no transformation of the code, and on
       | development you have some help from Typescript.
        
       | vasergen wrote:
       | > The experience of using Node.JS with TypeScript, ts-node, and
       | ESM is horrible.
       | 
       | So true, I really wandering if there was a better alternative,
       | they essentially broke a lot of packages and I don't know how
       | many dev hours will be put now to fix all of this, because so
       | many tools are broken now. Additionally to that, they did some
       | other not backwards compatible changes, like removing __direname
       | in ESM, which is IMHO not the best decisions, why not for example
       | just keep it as it is, but deprecate it and have a warning
       | message.
        
         | khalidx wrote:
         | I agree that the migration experience has been subpar! I
         | dropped ESM migration of my packages 2-3 times before finally
         | picking it up again and wrapping it up in a simple guide.
         | Hopefully with the config I shared you'll find that you can use
         | all those out-of-reach ESM packages now! Also, I provided
         | examples for getting __dirname and __filename -like behavior.
        
         | azangru wrote:
         | > a better alternative
         | 
         | Deno?
        
       | jampekka wrote:
       | https://gist.github.com/joepie91/bca2fda868c1e8b2c2caf76af7d...
        
         | khalidx wrote:
         | Strong agree. This has caused a major rift in the Node
         | ecosystem (and for its packages).
         | 
         | All we can do is adapt and keep building. Using Node v20 (LTS)
         | currently with the config linked in the parent post.
        
       | demurgos wrote:
       | I always found it easier to avoid `ts-node` as it introduced a
       | bunch of small compat issues.
       | 
       | Since TS 4.5 and their support for `.mts`, I finally settled on
       | just chaining `tsc --build && node ./build/main.mjs`.
        
         | azangru wrote:
         | And for development?
        
           | demurgos wrote:
           | With TS, I get type checking in the IDE; I don't need to
           | rebuild every few seconds.
           | 
           | When I actually need to build and test, it's very fast (<2
           | seconds). I use Yarn workspaces/subprojects and TypeScript
           | references with incremental builds so it's not really an
           | issue.
           | 
           | Here is the `package.json` [0] for a serialization lib I did,
           | you can check the `scripts` section: it's very minimal and
           | I'm quite happy with it. I'm an old Gulp maintainer, so for a
           | long time I had heavy Gulp config with a lot of processing.
           | Over the years I could get rid of it. ESM was the last thing
           | holding me back; and now I'm so happy that I can just use a
           | few simple commands.
           | 
           | [0]: https://github.com/demurgos/kryo/blob/master/packages/kr
           | yo/p...
        
         | khalidx wrote:
         | I generally agree with your statement, but have found ts-node
         | incredibly valuable especially when developing servers or CLIs
         | where I want to start/restart the process many times without a
         | build step every time.
        
           | SahAssar wrote:
           | Node has a built in watch mode and so does tsc. So if you
           | start both you should get what you want.
        
         | beepbooptheory wrote:
         | or: `tsc --build --watch` and then just have another terminal
         | to run.
        
           | demurgos wrote:
           | Yes, TS now fully supports ESM so the watch mode works great.
           | I'm not used to using it when working in Node, but other
           | people I work with use it all the time.
        
       | koolba wrote:
       | Many people in this thread are rightly complaining that this does
       | not answer the "why does this work". Having a working example is
       | a good start for that though as at least you have a known target
       | and as you change things (and break things), you can see what
       | those options did.
       | 
       | One problem with this guide that makes that trickier is that the
       | tsconfig.json itself imports
       | https://github.com/sindresorhus/tsconfig/blob/5c87dc118e057d...
       | and overrides a bunch of values.
       | 
       | So if you really want to understand what it's doing, you need to
       | get rid of that dependency and inline / merge that config file.
       | That would also add stability to your project as it's one less
       | upstream dependency out of your control (and a big one at that as
       | it controls how you entire project is built!).
       | 
       | For example the imported tsconfig.json changes these:
       | "compilerOptions": {           // ...            "module":
       | "node16",           "moduleResolution": "node16",
       | "moduleDetection": "force",           // ...
       | "allowSyntheticDefaultImports": true, // To provide backwards
       | compatibility, Node.js allows you to import most CommonJS
       | packages with a default import. This flag tells TypeScript that
       | it's okay to use import on CommonJS modules.           "jsx":
       | "react",           // ...          }
       | 
       | But you wouldn't notice that if you just look at the gist. It'd
       | just be a magic that you can write React code in a .tsx file.
       | Clearly that has to be enabled _somewhere_.
        
         | btown wrote:
         | https://documentation.divio.com/ is a good overview of the
         | "four types of documentation" paradigm: tutorials, how-to
         | guides, explanations, and reference have to all exist.
         | 
         | One of my major gripes with the JS/TS ecosystem is that
         | "explanations" are sorely lacking. See
         | https://www.typescriptlang.org/tsconfig for the relevant
         | documentation for tsconfig files. Tutorials are on the page,
         | how-to guides abound on the wider internet (like the OP), and
         | the linked TSConfig Reference and JSON Schema (used in code
         | completion in IDEs) are together absolutely massive.
         | 
         | But an explanation is missing! There is no official
         | documentation about how different options interact to say: as
         | I'm walking a file tree as the Typescript compiler, this is how
         | I will interpret a certain file I encounter, what will be
         | outputted, and how that will be interpreted by bundlers and
         | browsers, especially in an ESM world.
         | 
         | https://medium.com/extra-credit-by-guild/tsconfig-json-demys...
         | is in the right direction, but outdated as ESM has become much
         | more popular in the past 3 years, and still organized by option
         | (so it's already somewhat in the "reference" world).
         | 
         | IMO even independent of documentation, the industry's move to
         | ESM is problematic:
         | https://gist.github.com/joepie91/bca2fda868c1e8b2c2caf76af7d...
         | describes many of the issues. But they're certainly exacerbated
         | by good explanation-style documentation that helps people
         | understand how ESM works under the hood!
        
           | paddy_m wrote:
           | What programming languages and libraries are well explained
           | in this aspect?
        
             | Macha wrote:
             | Python, Rust. Given that Python was one of the first open
             | source projects to choose such a model, and Rust explicitly
             | adopted such a model, that's probably not so surprising.
             | 
             | (Somebody is going to bring up the Python packaging
             | clusterfuck as a retort to this, but the fact that Python
             | packaging is both assumed and held at a distance is a
             | larger problem than just documentation)
        
           | mst wrote:
           | I once did a conference talk on the different types - called
           | it Euclid, Socrates and Mill and analogised a good tutorial
           | to Euclid's Elements, the explanation part to Socrates and
           | howto/cookbook type stuff to John Stewart Mill.
           | 
           | (don't remember if there's a decent video out there but I
           | figure you probably don't need to listen to me waffle to see
           | how the analogies might work ;)
        
           | mook wrote:
           | It's not even that great, typescript doesn't even have a good
           | reference. There are random features that are only documented
           | on release notes.
           | 
           | Working with TS has been somewhat frustrating.
        
           | jakebailey wrote:
           | > One of my major gripes with the JS/TS ecosystem is that
           | "explanations" are sorely lacking. See
           | https://www.typescriptlang.org/tsconfig for the relevant
           | documentation for tsconfig files. Tutorials are on the page,
           | how-to guides abound on the wider internet (like the OP), and
           | the linked TSConfig Reference and JSON Schema (used in code
           | completion in IDEs) are together absolutely massive.
           | 
           | > But an explanation is missing! There is no official
           | documentation about how different options interact to say: as
           | I'm walking a file tree as the Typescript compiler, this is
           | how I will interpret a certain file I encounter, what will be
           | outputted, and how that will be interpreted by bundlers and
           | browsers, especially in an ESM world.
           | 
           | Perhaps you missed it, but Andrew (from the TS team) recently
           | finished a massive overhaul of our module docs: https://www.t
           | ypescriptlang.org/docs/handbook/modules/introdu...
           | 
           | The "theory" page describes TypeScript's perspective on
           | modules. The "reference" page documents things from the "as
           | I'm walking a file tree" perspective (among many other
           | details). The "guides" page also provides recommendations for
           | certain kinds of projects.
        
       | paradite wrote:
       | I am pretty sure "type": "module" doesn't work with React
       | Native/Expo and jest (in 2022 last time I tried).
       | 
       | If you Google the error you will get stackoverflow posts with
       | hundreds of upvotes.
       | 
       | And that's the main problem with using ESM - 3rd party library
       | support. It is trivial to do hello world in ESM with Node.js, but
       | try that with 10 dependencies and quickly you will be hit errors.
        
       | Rapzid wrote:
       | Module resolution "bundler".
       | 
       | ts-node --esm --swc
       | 
       | Haven't really had any issues with this in a long time.
        
       | tuyiown wrote:
       | Add eslint and jest to pull your hairs of you head. I managed to
       | get it right last week, but I'm pretty confident that next
       | upgrade I'll have to revise most of it.
        
         | rickstanley wrote:
         | Have you considered using Vitest? Its performance has had a
         | significant impact on my workflow and the workflow of my
         | colleagues. It supports ESModules by default.
        
           | tuyiown wrote:
           | Ah! thanks a lot, I'll give it a good look next round, but I
           | won't have much difficulty moving from jest, because its old
           | roots triggers too much unexpected and hard to anticipate
           | constraints.
        
       | drtgh wrote:
       | Node.js, TypeScript (compiled script...), ESM modules, versions,
       | and the dependencies tree hell... You guys are adopting the
       | masochism, the problem is that you are dragging the rest of us
       | into that hell.
        
         | bovermyer wrote:
         | I'm going through a special version of this hell right now at
         | work. I'm updating old Lambdas that are on the node.js 12
         | runtime.
         | 
         | Some of them have internal dependencies that just _no longer
         | exist_, or aren't compatible with Node past 14.
         | 
         | Meanwhile, all I had to do to update old Python Lambdas was
         | just update the runtime itself.
        
           | postalrat wrote:
           | https://www.google.com/search?q=python+version+hell
        
             | bovermyer wrote:
             | Note that in my original comment, I didn't say Python
             | doesn't have version problems. I said my (specifically my)
             | Lambda version migration problems were much worse with
             | Node.js than Python.
             | 
             | Also, I'm vaguely offended that you used a "let me Google
             | that for you" reply as your sole comment. Did you really
             | have nothing more intelligent to add than low-effort snark?
             | Go back to Reddit.
        
               | postalrat wrote:
               | A lot of people have versioning problems in all
               | languages. You said "Meanwhile, all I had to do to update
               | old Python Lambdas was just update the runtime itself. ".
               | You know that isn't always true in Python that you just
               | update the runtime and nothing goes wrong.
        
         | dclowd9901 wrote:
         | It's only the module resolution bullshit. Typescript is
         | amazing, but module resolution between the browser and node is
         | so terribly fraught it kills the whole experience.
        
         | postalrat wrote:
         | What is the alternative? Commenting on hn and reddit?
        
       | dangoodmanUT wrote:
       | This is why I use bun now! It just works, NodeJS is such a shit
       | show right now, feels like the python 2->3 move.
        
         | davidy123 wrote:
         | I tried to use Bun but it doesn't support some low level Node
         | APIs properly, in my case for Playwright. Keeping an eye on it
         | though, what I saw seeemed promising.
        
           | sroussey wrote:
           | Make an issue. I did so for various compat issues and they
           | are fixed now.
        
             | davidy123 wrote:
             | There are already long running issues on this topic.
             | https://github.com/oven-sh/bun/issues/2492
        
         | jzig wrote:
         | I've been curious about using Bun. Could you point to an
         | example of something like Node backend code that's written in
         | TS using Bun?
        
       | monooso wrote:
       | I see (and have participated in) a lot of this "just copy this
       | thing, trust me it works" type of content related to Node and
       | TypeScript.
       | 
       | It makes me wonder why Deno [1] still seems to be such a niche
       | choice. Most of these headaches just go away.
       | 
       | Does anyone here prefer Deno for new projects? And if not, why?
       | 
       | [1] And Bun, although that's much newer.
        
         | mark_and_sweep wrote:
         | Being using Deno for new projects for years now. Not looking
         | back.
        
           | robbywashere_ wrote:
           | What are the advantages of deno over node?
        
             | flohofwoe wrote:
             | Not the parent, but one very nice aspect is that an entire
             | working Deno installation is just one file: the actual deno
             | executable.
             | 
             | ...when installing via homebrew on Mac you get 3 more files
             | which look like shell-completion definitions:
             | bin/deno         etc/bash_completion.d/deno
             | share/fish/vendor_completions.d/deno
             | share/zsh/site-functions/_deno
        
               | e1g wrote:
               | Both Node.js and Bun are also single executables. Node.js
               | doesn't (yet) transpile TS for you, and that's a single
               | dependency away.
        
               | flohofwoe wrote:
               | Yeah I was confused that the Node installation directory
               | was showing me 18k files in several thousand directories,
               | but these seem to be global npm installs which npm seems
               | to put into the node installation directory (which tbh is
               | weird, I would expect those somewhere in my user
               | directory).
        
         | flohofwoe wrote:
         | I prefer Deno over Python now for "cross-platform shell
         | scripting", because the "import directly from a github
         | repository" is very nice for that use case. Haven't tried it
         | yet as direct replacement for npm/node.js though (mainly
         | because I'm unsure yet how well it works as a drop-in
         | replacement when other people continue using npm and node.js).
        
         | vinibrito wrote:
         | Deno still has quirks, like not running on ARM processors.
        
           | mmastrac wrote:
           | I work on Deno, specifically the CLI. We support both Mac and
           | Linux ARM, though the Linux ARM builds are currently produced
           | by a third party contributor.
           | 
           | If you have specific issues with ARM, I'm certainly
           | interested in fixing those. I don't have any timeline for
           | when we'll add Linux ARM as a binary release target but I'm
           | happy to ensure any ARM-only bugs get the proper attention.
        
             | no_wizard wrote:
             | Does that mean deploying Deno to AWS Graviton is an issue
             | currently?
             | 
             | Thats the use case I have in mind to cut costs
        
               | mmastrac wrote:
               | I haven't specifically tested it but it _should_ be
               | supported. I don't have easy access to graviton instances
               | at this moment, but I've previously used
               | https://github.com/LukeChannings/deno-arm64 with great
               | success.
               | 
               | As long as your ARM OS is 64-bit, Deno should function
               | properly. 32-bit _might_ be supported, but TBH we don't
               | do any testing of those configurations as far as I'm
               | aware.
        
           | flohofwoe wrote:
           | Weird, when I run 'file deno' on my ARM Mac I get:
           | deno: Mach-O 64-bit executable arm64
           | 
           | ...also haven't experienced any problems so far.
        
             | spion wrote:
             | How about in Docker on ARM Mac?
        
               | mmastrac wrote:
               | No official docker images, but lukechannings maintains
               | ARM/Linux builds and an unofficial docker container that
               | are well supported:
               | 
               | https://hub.docker.com/repository/docker/lukechannings/de
               | no
        
         | willsmith72 wrote:
         | I've tried both, and love their potential.
         | 
         | I would highly advise any startup considering using them to
         | reconsider. You don't want your business to being running into
         | rough edges all day. You don't want to be reinventing things
         | all day.
         | 
         | They're fun, and especially deno is really fun. It feels more
         | like go, where you control everything.
         | 
         | But they're still not nearly as productive as node
        
           | monooso wrote:
           | Can you expand on what you mean by "not nearly as productive
           | as node"? I've found the opposite to be true, because of the
           | simplified tooling.
           | 
           | That said, most of my Deno projects have been fairly basic,
           | so I'm curious if there's a point at which the early wins
           | give way to hidden pain points.
        
         | ravenstine wrote:
         | Yeah, I use it for anything new, though so far it's been
         | primarily hobby projects, including a sort of larger one I
         | haven't gotten off the ground yet.
         | 
         | I wouldn't necessarily suggest that a newbie programmer go
         | right to Deno yet because today you still have to be prepared
         | to deal with some differences and quirks.
         | 
         | But here is why I like Deno:
         | 
         | - Typescript pretty much Just Works (TM) out of the box without
         | having to think about it
         | 
         | - More web/browser APIs right out of the box with less Node-
         | specific weirdness. Anything that is Deno-specific (such as
         | anything that lives on the Deno global) is, in my opinion,
         | better designed than Node's APIs.
         | 
         | - Requiring file extensions in import specifiers makes total
         | sense to me. Some people think this is stupid, but I see no
         | reason not to make them actual file paths and not this sort of
         | pseudo file path that omits the extension.
         | 
         | - I like how Deno can bundle your application into a single
         | executable.
         | 
         | - Testing framework and linter are built right in. Which is
         | great because, let's face it, most of us have been using such
         | things for a very long time now.
         | 
         | - Being able to pull in modules from the web without NPM is
         | fantastic.
         | 
         | - Node.js and NPM compatibility has gotten _way_ better
         | recently.
         | 
         | - Binary data is handled as Uint8Array rather than using a non-
         | standard Buffer like in Node. Makes total sense. Skip the
         | middle-man and just give me the bytes in a widely compatible
         | form.
         | 
         | - Granular security with strict permissions by default is
         | really nice. Sometimes I do want to import a module but then
         | have a guarantee that third-party code won't phone home. It's
         | also flexible enough that you can allow your own code to reach
         | your own domains but then some module you import from elsewhere
         | doesn't send data to some other domain. I'd still choose to not
         | use such modules, but it's good that you can mitigate the risk
         | of malicious code without having to do anything.
         | 
         | And sure, Node has improved a lot since the inception of Deno
         | and will continue to improve. It can probably do some of these
         | things and may end up having more parity with Deno. I don't
         | think that Node is bad. I still use Node, primarily at work,
         | and in cases where a package has maintainers that refuse to
         | support Deno (ex. Playwright).
        
         | conaclos wrote:
         | I would love to use Deno, however it is not totally compatible
         | with the TypeScript ecosystem: it is not possible to import a
         | TypeScript file using the `js` extension. This is a dealbreaker
         | for me because by adopting the `ts` extension you make your
         | code deno-specific; You can no longer use TSC, ESbuild and the
         | like.
        
           | wrs wrote:
           | Not sure what you mean? Our whole codebase is .ts files, and
           | we use tsc and esbuild without apparent difficulty.
        
             | conaclos wrote:
             | I mean, if you have a file `mod.ts`, in Deno you cannot
             | import `mod.ts` using the following import:
             | import {} from "./mod.js"
             | 
             | You have to write:                 import {} from
             | "./mod.ts"
             | 
             | ESbuild doesn't transform source imports. Thus, by
             | transpiling your code using ESbuild, you get an erroneous
             | import that leads to a runtime error in browsers and Node.
             | The case is worse for TypeScript, because it refuses to
             | tarnspile this code.
             | 
             | By the way, bundling with ESbuild is possible, however when
             | you write a library you generally want to transpile the
             | code, not to bundle it.
        
               | pipe01 wrote:
               | I use esbuild to import .ts regularly, I'm not sure how
               | you came to that conclusion
        
               | iainmerrick wrote:
               | ESbuild has handled ".ts" imports for as long as I've
               | used it.
               | 
               | TSC recently added a flag that allows ".ts" imports too.
        
           | bartlomieju wrote:
           | Bartek from the Deno team here. We are working on making this
           | possible with a flag in the upcoming release.
        
         | methodical wrote:
         | This may be a luddite-esque take, but personally, I'm very
         | hesitant to use Bun on any meaningful project at the moment. It
         | screams too-good-to-be-true right now. I also believe that I
         | may have heard of some people running across issues with it
         | recently, although I maybe conflating my memory of it with
         | something else. That, and, while I understand the namespace
         | pollution with JS packages, saying that I use "Bun" for my
         | projects is a bit of a turn-off, to be quite honest. I may try
         | it for some pet project in the near-term future but if I was to
         | make a choice for anything else I see operating long term I'd
         | be much more inclined to use Deno, although I still think even
         | that is probably a bit less established then I'd prefer, so I'd
         | probably still use Node until Deno matures a bit more.
        
           | plopz wrote:
           | i think its reasonable to hesitate on using something less
           | than 2 years old. it does a lot of things that look good to
           | me, but im happy to wait a few years and see. it still needs
           | to get buy in from people who maintain packages, for example
           | just try using puppeteer with it. and its also not clear to
           | me how its going to make money.
        
         | davedx wrote:
         | Because deno is strongly opinionated on things other than the
         | language and module system. I don't want to use golang style
         | dependencies. I don't want all the upsells that come with using
         | deno. It's an island unto itself.
        
           | monooso wrote:
           | Upsells?
        
             | yencabulator wrote:
             | They are pushing their SaaS pretty hard, these days.
        
               | imbnwa wrote:
               | Bun is gonna prolly end up doing the same thing though
        
         | keb_ wrote:
         | Deno is great, and I use it where I can, but a lot of front-end
         | tooling still treats it like a second-class citizen including
         | esbuild.
        
         | talkingtab wrote:
         | Prefer not to use Deno.
         | 
         | First, my personal choice is not to use TypeScript. For me it
         | just adds a layer of complexity that adds very little. That I
         | am a sole developer certainly is a factor in that decision. And
         | history. I worked with Java for a long time, with all the
         | safety it provides, only to find that PHP and JavaScript
         | programmers could ship in 1/4 the time with the same level of
         | functionality. I find that passing named parameters:
         | `foo({animal: "duck"})` makes my plain old javascript much more
         | robust, with very little cost.
         | 
         | So strike #1 against Deno is that it puts typescript much more
         | in the foreground.
         | 
         | Strike #2 is that Node works. Not because it is right, but
         | because services make sure they work with node. They don't put
         | the same effort into making things work with Deno.
         | 
         | I needed to write code using Deno that talked to a Digital
         | Ocean managed Postgres database. I spent three days. Then I
         | decided not to use Deno. Was this Deno's fault? No. But if you
         | need to get things done and one in 1000 of those things works
         | in Node but not in Deno, then the choice is straight forward.
         | 
         | I'm not saying these are good reasons, but I did try Deno and
         | wanted it to work.
        
           | petre wrote:
           | While I mostly agree with you, I hope deno removes at least
           | part of the nodejs mess when becomes ready for prime time.
           | It's already better designed in so many ways. Then I can
           | safely ignore the typescript functionality that, like you
           | said, ads too little value for me. This is mostly wishful
           | thinking. If deno doesn't deliver, maybe bun will. The funny
           | thing is they are trying to improve deno by adding
           | compatibility to the same nodeisms that make node such a
           | messy experience, like package.json and node_modules. Once
           | these will get used out of habbit, there is no going back.
        
       | davidy123 wrote:
       | I'm going to keep hitting reload on this page until someone
       | solves some of the worst problems of my work life right now;
       | getting a npm monorepo with typescript, eslint and jest working
       | smoothly. Thank you to whoever(s) that is. I'm trying to make a
       | public project, but building/developing with it is successive
       | layers of sometimes-works voodoo that have nothing to do with the
       | project goals. Somewhat compounded when members of nx (nee lerna)
       | popped in to try to help, adding another layer of sometimes-
       | works. As it is, DX depends on a fast computer to basically
       | rebuild the whole thing each time, or running build & test in a
       | dozen workspaces, because I haven't found any other reliable
       | "workflow."
        
         | searchableguy wrote:
         | We gave up and switched to vitest.
        
           | flohofwoe wrote:
           | +1 for vitest :D I was amazed that it "just worked" after
           | struggling for hours getting jest to work because of silly
           | file extension problems (really... what's up with that...
           | wouldn't that be easy to fix if the Node.js and Typescript
           | teams would talk for 5 minutes and agree on one approach?)
        
           | davidy123 wrote:
           | I don't use Vite though. Aside from typescript, I'm trying to
           | be as vanilla/unopinionated as possible, using Web Components
           | for example. And there are hundreds of Jest tests I don't
           | want to port.
        
             | flohofwoe wrote:
             | You can use vitest like a standalone testing tool, it will
             | install vite as dev-dependency but you don't need to build
             | your whole project around vite.
             | 
             | In my case it was literally a drop-in-replacement for jest,
             | done in two minutes and without a config file. A simple
             | config file only was required a bit later when I added
             | test- and coverage-reporting as junit.xml and cobertura
             | format for Gitlab CI.
             | 
             | Didn't even have to change a single line of testing code (I
             | didn't use Jest's mocking magic in that project though).
        
               | davidy123 wrote:
               | Thank you, it sounds pretty good, especially solving the
               | modules problem. I will look into it when finished
               | current sprint.
        
         | tommy_guo wrote:
         | This is the current setup I'm using for my TypeScript monorepo:
         | https://github.com/tommyguo/node_monorepo. I tried avoiding
         | Lerna because I didn't feel like I needed it. Happy to hear
         | feedback!
        
           | davidy123 wrote:
           | Thank you, I will take a look after current sprint.
        
         | dimgl wrote:
         | We dropped Jest and switched to Vitest across the entire stack.
         | It's a shame what happens to these projects over time...
        
       | resters wrote:
       | I thought there were "presets" that NPM and Yarn knew about to do
       | this kind of thing...
        
       | sirius87 wrote:
       | The current ESM experience makes it seem like decision-makers in
       | the node.js project were wilfully oblivious to how large the
       | TypeScript community was and how it was being used in node
       | modules and projects. It really does feel like the maintainers
       | focus was on JS and harmony with TypeScript's evolution was low
       | on the priority list.
       | 
       | Meanwhile anyone using an intersection of TypeScript with jest
       | and any of sindresorhus' libraries when he flipped to ESM for his
       | bajillion libraries immediately felt the downside and moved hard
       | away from ESM.
       | 
       | Imagine the mind-boggling hours lost just to get these
       | export/import formats to glue.
        
         | madeofpalk wrote:
         | I really enjoy frontend/node/typescript development. I roll my
         | eyes whenever the HN-types complain about CSS or frontend
         | development being a hellhole. Mostly the comments I see seem
         | ignorant or impatient ("Why doesn't this thing work without be
         | bothering to learn it?")
         | 
         |  _However_ , the intersection of typescript, nodejs, and ES
         | modules is consistently the most frustrating experience I ever
         | have. Trying to figure out which magic incantation of
         | tsconfig/esbuild/tsc/node options will let me just write code
         | and run it is a fools errand. You might figure something out,
         | and then you try to use Jest and then you descend into madness
         | again.
         | 
         | The biggest tip I can give people is to ditch ts-node and just
         | use (the awkwardly named) tsx
         | https://github.com/privatenumber/tsx, which pretty much just
         | "mostly works" for running Typescript during dev for node.
         | 
         | The problem mostly seems to stem for all the stakeholders being
         | pretty dogmatic to whatever _their_ goals are, rather than the
         | pragmatic option of just meeting people where they are. I
         | really wish the Node, Typescript, Deno /Bun, and maybe some
         | bundler people would come together and figure out how to make
         | this easier for people.
        
           | sirius87 wrote:
           | Totally agree.
           | 
           | It's doubly frustrating because a standard for authoring
           | modules across browser and server platforms such as ESM is a
           | good thing. But it's a bit arrogant to expect module authors
           | across TS and JS ecosystems to ship overnight. Beginners may
           | just turn to Deno or Bun simply because hundreds of coding
           | tutorials and snippets no longer work.
           | 
           | Or, when you finally get a TS config that works but then you
           | import @aws-sdk/* or prisma seeds and then you _really_ rip
           | your hair out.
        
             | quickthrower2 wrote:
             | I am finding whatever NextJS does "just works" and I hit
             | issues when I roll my own stuff. But I have't dug deeply
             | into how they do it yet.
        
           | Shacklz wrote:
           | Couldn't agree more. Love the frontend-space, love the
           | ecosystem, but hate the whole ESM vs. CJS fiasco with a
           | passion.
           | 
           | To some degree, I think the typescript-team itself also has
           | to take some blame here. I understand their point that they
           | do not want to do any rewrites, and to some degree it makes
           | sense, but if the ecosystem as a whole really wants to move
           | forward to a common understanding of how it _should_ work,
           | someone needs to do the heavy lifting for dev-experience, and
           | right now they 're best-equipped to actually solve the
           | problem, or at the very least help us a lot in doing so.
           | 
           | Their dogmatic approach makes sense for the scope they set
           | out with when starting with typescript but in my eyes refuses
           | a bit the reality the ecosystem currently finds itself in.
           | And I'm saying this as an absolute ts-fanboy; it's one of the
           | very few things about typescript that I take an issue with.
        
             | eyelidlessness wrote:
             | I'm curious what it is you think TypeScript could do, or
             | could do differently, to address the situation. Or what you
             | think they've been dogmatic about, and what reality they've
             | refused [to see? to accept? to fix? unclear what you mean]?
        
           | galactus wrote:
           | So much this.
        
           | teaearlgraycold wrote:
           | Once Bun is feature complete I'm jumping ship
        
           | johnfn wrote:
           | Agreed with everything, except this:
           | 
           | > I really wish the Node, Typescript, Deno/Bun, and maybe
           | some bundler people would come together and figure out how to
           | make this easier for people.
           | 
           | Bun _has_ solved this. Bun is straight-up magic; they 've
           | implemented tons of hacks and heuristics so everything just
           | works. Bun can even handle ridiculous or otherwise invalid
           | code, like having import and require in the same file.
        
             | madeofpalk wrote:
             | My point here is that Bun should go teach Node how to be
             | pragmatic and build a good developer experience
        
               | johnfn wrote:
               | Oh, yeah, totally agreed then.
        
             | yencabulator wrote:
             | > tons of hacks and heuristics
             | 
             | So, business as usual in the Javascript space. That's how
             | the ecosystem got here, and why nothing works reliably.
        
               | johnfn wrote:
               | Like I said in my comment, Bun works just fine. You seem
               | to have taken 5 words I said out of context to justify
               | something that I didn't say. It's not true that "nothing
               | works reliably". Bun works reliably.
        
             | edgyquant wrote:
             | I've never heard of bun before today. Why is it so low key
             | and what's it main selling point?
        
               | kristiandupont wrote:
               | What are your main sources of tech news? Bun has been
               | quite a darling here for a while..
        
               | phatskat wrote:
               | My own primary news source these days is HN and I've
               | missed anything about it, your comment isn't really
               | helpful.
        
             | kaliqt wrote:
             | How hard would it be to migrate a node project to Bun
             | though? I want to move, but I'm not sure.
        
               | johnfn wrote:
               | Should be a drop-in replacement.
        
             | mardef wrote:
             | Bun has solved this, unless you have developers on Windows.
        
           | brundolf wrote:
           | For projects where I can, I've moved to Deno and never looked
           | back. It's blissful over there
        
             | yencabulator wrote:
             | Except when you need libraries from npm, and then you have
             | a choice 1) use npm: imports and watch things not work 2)
             | use esm.sh imports and watch supposedly-immutable URLs
             | change their contents all the time, _and_ be ready to pile
             | on kludges to get transitive dependencies to behave.
        
               | bartlomieju wrote:
               | Bartek from the Deno team here. You can also use
               | `package.json` and bare specifiers with Deno. We also
               | recently added `--unstable-byonm` flag (Bring Your Own
               | Node Modules) that allows you to manage `node_modules/`
               | be the package manager of your choice. In other words,
               | you should be able to drop Deno into an existing Node
               | project.
        
               | brundolf wrote:
               | I have had mixed results when using NPM libraries, but I
               | also haven't run into any cases yet where I absolutely
               | needed them
               | 
               | Some stuff you might reach out to NPM for is built into
               | Deno's standard library. Other stuff has become built-in
               | JS language features over the years. And the ecosystem,
               | while nowhere near as big as NPM's, seems to have all the
               | most important stuff at this point, at least for back-end
               | work
               | 
               | And if I have to fill gaps by reinventing some small
               | wheels here and there, or by interning and converting an
               | NPM library, that's still worth it to me to avoid all the
               | tooling headaches
        
           | lacrosse_tannin wrote:
           | How about not using Jest?
        
           | zerobrainwash wrote:
           | Relieved to hear I'm not the only one. I always blamed myself
           | for not understanding it deeply enough. But admittedly, it is
           | a shit snow and the most frustrating part of development.
        
           | qudat wrote:
           | > I roll my eyes whenever the HN-types complain about CSS or
           | frontend development being a hellhole. Mostly the comments I
           | see seem ignorant or impatient ("Why doesn't this thing work
           | without be bothering to learn it?")
           | 
           | I'd also argue that outsiders looking into all the complexity
           | are ignoring the complexity within their own specialization:
           | https://bower.sh/front-end-complexity
           | 
           | It's hypocritical thinking.
        
           | cjr wrote:
           | Hard agree, especially with your first two paragraphs :)
           | 
           | The biggest tip I would add is to bin jest and start using
           | vitest.
        
         | rtpg wrote:
         | Honestly I think the blame[0] is to share across the board. I
         | have read through a bunch of typescript lang issues on this
         | topic, and the general issue is that Typescript doesn't want
         | tsc to do certain kinds of rewrites during compilation (code
         | transpilations that go beyond the most simple things).
         | 
         | This makes sense but honestly means a lot of QoL fixes are
         | kinda impossible to do. At this point I, personally, would
         | almost want tsc (the compiler component) to stop being almost a
         | good bundler and remove some features. Every project I've
         | worked on that uses tsc directly ends up needing a "come to
         | Jesus" moment where a "real" bundler gets introduced and
         | suddenly a lot of stuff becomes easier. Doubly frustrating for
         | me to feel this because tsc does a lot of stuff and it is hard
         | to imagine how Typescript the language moves forward without
         | Typescipt the compiler. I just really don't want to type `.js`
         | for files that are, pre-build, `.ts`.
         | 
         | [0]: "blame" here meant in the weakest sense of "there are
         | people who could make decisions in another way to make this
         | better". Not so much in assigning moral blame
        
           | iainmerrick wrote:
           | I still don't fully understand why TypeScript needed to be
           | involved in the discussion at all. TSC tries to do far too
           | much and doesn't do most of it very well. The tsconfig format
           | is restrictive and annoying.
           | 
           | TS would be a lot better if it were just a type checker and
           | nothing else (which is more or less what you get when you
           | switch to a proper bundler).
        
         | mofle wrote:
         | TypeScript had years to prepare for ESM, but they did not. Same
         | with Jest. ESM was developed in the open and anyone could
         | participate, including the TypeScript team. You are talking
         | like ESM just happened overnight. It had been in development
         | for 10 years.
         | 
         | Node.js released initial ESM support [1] in Node.js 12.17 in
         | May 2020, 2 years later (!), TypeScript finally added support
         | for ESM [2].
         | 
         | Here's a straight forward guide on how to use TypeScript with
         | ESM:
         | https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3...
         | 
         | [1]: https://nodejs.org/en/blog/release/v12.17.0
         | 
         | [2]: https://devblogs.microsoft.com/typescript/announcing-
         | typescr...
        
           | sirius87 wrote:
           | Curious to see how this one decision plays out for nodejs IF
           | -
           | 
           | - module authors increasingly adopt ESM
           | 
           | - TypeScript experience with Deno is butter smooth
           | 
           | - npm packages work with Deno
           | 
           | - performance characteristics are similar
           | 
           | - DX for beginners just works (compared to thousands of stale
           | articles with `require('pkg')` and `npm install pkg@latest`
           | for nodejs)
        
           | wwwigham wrote:
           | > ESM was developed in the open and anyone could participate,
           | including the TypeScript team.
           | 
           | This point stings for me, personally, since _I_ was the
           | TypeScript language dev _in_ this wg trying to make our
           | concerns noted, because we certainly did participate. However
           | the group largely deadlocked on shipping with ecosystem
           | compatibility measures, and what you see in node today is the
           | "minimal core" the group could "agree" on (or be bullied into
           | by group politic - this was getting shipped weather we liked
           | it or not, as the last holdouts). The group was dissolved
           | shortly after shipping it, making said "minimal core" the
           | whole thing (which was the stated goal of some engineers who
           | have since ascended to node maintainer status and are now the
           | primary module system maintainers), with the concerns about
           | existing ecosystem interoperability brought up left almost
           | completely unaddressed. It's been a massive "I told yo so"
           | moment (since a concern with shipping the "minimal core" was
           | that they would _never_ be addressed), but it 's not like
           | that helps anyone.
           | 
           | Like this shipped, because _in theory_, it'd be a non-
           | breaking from a library author perspective to get node's CJS
           | to behave reasonably with ESM (...like it does in `bun`, or
           | any one of the bundler-like environments available like `tsx`
           | or `webpack` or `esbuild`), and _in theory_ they're open to a
           | PR for a fix... I wish anyone who tries good luck in getting
           | such a change merged.
        
             | stephen wrote:
             | Fwiw I appreciate your effort! That sounds really
             | frustrating.
             | 
             | I agree the recent bun/tsx/esbuild (but bun especially) has
             | shown the node CJS/ESM fiasco was a bit of an emperor-
             | wearing-no-clothes moment, where I think us every-day JS
             | programmers just trusted the node devs at their word, that
             | CJS/ESM had to be this painful...
             | 
             | But now, seeing that it doesn't have to be that way, it's
             | like wait a sec...the last ~5 years of pain could have been
             | avoided with some more pragmatic choices? Oof.
        
           | eyelidlessness wrote:
           | > TypeScript had years to prepare for ESM, but they did not.
           | 
           | How did they not? This is confusing to me, as I've been
           | authoring and emitting ESM in TS for quite a few years now.
        
           | joshkel wrote:
           | As someone who uses Jest and alternatively enjoys and is
           | frustrated by it, this isn't all Jest's fault. Node is just
           | now releasing fixes for [significant memory leaks](https://gi
           | thub.com/jestjs/jest/issues/11956#issuecomment-180...) around
           | ESM support within the [VM
           | APIs](https://nodejs.org/api/vm.html) that Jest depends on.
        
         | wruza wrote:
         | _when he flipped to ESM for his bajillion libraries_
         | 
         | But that was just a short migration period. It's only been
         | three years and we almost fixed all these issues. This one is
         | probably the last one, this month.
        
           | sirius87 wrote:
           | FWIW it wasn't meant to sound critical of him, his
           | contributions are much loved and his attempt to push to ESM
           | was also in good spirit with his helpful gist on the issues,
           | but ESM was no silver bullet for the wide mix of imported
           | modules in some projects.
           | 
           | I remember spending a weekend simply inlining all his module
           | code directly into a project to sidestep the type module
           | change. Fun.
        
             | wruza wrote:
             | Not fun really. I am critical (of everyone involved). We
             | were asked to migrate under a promise it'll be over soon.
             | "It only needs a little kick", they said, ignoring everyone
             | and vandalizing the loved contributions. Years passed and
             | we:
             | 
             | - still stumble upon it even in _fresh projects_
             | 
             | - have no esm-only bundle-less projects in practice,
             | because it's still impractical
             | 
             | - learned a bookshelf each about the thing that should just
             | work
             | 
             | - watch entire toolchains decay into a shitton of date-
             | dependent issues
             | 
             | - have no clear troubleshooting paths, even when we have a
             | clue what's wrong
             | 
             | They forcefully promised some bright future, we helplessly
             | agreed.
             | 
             | Where the bright?
             | 
             | Three years later, I lost half an evening to [1] again. My
             | love and politeness reserves are depleted.
             | 
             | [1] https://news.ycombinator.com/item?id=38365983
        
         | jampekka wrote:
         | Makers of ESM were wilfully oblivious to sanity. CommonJS
         | was/is one of the, if not the, best module and dependency
         | systems out there.
         | 
         | https://gist.github.com/joepie91/bca2fda868c1e8b2c2caf76af7d...
        
           | brundolf wrote:
           | Being imperative instead of declarative, it hinders a host of
           | key optimizations like parallel loading and dead code
           | elimination
        
             | jampekka wrote:
             | This is discussed in the link I posted. Bundlers manage to
             | statically analyze CommonJS just fine. With
             | require("stringliteral") and exports.thing = thing, that
             | cover 99.9% or so usage, this is just as easy to statically
             | analyze as ESM.
             | 
             | Saying that you need declarative for static analysis is
             | like saying tail call optimization is impossible.
             | 
             | And if a stricter module system would be still required, it
             | could have been quite easy to make compatible with, well,
             | require.
        
               | petre wrote:
               | Require is fine but I totally hate the CJS exports. Feels
               | like writing '90s era Perl code. On the other hand ESM
               | dynamic imports like
               | import('this').then(r => that())
               | 
               | rather suck.
        
           | madeofpalk wrote:
           | I find this mostly unconvincing (except for the part where
           | all the tools messed this up and made the problem more
           | difficult).
           | 
           | It's not clear to me how you get top-level await with CJS
           | with significant drawbacks OR breaking changes that would
           | just end up back up in ESM land.
        
             | jampekka wrote:
             | The convoluted byzantine mess that is ES top level await is
             | a self-inflicted problem stemming from the ESM bizarre pipe
             | dream that static import won't be a blocking operation for
             | code that depends on the imported code.
             | 
             | With blocking require there's of course no problem with top
             | level await. And having a thenable import doesn't even need
             | any language level support.
             | 
             | Yeah, you can parallelize static imports. But you can just
             | as well doing this by having a semantically blocking
             | require that is free to of course do whatever it wants as
             | long as the execution is sequential in effect.
             | 
             | If there's some dynamic trickery the implementation can't
             | figure out, just revert to blocking and nag in the console.
        
           | ptx wrote:
           | The post dismisses native browser support (a huge benefit of
           | ES modules) as "an utterly useless feature" that's
           | "unavoidably slow" because of the additional roundtrips
           | needed as the dependency tree is traversed.
           | 
           | But this problem has been solved by modulepreload[0], also
           | natively supported in the browser, which lets you specify the
           | modules upfront in the HTML, avoiding the need for additional
           | roundtrips. Tooling could help with generating the list of
           | preloads but is not necessary.
           | 
           | [0] https://developer.mozilla.org/en-
           | US/docs/Web/HTML/Attributes...
        
             | jampekka wrote:
             | Tooling could also analyze the dependencies and create
             | appropriate bundles of the code to avoid roundtrips.
             | Actually such tooling has existed for over a decade and are
             | used by practically all but simplest Javascript
             | applications.
             | 
             | I'm all for development without a compilation step. I've
             | written hacks to resolve node modules and transpile in
             | browser to avoid compilation. Implementing prefetching even
             | with this hack would be less hacky than going full circle
             | and injecting HTML tags to do the prefetching.
             | 
             | ESM is like XML: The problem it solves is not hard, and it
             | doesn't solve the problem well. Actually ESM it isn't even
             | close to solving the problem after trying for almost 15
             | years.
        
               | ptx wrote:
               | As you say, tooling can solve the problem. But with ES
               | modules and modulepreload, we can now (contrary to what
               | the post argues) also solve it without the tooling, which
               | is an improvement.
               | 
               | Yes, all but the simplest applications currently use the
               | tooling-based solutions, because there was no other way.
               | But now that we have an alternative solution, perhaps all
               | but the most complex applications will manage just fine
               | without tooling, using just the built-in module support.
        
         | alexcroox wrote:
         | Experienced that this week! Upgraded to node 20 and typescript
         | and his p-limit lib was the source of a lot of pain. No matter
         | how much I changed the tsconfig I just couldn't get it to work
         | with the subpath imports his lib used. Ended up downgrading the
         | lib to previous major and moving on.
        
         | andrewaylett wrote:
         | The good news is that one may use `expect` with Node's built-in
         | test runner -- the result feels fairly similar to using expect
         | with Jest.
         | 
         | Indeed, Node's test support can handle dynamic test creation,
         | so one can do crazy things like
         | https://github.com/andrewaylett/prepackage-checks/blob/main/...
         | -- that dynamically asynchronously executes NPM builds from
         | subdirectories, loading and running per-build expectations.
        
         | unflxw wrote:
         | My impression is that Node.js has to be dragged kicking and
         | screaming into any modern JavaScript development practices, and
         | each time, they try to support as little of it as possible as
         | they can get away with.
         | 
         | They have only last year actually rolled out a release that
         | uses ESM modules by default, when the bulk of the community has
         | adopted TypeScript and moved on to using ESM imports (even if
         | they are importing CJS modules under the hood)
         | 
         | They were really late to async/await, and even more so to
         | promises. The chaotic situation where each dependency bundled
         | its own promise library remained in Node.js years after
         | browsers shipped built-in promises. And it still hasn't
         | trickled down to their standard library, most of which is still
         | callback-based and needs to be "promisified" manually. Even
         | their support for fetch, which is eight years old at this
         | point, is still marked as experimental.
        
         | w3news wrote:
         | That it why i use native functions. No typescript syntax, no
         | jest. For testing i use just the native test runner, and that
         | works great with ESM. Jest has indeed still not good ESM
         | support, you can do some Babel trics, but makes the process too
         | complex. Best is to find an alternative, like the native test
         | runner. Also typescript try some things that are not stable at
         | ecma. It was too soon with the import/export, and dont use the
         | native way. Also commonjs is still the default at typescript
         | after compiling, but Node is moving to ESM as a default. I hope
         | typescript will use more native functions that are already
         | available and dont use their own way.
         | 
         | For me typescript syntax and jest is a no go.
         | 
         | Typescript is useful to check types, but i write just
         | JavaScript with JSDoc, and check it with eslint in typescript
         | modus.
        
       | bearjaws wrote:
       | Main reason I even tried bun out. Honestly 'just works', I've
       | only had one issue so far and it was with a unpopular compiled
       | module.
        
         | sroussey wrote:
         | I love it. Had some issues with terminal stuff, now fixed.
         | 
         | Just works, indeed.
         | 
         | But I have a difficult time trying to get a project make to
         | node/ts.
        
         | mst wrote:
         | I'm really enjoying bun for my own stuff but tsx looks more
         | promising for work projects.
        
       | solatic wrote:
       | Having tried to wrangle all of this both professionally and for a
       | side project, the link is an over-simplification. No, it won't
       | "just work".
       | 
       | Part of the problem is the fact that web browsers, Node.js, and
       | other JS runtimes have slightly different needs and expectations.
       | Part of the problem arises when you're trying to mix and match
       | web code, Node.js code, and other JS runtime code in the same
       | monorepo. There's no single magic-bullet configuration.
        
       | _nalply wrote:
       | One problem I encountered with ESM TypeScript development on the
       | browser without bundling: many Node packages aren't set up for
       | that.
       | 
       | You might ask why without bundling?
       | 
       | Sometimes you just want to start something simple on the browser
       | and compile to JavaScript on the fly.
       | 
       | I tried the dev server from Modern Web [0], and I liked it. I
       | program in TypeScript and the browser reloads whenever I save a
       | file. Of course I could set up a bundler and for a small program
       | waiting times are negligible. But I hate bundlers. I know it's
       | irrational, but nowadays I program for fun so I think I should
       | have the choice to reject bundlers.
       | 
       | This fails for many Node dependencies. There is a conflict
       | between CommonJS and ESM. I am not 100% sure that what I want to
       | achieve is impossible without forking dependencies and making a
       | small change.
       | 
       | I even found a way to have a CommonJs and ESM polyglot, but this
       | hack is extremely ugly. I named the hack modglot [1]. I don't
       | think this is a good idea and I don't understand enough to
       | propose something. I am somewhat dejected about the current state
       | of TypeScript development for the browser and paused development.
       | 
       | Now I am programming in Rust again just for fun, but if I return
       | to TypeScript, probably I will try out Deno.
       | 
       | [0]: https://modern-web.dev/guides/dev-server/getting-started/
       | 
       | [1]: https://github.com/nalply/modglot
        
       | cantSpellSober wrote:
       | Does Node.js plan to transpile TS out-of-the-box soon? (Picking
       | up a legacy project, can't swap out for Deno or another runtime
       | just yet)
        
         | khalidx wrote:
         | This would be a nice direction for the Node community. I wish
         | for this. Especially since so many other platforms are
         | supporting it out of the box.
        
       | tommy_guo wrote:
       | Sharing https://github.com/tommyguo/node_monorepo if this helps
       | folks. It's a Typescript monorepo template with everything you
       | need included.
       | 
       | I'm currently using this setup to run multiple services on AWS.
        
       | preommr wrote:
       | > Just add the following files and run npm run dev. You'll be
       | good to go!
       | 
       | This attitude just doesn't work for js ecosystem. I have some
       | shell scripts, vim config files, etc. that I don't remember what
       | they do, but I just copy over and they work.
       | 
       | Coding projects are different; they break all the time.
       | Especially with how fast the js/ts ecosystem works. One day, a
       | crucial library just decides that it's changed something that
       | doesn't work with the build process because there's so many
       | variations of them that they can't possibly all be tested
       | against.
        
       | bhouston wrote:
       | I did some experiments myself and settled on this template
       | repository:
       | 
       | https://github.com/bhouston/template-typescript-monorepo
       | 
       | This has a lot of features that work well together: - TypeScript
       | - ESM - Node.JS Server + React + Cli - Monorepository - Fast
       | Incremental Updates
       | 
       | Feedback welcome. I use this for about a dozen different projects
       | now.
        
       | conaclos wrote:
       | Some comments and suggestions:
       | 
       | - `importsNotUsedAsValues` is deprecated [0] since TypeScript
       | 5.2, in favor of `verbatimModuleSyntax` [1].
       | 
       | - I could set `module` to `Node16`. This automatically set
       | `esModuleInterop` to true.
       | 
       | - Also, to catch more issues, set `allowUnreachableCode` to false
       | and set `strict`, `noImplicitReturns`, `noImplicitOverride`,
       | `noFallthroughCasesInSwitch`, `exactOptionalPropertyTypes` to
       | true.
       | 
       | - Set `types` to the empty array `[]` to avoid loading unwanted
       | types.
       | 
       | - Enable `skipLibCheck` to avoid checking imported module types.
       | 
       | - Not sure that `declarationMap` is still useful nowadays.
       | TypeScript is now able to match directly against source files.
       | 
       | - Enable `composite` that in turns enables `incremental` and
       | `declaration` (declaration file emit). `composite` enables
       | project references which is useful in a monorepo setting or to
       | separate source and test files into two projects. See [2]
       | 
       | - Enable `checkJs` to type-check JavaScript files
       | 
       | To summarize:                 {         "$schema":
       | "https://json.schemastore.org/tsconfig",
       | "compilerOptions": {           "lib": ["ES2022"],
       | "module": "Node16",           "target": "ES2022",
       | "outDir": "./dist",           "composite": true,
       | "sourceMap": true,                "types": [],
       | "isolatedModules": true,           "resolveJsonModule": true,
       | "skipLibCheck": true,           "verbatimModuleSyntax": true,
       | "allowUnreachableCode": false,           "checkJs": true,
       | "exactOptionalPropertyTypes": true,
       | "noFallthroughCasesInSwitch": true,
       | "noImplicitOverride": true,           "noImplicitReturns": true,
       | "strict": true         }         "include": ["./src/**/*.ts"],
       | "exclude": ["./src/specific-file.ts"]       }
       | 
       | [0]
       | https://www.typescriptlang.org/tsconfig#importsNotUsedAsValu...
       | 
       | [1] https://www.typescriptlang.org/tsconfig#verbatimModuleSyntax
       | 
       | [2] https://www.typescriptlang.org/docs/handbook/project-
       | referen...
        
       | rglover wrote:
       | Hear me out: if you need to do this just to use a tool
       | effectively, maybe it's a bad tool.
        
         | wruza wrote:
         | We're open to suggestions!
        
           | rglover wrote:
           | In this specific context: just use plain JavaScript with
           | default args and your own, inline type checker functions. No
           | need for stuff like this and you can customize type checks to
           | your heart's content.
        
       | wruza wrote:
       | Ah, I upgraded just yet, realized node 20 broke the way ts-node-
       | esm loader works. Had to downgrade to 18, because there's no
       | functionality I really need from 20. Also Vite complained when I
       | tried node 19, because it requires <=18 && >=20 for some reason
       | (probably good one).
       | 
       | I'm maintaining a few pristine example projects to keep track of
       | these ways and test them periodically. This iteration probably
       | had the shortest lifetime. I didn't manage to develop even a
       | single toy project before something got obsoleted again. Love
       | this community. Looking forward to solve a handful of brand new
       | issues with tsx.
       | 
       | I wish there was some IDEish starter pack which you could install
       | and start writing code anytime, without investigating issues with
       | running a damn interpreter.
        
         | jb_hs wrote:
         | My guess is node 19 isn't an LTS version and it's hard enough
         | to maintain just the LTS versions. Probably a requirement that
         | will save a lot of pain...
        
       | c-hendricks wrote:
       | I've been trying to upgrade a couple of libraries we use
       | internally at work to output CJS + ESM, from a typescript
       | project, and have the output be 1-to-1 files (so, no bundling /
       | rollup / whatever you want to call it).
       | 
       | What a frustrating experience it has been.
       | 
       | Using unbuild "works", but
       | 
       | - For the life of me, I can't get unbuild to generate `.d.mts`
       | files when my source files don't have `.mts` extensions. Luckily,
       | when the library is used in a downstream project and a `.mjs`
       | file is imported, TypeScript properly loads the `.d.ts` file
       | anyways
       | 
       | - When it comes to a downstream project, TypeScript doesn't seem
       | to work with export maps. People say it does, but maybe because I
       | don't have `.d.mts` files TypeScript is saying it can't find type
       | information? It _does_ work with simple export maps, but if I say
       | `'./ _' : './dist/esm/_'` so the downstream project doesn't have
       | to manually import from `dist/esm` I see the issue
       | 
       | - Using the "esm" module / moduleResolutions + converting my
       | files to `.mts` + changing imports in the source to import the
       | non-existant `.mjs` files results in a CJS bundle that tries to
       | require a `.mjs` file, which unbuild has built with a `.js`
       | extension, so it throws an error because it can't find the file.
       | 
       | - For some reason unbuild mucks with the hashbang line in my
       | _CJS_ `bin` script, the ESM one it doesn't touch
       | 
       | Ugh.
        
         | moltar wrote:
         | Try tsup it does just work unless your package is doing
         | something funny.
         | 
         | Then do a check with attw cli tool and it'll report your compat
         | mistakes with links to explainer docs.
        
           | c-hendricks wrote:
           | That's what I tried using before and I had even less luck /
           | had to do more fandangling, but thanks for the suggestion.
           | 
           | Like I said, these are libraries whose "build" before was
           | just `tsc`, there's nothing funny going on.
        
       | dimgl wrote:
       | +1 to what one of the commenters is saying. You can skip all of
       | this and just use `tsx`. I currently sponsor that project. That's
       | how impactful it was on all of my development.
       | 
       | I will say that it's kind of sad that Node.js has devolved into
       | this.
        
       | apitman wrote:
       | Typescript is a huge improvement over JS, but I never use it. My
       | rule of thumb is that if TS provides a tangible benefit, I have
       | too much complexity on the frontend.
        
       | kshahkshah wrote:
       | Now add eslint and prettier :)
        
       | nop_slide wrote:
       | Could someone succinctly describe the situation between node ts
       | and esm?
       | 
       | I'm not very familiar with the ecosystem and trying to understand
       | what pain ports people are describing here in the comments.
        
       | awongh wrote:
       | I just got started with a Next.js project coming from React with
       | JS and.... another JS/TS rant incoming.....
       | 
       | For an ecosystem that purports to be ready for professional use
       | it absolutely boggles my mind that the tooling is stuck at this
       | very amateurish level.
       | 
       | Why isn't there a ready preset for me to use ESM syntax with
       | Next.js / Typescript?
       | 
       | What's wrong with the culture around Node/TS/JS tooling in
       | general that it's so consistently broken all the time? What the
       | hell.
        
         | eddd-ddde wrote:
         | Try QwikJS. It solves what you ask for, create a project and
         | you are ready to go.
         | 
         | Qwik feels so right to use, if you have 5 minutes you should
         | read about it: https://qwik.builder.io/docs/concepts/think-
         | qwik/
        
       | SnoozingBoa wrote:
       | Here comes a question what many of the people reading the
       | comments are thinking:
       | 
       | As of November 2023, what is the canonical way to set up a Node
       | project with Typescript and hot reload?
       | 
       | Minimal setup with least amount of configs and tooling. I am not
       | after any other tools like Bun.
        
         | ycombinatornews wrote:
         | Snowpack, parcel, esbuild. Minimal setup each. YMMV based on
         | how you plan to distribute the build results (package, site or
         | app) after.
        
           | vlod wrote:
           | Maybe I'm not getting it, but I just set up an express.js app
           | this last weekend with nothing much more than tsc
           | (typescript) and ts-node.
           | 
           | Do you need all that other stuff for a simple node app?
        
       | demondemidi wrote:
       | "...for a few months."
       | 
       | Until this github repo dries up the same way similar attempts at
       | this have.
        
       ___________________________________________________________________
       (page generated 2023-11-21 23:03 UTC)