1. 24
  1. 31

    It’s interesting what’s being included under the umbrella of “Typescript” in this post. As someone who’s been writing JS for the better part of 20 years, it’s generally been clear to me what’s JS, what’s Node vs browser, and how Typescript is a layer over JS. But if I was coming in today and trying to learn Typescript I would totally conflate all these things, too.

    Some concrete examples:

    The ecosystem is also pretty impressive. With over 1.3M npm packages available.

    I would bet that the vast majority of the packages on npm are pure JS with no Typescript support. Factor in popularity and you’ll see a lot more TS, but npm is a Javascript package repo, it predates Typescript by several years. It’s where you get Typescript-supporting packages from, but it’s not of Typescript.

    Typescript is also very async-friendly, and everything is single threaded.

    Javascript is also very async-friendly …

    But if I had to choose the thing I disliked the most… that would be the module system

    100% agree, and this is a place where adding in Typescript does makes things more confusing. It is massively frustrating when you run into module issues, and the sooner the ecosystem can get on the same page, the better. Though I suspect this pain will stick around for years. But the module issue also isn’t really of Typescript.

    I accept that these are probably all pointless distinctions to someone who’s trying to write some Typescript and deploy their code!


    Aside, since the author is here: I’m not sure if the bit about checking for a successful request is just an example for the blog post, but in case it’s not: Rather than checking the status code, from fetch you probably have a Response object, so you likely want the Response.ok property

    1. 7

      I’ve noticed this as well, similarly having used JS for 20+ years. It’s actually somewhat frustrating to me to hear people argue for TS using JS features because it shows a fundamental misunderstanding or lack of knowledge of the ecosystem and language itself.

      Not that this blog is arguing these points, but seeing TypeScript thrown around where it’s really just JavaScript is still difficult for me to see. JS is demonized while people sing the praises of TS, but quite frankly, if you could only use JS, you wouldn’t really notice that much of a difference.

      1. 2

        Yeah. I am actually aware of some of those distinctions. But you captured my point correctly! As a newcomer, as much as I am aware of those distinctions now, the post documents my journey learning through all of that, so I included some things even though today I know better (And I wish I had taken more notes!)

        All in all I am pretty happy: having started my career in the kernel, and now writing Javascript/Typescript… maybe I am finally full-stack?

        Thanks a lot for the Response tip! I’m learning stuff every day.

        1. 1

          Personally I found it hilarious, the bit with the response code. Here comes a hard-core systems-language, low-level guy, complains about types and stuff, then assumes that 2.03 equals 2. Like, I thought you guys are precise!

          Anyway, nice post for people trying to deal with TypeScript.

        2. 1

          I accept that these are probably all pointless distinctions to someone who’s trying to write some Typescript and deploy their code!

          Yes, but I’m going to pick on you a bit even though you “admit” this.

          The way you describe your examples as “That’s JavaScript, not TypeScript” or by distinguishing between JS, a browser engine, and Node.js is very similar to a scenario in which someone said “I’m switching from Rust to Java” and I chimed in and said “Actually, you’re writing Java on the Oracle JVM.”

          “Switching from Rust to TypeScript” could only possibly mean that the code they are authoring is written in TypeScript and that it’s running in whatever runtime matches the use-case that the Rust code would’ve been used for (so, likely Node.js).

          Is there anyone who doesn’t know that TypeScript is just a broken type system on top of JavaScript?

          1. 1

            100% agree, and this is a place where adding in Typescript does makes things more confusing. It is massively frustrating when you run into module issues, and the sooner the ecosystem can get on the same page, the better.

            One thing that helps in this regard is that libraries are starting to ship ESM-only, meaning if you’re still on the old CommonJS system or you’re using an older version of Node (pre-12), you can’t use that library anymore. This is going to incentivize a lot of people to upgrade, or rethink how they’re approaching JavaScript.

            1. 1

              that’s what one would logically assume would happen. But then look at python2 vs python3, which did a similar thing… Took at least 10 years to resolve.

              1. 1

                I definitely get that, and as someone who dealt with that whole transition in my own software, I distinctly remember the pain being caused by accidental upgrades to Python 3 or downgrades to Python 2.

                But I think the JavaScript package ecosystem is a bit different for a couple reasons:

                1. Python packages have classically been (and especially were around that time) much larger than JS packages. It takes longer to upgrade these packages, as they have a lot of interdependent code and potentially external libraries needing to be linked. A package like left-pad would have never existed in Python (you know, assuming Python didn’t have a proper standard library), because it just goes against the culture of packaging in that language. Instead, you might find a library that does all of the string manipulation functions. This is great for a language like Python where you are typically running it on a server, but not so great when you are thinking about pulling dependencies from all sorts of places on the web, essentially trusting the network with your package management.
                2. (somewhat related to the first point) JS packages are a lot more numerous than Python packages. As a result, we have all those memes about how node_modules/ is denser than a black hole or whatever, but the truth to that is due to all of the tiny packages in the JS ecosystem, just a single one updating to be ESM-only can cause some real peril in your dependency tree. This is why most libraries are doing CJS/ESM these days, but there are a few that are only distributing as ESM in order to help speed this transition along.
                3. Multiple runtimes depend on this package management standard. “ESModules” is effectively “standard JavaScript modules” at this point, as not only does this work in NodeJS, but it also works in Deno, BunJS, browsers, Blueboat, Duktape, etc. If a library author is writing something simple, that isn’t depending on runtime-specific stuff such as filesystem access or standard library functionality, compiling for ESM makes a lot more sense than maintaining a special CJS version just for customers of a single (albeit, the largest) runtime. It starts to make a lot less sense when that particular runtime gives you the option to not use CJS.

                I’m not saying that “oh this time it’s different trust me bro”, but I am saying that while there are similarities here, I think the incentive here for not only application developers but also library developers to upgrade is much greater than it was in the Python world when they switched to v3. It also feels a lot easier to me, as someone who had to go from Python 2->3 and has also seen JavaScript go from a language without basic shit like conditionals into the juggernaut that it is today, than Python was because there are tools to compile your code for different environments, like you couldn’t e.g. write a Python 3 program, compile it down to Python 2, and then distribute both versions in the same package. (or can you? if so that’s pretty cool but I had no idea it existed back then)

                1. 2

                  that’s very helpful context, thank you!

                  Having this being simpler would definitely be of benefit to everybody, so I am rooting for this

          2. 22

            TL;DR: He discovered that using a systems programming language is a less good fit for application development than an application programming language.

            1. 13

              Well, many Rust adherents market it as the last language one will ever need for any use case. No wonder newcomers often have to discover by themselves that it’s not. ;)

              1. 4

                I have that a lot with some ardent Python enthusiasts (though I’m sure Python isn’t special in this regard, I just have 15 years of Python experience so I pick on it a lot). It feels like a weird kind of gaslighting:

                Me: Python probably isn’t the best language for X

                Python fans: what do you mean? It’s great for X!

                Me: <lays out issues>

                Python fans: well what kind of idiot would use Python for X? If you have to do X, use the right tool for the job!

                1. 1

                  [who?]

                  In Rust user forums if you ask what to use for a blog or a CRUD app lots of people will tell you to just use JS, Go, Ruby or whatever. For a low-level language, Rust is surprisingly versatile, but being able to do most tasks doesn’t make it the most practical choice for most tasks.

                2. 1

                  Yeah. Always use the right tool for the job.

                3. 8

                  It’s an interesting article, but I can’t help but feel that the author simply misunderstood what Rust is for to begin with and chose the wrong tool for the job from the outset.

                  Next up: “Why I’ve decided to abandon my laser cutter in favour of a hammer + saw when building my bird table”.

                  1. 1

                    How did I misunderstood what Rust is for ?

                    1. 3

                      Rust is a safe systems-programming language. Systems programming languages are intended for the things that you can’t do in application-programming languages, such as writing memory allocators, language runtimes, and other things that need to explicitly bypass type safety. If you have a task that can be solved in either Rust or an application-programming language then it is, by definition, not a systems-programming task and so a systems-programming language is not the right tool for the job.

                      1. 1

                        awwnn, thank you! (but you didn’t read the article, did you? =p)

                        The project that inspired me to write this is a rust engine with a Typescript programming interface, so the system stuff is in Rust, the app stuff is in Typescript.

                        It’s cool though, I also comment on stuff I didn’t read every now and then, it’s fun!

                        1. 1

                          Why the weird aggression? David is right. If you were able to abandon Rust in favour of typescript, then almost by definition it’s because the task wasn’t well suited to Rust in the first place.

                          1. 1

                            Sorry, didn’t mean to come across as aggressive, although reading my comment again, I certainly did. But the main point stands: since I didn’t abandon Rust in favor of Typescript (we wrote an engine, in Rust, that executes Typescript code and has a Typescript API), that means the comment was almost certainly made without reading the article.

                            1. 1

                              Fair enough!

                  2. 5

                    you will find a post about how Jane the Developer moved from language A to B, or B to C (Err… C is an actual language, but alas).

                    There’s a programming language for any character in the latin alphabet, so there is for B.

                    It would be surprising to find someone writing modern user interfaces in C outside of Guantanamo Bay,

                    Hmm, I am pretty sure a lot of people still write “modern” GUIs in C. I mean what’s the alternative when you want to be cross-platform and not rely on web technology?

                    With over 1.3M npm packages available, orders of magnitude more than crates.io.

                    There are wildly more packages in npm than on crates.io, but one of the reasons is probably that there is no proper standard library in the JS world and everything has to be reinvented. Also, I would guess that the quality of cargo and npm packages is quite different, with Rust crates being of higher quality in general. But that’s just my personal opinion.

                    1. 2

                      I am pretty sure a lot of people still write “modern” GUIs in C. I mean what’s the alternative when you want to be cross-platform and not rely on web technology?

                      Two of the most popular cross-platform GUI libraries (Qt, wxWidgets) are written in C++. For C# there’s Avalonia, for Java there’s SWT or the bafflingly enduring Swing. And pretty much every language with an FFI has bindings to GTK, most of which provide a gentler development experience than raw C and GObject.

                      1. 1

                        Hmm, I am pretty sure a lot of people still write “modern” GUIs in C. I mean what’s the alternative when you want to be cross-platform and not rely on web technology?

                        … Rust? Haskell? Anything with an FFI and a portable compiler?

                        1. 1

                          Hmm, I am pretty sure a lot of people still write “modern” GUIs in C. I mean what’s the alternative when you want to be cross-platform and not rely on web technology?

                          That depends. For me the alternative of writing GUIs in C is to just retire. =p (disclaimer: I am joking! (or am I?))

                        2. 3

                          At the end of the day, the biggest surprise for me, is that this wasn’t really a transition. Like an immigrant that keeps their old home and visit often, I was pleasantly surprised when I looked around and realized that my life was now expressed in both Typescript and Rust.

                          That sounds like a very biased, wealthy point of view on immigration; I found it rather insensitive and fairly distracting. (It reads to me like “When you buy a new Tesla, you can still use your old model, and sometimes that’s nice because …”.)

                          1. 3

                            Jane the Developer moved from language A to B, or B to C (Err… C is an actual language, but alas)

                            So are A and B. Why do you think C is named C?

                            1. 3

                              Very interesting article. One question, though…

                              To my surprise, even fetch presented me with issues. To begin with, I was surprised to even need a module to do that. It feels like the most basic thing I’d want to do in that environment.

                              If you’re using Deno, shouldn’t you already have access to fetch from the runtime?

                              1. 1

                                that’s right, but the article is trying to convey a general sense of things in the Typescript ecosystem in general that bugged me.

                                I tried to ground some things with examples of the project I am working on, but every now and then we write node.js helpers for the infrastructure (so we can share code easily), and those issues pop up.

                                1. 5

                                  FWIW, Node 17+ also has fetch. But I get it. There’s a lot of legacy crud lurking behind things like native web APIs and modules.

                                  1. 1

                                    I did have a mixture of node16 and node18 on our infrastructure, so that explains it. but fetch or no fetch the whole import is still terrifying.

                                    1. 1

                                      Yep, that’s something of a history - you also have fine http or https clients in prior versions of node: require('http') or https. You lost the compatibility with the browser now, though, so people also wanted fetch, and now we have it.

                                      Edit: also, as mentioned in the article, it is very confusing for newcommers!

                              2. 2

                                chiselstrike looks very interesting; bookmarked it to explore for my current project!

                                1. 2

                                  hit me up if you need some help!

                                  1. 1

                                    decided to stick with self-hosted django for the current project, but i’m keeping an interested eye on chiselstrike. some feedback (from the perspective of non-web developer trying to teach myself webdev at a hobbyist level):

                                    • does using next-auth mean i am tied to a react-based frontend? i was unable to figure that out myself after reading through related issues on nextauth’s github tracker, but something like a sveltekit-based example would have been helpful.
                                    • from the docs, the intended use case is to have chiselstrike be the sole backend for both data access and business logic, however i could not see anything about using arbitrary npm libraries in the backend. i wouldn’t mind porting my existing python code to typescript in return for not having to manage a database, but i would then need to use javascript libraries equivalent to the python ones i’m currently using.
                                    • it feels like adding extra friction to the process to have to host my frontend and backend in two separate places (very minor complaint; if i were doing actual professional web development i doubt i would care but as a hobbyist it seems clunky)
                                    1. 2

                                      Thanks! That makes sense. FWIW although we’re close, we don’t call ourselves production ready yet, so definitely Django is a great choice!

                                      About your points:

                                      • In general we want to be very decoupled from the frontend. We have users with a frontend in mind, but there are some users using this for just microservices and that’s fine too! That’s why we decided to expose the http layer instead of going straight into react. But next-auth is indeed - to the best my knowledge, quite frontend centric and we’ll be exploring more alternatives on the auth front
                                      • arbitrary npm’s can be used, but we don’t talk about it too much because things that use node.js global’s, like Buffer, don’t work very well. We’re fixing this but it require some refactors. You can see some examples of node modules here: https://blog.chiselstrike.com/why-cant-we-be-friends-14d2fe324d3e (see how we’re importing handlebars in one of the endpoints)
                                      • Totally understand!!! hosting frontend is very different, you have to worry about things like CDN, invalidation, and Vercel and Netlify will ever do this much better than ChiselStrike. But for simple projects I do agree that it would be cool to be able to host the frontend as well. We’re thinking of good ways to do it