The author never actually says what is so wrong with JavaScript. I think it is quite a good dynamically typed language, and it certainly has some very high-performance implementations. If you don't like it, just use something else?
> Ultimately, JavaScript was the right thing at the right time. It ended up being folded, spindled, and mutilated to serve purposes that it isn’t well suited for
Counterpoint: many quirks in the language were addressed, e.g. introduction of === and with ESLint you get many of the practical advantages of a type checker. And when you need more safety, sprinkle TypeScript on top.
What I really want for Christmas is a TypeScript-to-native compiler.
> The author argues against untyped code, and for using typescript instead of javascript to get types.
Considering how much of the article was about typing and not specific to JS itself, "Just Say No to Dynamic Typing" would've probably been a better title for readers. It would likely get less clicks, though. :')
The JIT seems to figure it out just fine. Otherwise typeless programming is just a particular style and it's not particularly complicated just different. I've never understood this rationale in a language that does not have pointers.
JS ist not typeless. In fact dynamic languages allow you to use very complex types that are not even possible to express in most static type systems. That is why TS needed to have such an advanced and complex type system to catch at least most of it's power.
You are right that dynamic typing is a valid style though and offers some great advantages but also disadvantages. That is why most dynamic languages have added gradual typing support to have the best of both worlds. The real issue is the weak typing in JS which is an design mistake in retrospect.
I was not arguing for explicit typing myself in the previous comment (I was just the messenger).
But now I'm going to. For context, I write code in both explicitly typed and not explicitly typed languages (mostly JS).
> The JIT seems to figure it out just fine.
And the CPU will figure out binary code just fine. But you won't. You can, but not easily. You are writing for the computer, but also in a way that you (and your peers, if applicable) will be able to work with the code: extend it, fix it, maintain it, make it evolve. "The runtime figures it out" is hardly an argument for the dev UX.
Explicit typing is one way among other things to document the code, and this is documentation that's automatically checked by the tooling, which is nice. Types are documentation that can't rot. I'd say, good to take.
"The JIT doesn't need this to figure out the types" also applies to documentation by the way. The runtime, however, doesn't need to understand the code, just to run it. But you need to understand the code when working on it.
Types can help you figure out what functions you can call on any particular variable, without having to have something similar to a complete stack trace in your mind to know which type is a variable.
Sometimes, you can't even have the complete stack trace, for example when you are working on a library called by user code, or when you are calling some black box library code from user code. It's nice having types that are automatically checked at the interfaces so you don't have to figure it out (which you may need to do by running the related code, noticing the return types and hoping for the best). Even if you are dealing only with code that you have access to, it's nice not to have to go read all the code of the other side each type.
Explicit types just make it easier and faster to understand code, and also to modify it. Without types, you need to "recompute" the type of anything you are dealing with, risking calling the wrong method if you do a mistake at this step. Of course, if you have solid testing in place, you will probably catch it, but with explicit typing, that's a mistake you can't do: it'll be in red in your editor, or an error at the type checking step, winning some time.
Explicit types lets you avoid having to re-figure out again and again types of things, and that's cognitive burden that's freed to give more room to focus on what the code actually does. They also help your IDE help you if you use one (or something like LSP).
if you are dealing with small pieces of code, it doesn't matter much: everything can be kept in your head anyway. For such code, explicit typing can be just noise. But for bigger code, types are a relief.
For me, a nice balance is explicit typing at the interfaces (function parameters and return types), and implicit typing inside the function body.
All in all, I think explicit types make me faster for anything more than a trivial amount of lines of code. So I have a strong case for explicit typing. But I don't have much for non explicit typing.
The only reason I can choose to write vanilla JS despite this is because Typescript more or less requires opening the NPM can of worms. Would browsers allow type annotation in JS, I would totally use them and have some type checking pass somewhere to enforce correctness.
>The author never actually says what is so wrong with JavaScript.
The author does but you have to extract it yourself by using some mental subtraction from the sentences he did write:
>[...], TypeScript has all of the benefits of JavaScript (such as they are) while _adding_ a type system that is expressive and powerful. [...] TypeScript leverages the ubiquity of JavaScript while _adding_ all the power of a modern typing system. And that is why you should be using TypeScript instead.
Translation... subtract out the "added modern type system" from Typescript... to reveal his Javascript criticism: "Javascript does not have a modern type system to help catch errors."
This is a plea to use TypeScript instead of JS. Why not. Strong typing is certainly great. But the reason I don't use TypeScript isn't any of those listed: it's because it needs a compilation step, and I don't want that.
With runtimes like Bun and Deno (and lately Node itself), you can run Typescript directly with pretty much zero config. There is transpilation behind the scenes, but the time that takes is minimal.
I personally switched to Bun, and could not be happier. My build toolchain is quite simple now. I run the Typescript compiler to just type check my code, and use Bun to actually run it. For bundling, I use esbuild.
I wasn't sure the Bun bundler was powerful enough to handle my needs. Bundling is a hard thing to get right, and I tried many, many tools and configurations over the years before settling on esbuild.
> it needs a compilation step, and I don't want that
That's such a weird requirement, maybe because I'm used to writing Go code in my day job. I work on some React webapps on the side and there's no way I would miss on TS, typing is just the only way to write code that you can actually refactor. Granted you get some of TypeScript safety for free thanks to `// @ts-check` and friends, but it's the bare minimum.
I do agree with you on the compilation, and this is the reason I'm still writing the occasional .js or .mjs file. However, the js I write starts with enabling ts-check and has all of its type information encoded as comment. This way, I'm getting the benefits of typescript while writing the code without needing the whole compilation step.
> it's because it needs a compilation step, and I don't want that
Why? The seconds it takes to compile even a large project are paid back a million fold everytime it catches a mistake you'd have missed or your IDE out you used the wrong type.
It's probably not listed in the article because it's a nonsensical argument.
Personally I like using typescript's namespaces that have no nice-enough jsdoc/js equivalent, but if tsc/tsserver had an option to mutate in-place typescript syntax to jsdoc notations where possible I would use it as much as possible.
>catches a mistake you'd have missed or your IDE out you used the wrong type.
Do people really have this issue? My errors are never type related and when they are the console tells me immediately and the exactly line to fix.
What I need is a StupidScript to save me from the stupidity of my logic errors…
Like for example I’m working on a custom game engine for a web game I’m making, I’m having issues with the rewards unlock at the end of the match. The code is “correct” the right types go to the right place but there is a logic error somewhere that prevents certain rewards from unlocking.
Types give you much more than just getting an error early when you call the wrong method on an object or pass a string where you needed a number.
Once you have written down the shape of the data flowing through your program in a way that a compiler can check you'll be able to reason about the whole program better and you might find issues much faster.
I think that types can directly help a lot with logic errors as well: one of the things people say most often when discussing typed programming language is that you can make illegal states unrepresentable, which means that you can encode logic into the type system itself.
Over the years I feel like I have read this comment at least ten times from different commenters (and the second time this month) and I cannot really fathom it. I consider myself a pretty good developer, and I have type errors many times a day. It is perhaps the most common error I encounter, and thankfully one of of easiest to fix with static typing.
By far the biggest recent productivity gain I have made using types is by generating the types along with client code for APIs via a swagger doc. I cannot overstate the value in seeing the types update when the backend devs have changed the API, and getting a compiler error when it doesn’t match with your code. By having the types the next developer after me is going to be spending far less time getting up to speed with the codebase.
I started programming with static types early in my career so perhaps I have become wired to lean heavily on the type system.
My first programming language was C/C++ and I learned dynamically typed languages after, I still prefer the dynamically type languages. I still do a lot of C/C++ code for micro controllers and the types are so annoying, either create a function for both ints and floats, templates or you cast the type. It's all so tedious, boring and uninteresting.
I have made a lot of code that works on a lot of third party APIs (The major LLMS, Image generators, E-commerce stuff) and yea it's all been easy breezy and never thought I wish I had types.
Yes. The point is that without type-safety and a compile-time type check, you have absolutely no way of knowing if you have an error like this until you hit that piece of code.
The very fact that you think you don't have those kinds of issues just exemplifies how you actually are just ignorant to all the type errors you have in your code because you haven't tested enough, hit the right edge case, etc.
I have bunch of code/programs that have been running live on prod for years that are super stable with no errors that have been reported but what do I know?
That's why I test the code and solve the logical issues? The joke was that the language would be smart enough to catch the less obvious stupid mistakes instead of obvious to solve type bugs.
I think the not wanting a compilation step complaint is even worse than the it's too much typing complaint, and I say that as someone who does not much care for typescript despite using it almost exclusively for the last 5 years.
I'll happily use TypeScript for all my UI components, libraries and server code, most of the time with Bun thanks to its OOB support for TypeScript.
But for Web UIs I'll drop down to a #NoBuild "Simple, Modern JavaScript" [1] i.e. using JS Modules + JSDoc Type Annotations to avoid needing any npm modules/build steps/etc. I still benefit from a library's TypeScript definitions/VS Code intelli-sense/static analysis/etc but completely avoid any build/bundling complexity for the cost of a slightly more verbose syntax in JSDoc type hints.
I'd happily move to using ECMA Type Annotations proposal [2] if it ever got accepted, but alas TC39 moves slowly...
I use Bun too, and I found that in many cases `bun build` is a small enough sacrifice to be able to use Typescript... after a certain size maintaining pure Javascript code becomes too difficult for me
I don't get the "type checking is the solution for the problems of the world". A lot of good things were/are written without type checking. Most of the problems I see in production have nothing to do with the wrong type being used or some forgotten required parameter.
Also, typescript is just javascript with a mustache. It's the same thing
> Most of the problems I see in production have nothing to do with the wrong type being used
I think this depends on how you use the type system in your code. If you're just passing around strings and numbers, then sure. But if you're making explicit types for all the entities your program processes, and if you're structuring them in a way that means you don't have a bunch of undefined fields in the normal case (e.g. by using tagged unions a lot), then Typescript is absolutely, objectively, transformative compared to Javascript.
yes, but they could have been made robust quicker with types. You still have types in untyped code, they're just in your head and the runtime doesn't know about them. That means you have to be extra thorough to do the type checking manually yourself, and having to write even more tests to validate your types and all those implicit assumptions
It definitely is. His first example is Assembly. That's like saying someone saying 'don't program in assembly' is being hypocritical because everything they program ends up in assembly.
I have said no to Javascript for over 20 years for reasons having nothing to do with the language. I actually like the way Javascript looks because it looks much like C. I have no problem with the Javascript language.
But Javascript is the language of choice for programs (scripts) that I do not care to run. By default, these undesired Javascripts are executed automatically with no user input when one uses a so-called "modern" web browser.
As such, I do not run Javascript. As it happens, the language is closely associated with the so-called "modern" browser, a program that I consider too big, too complex and too dificult to control. It takes far too long to compile, assuming the source code is even available.
I am submitting this comment without using a "modern" web browser.
Whilst not going to quite the same "extremes", I completely agree. I use a combination of plugins (primarily uMatrix on firefox), so stop all javascript execution by default.
There are a lot of sites out there dependent on javascript of course - but you can evaluate these as you find them and either move on, give them temporary permission, or permanent permissions.
I'm not convinced it actually makes the web any safer to browse given modern browser security controls, but it certainly feels safer to browse, and generally it's a much nicer experince with less crap happening on the page as you go (pop overs etc)
When I have to use a popular browser I too use extensions to achieve an "off by default" setting for Javascript.
Default settings matter. In popular browsers, Javascript is "on by default". From the evidence produced in Google's antitrust litigation, we know that companies or organisations that control these browsers choose default settings strategically to increase surveillance, data collection and ultimately online ad services revenue.
I rarely find websites that are truly dependant on Javascript, meaning the web developer had no choice other than to use it. Instead, what I find is (a) gratuitous use of Javascript to do something, e.g., make an HTTP request, etc., that can also be achieved without it and/or (b) use of Javascript to make HTTP requests I never intended to make, e.g., requests for ads or tracking. Javascript is effectively used to transfer control over web browsing from the web user to the web developer. Through the use of Javascript, a single request for a page becomes a trigger for dozens of additional requests the web user never intended to send, and usually to domains the web user has never heard of, that serve no useful purpose to the web user.
1. Extensions/add-ons like uBlock will show numbers of requests to be triggered with Javascript. Insanely high numbers are common. For example, something like fifty-seven for Github. Meanwhile I am able to use Github to search, read and download source code just fine with a relatively small TCP client (not git) that does not run Javascript, only sends a single HTTP request and generally uses only two github domains, i.e., github.com and githubusercontent.com.
In sum, I am not sure that many websites are truly dependant on Javascript to offer what they purport to offer to web users, e.g., information, files, etc. What I am more inclined to believe is that websites are dependant on Javascript to perform surveillance and data collection, not to mention serving ads and tracking.
"Typing everything allows you to clearly and succinctly declare intentions with your code as well as enforce those intentions throughout your code base. For an application with many developers, being able to clearly and definitively express what code does is a huge advantage over code that requires a fellow developer to spend cognitive energy to figure that out."
Types are definitely useful in the fight to 'make invalid states impossible', but this rather overstates the case. They go only a very little way in documenting intent.
I never understood people discussing JS and TS as different entities. TS is JS, but with types. But to be fair I can't imagine now using untyped JS without an LSP of some sort.
I don't see JavaScript as the webbrowsers assembly, and whilst it can be, don't agree that the web browser is the new operating system. These are the two predicates used to justify the author's argument to use typescript.
I don't have a problem using typescript, but prefer dart if you need a strongly typed (null safe) language.
I think the flexibility of JS forces you to be intentional with your code composition in order for it to not be a huge mess, which makes better programmers. With that being said, many programmers don’t want to think that hard so they rely on railroaded overly opinionated languages or write bad JS
JavaScript is a very capable language. It has better functional programming support than Java and Python. It has fewer footguns that C++. You can start with a scrappy prototype then gradually add type-checking later. Of the mainstream languages, it's actually one of the better ones!
Because Common Lisp has a pretty strong type system. Also at least with SBCL you have some support for gradual typing. Plus REPL-driven development means you catch many errors early on anyway.
The issue with JS is weak typing. Also programmers mostly using batch style programming makes it more frustrating though the browser dev tools are decent.
Dynamic typing is not an issue. Gradual typing can be added later on to an language. JS just needs to add syntax support for type hints so you don't need to rely on JSDOC. The weak typing is a serious design flaw and can't be fixed in a backward compatible way. Maybe with an explicit opt in where you declare types strong is the beginning of your file but that would make JS engines more complicated as they would need to support both and I don't see it realistically happening but one can dream.
Python actually has a good typed ecosystem these days, and unlike JS -> TS you don't have to add a compilation step to benefit from it: you just have to enable type checking in your IDE.
JS is in a different spot where to benefit from type checking you have to add a build step or reconfigure your build tool, switch files to another extension, add some "type stubs" dependencies, and make significant changes to the codebase to benefit from type checking.
I think if Node and the browsers started allowing type hints in their parsers you'd see much less resistance to TypeScript.
Other scripting languages are probably not popular enough to matter as much as JS does.
I know, I've used jsdoc type hints and I don't like them very much. They're verbose, types and names are the wrong way around, there's about two or three different syntaxes for defining any one thing, you don't get any autoformatting (AFAIK)... I'm not a fan.
Can you clarify how you do this? the type annotation TC39 is not approved; but I'm interested in hearing if you have a "userland" approach that works for you?
I've seen several ways of annotating Javascript that IDEs seem to understand. They usually involve using comments before fields, classes, or functions.
The most compliant one seems to be using [JSDoc](https://jsdoc.app/). JSDoc is mostly intended for generating documentation. However, the Typescript compiler can validate types (and can even interoperate with Typescript definitions), if you configure it as such.
In scenarios where you HAVE to write raw Javascript but still would like to do some type validation, this is probably the best solution.
It looks a bit like this:
/**
* Fiddle the widget
* @param {WidgetThing} The widget to fiddle
*/
function fiddleWidget(widget) {
This is a type hint that asserts that `widget` is of type `WidgetThing`.
JSDoc also works in the middle of a method:
/** @type {Foo} */
const foo = widget.fetchFoo();
This asserts that `foo` is of type `Foo`. This could in theory also be derived from the return value of `widget.fetchFoo()` of course.
JSDoc also has arbitrary type definitions:
/**
* @typedef Foo
* @type {object}
* @property {WidgetThing} parent - the parent that created this Foo.
* @property {string} name - the name of this Foo.
*/
I would stick to transpiling Typescript myself, but I've also seen use cases where that's simply not an option.
Translation: type less languages get messy when the project size grows. This is not only about javascript, it's also about python and whatever else is in fashion.
Still, the title is disappointing because switching to a type checked dialect of JS won't fix the bloat issues that are fundamental to the browser as a platform.
Any system can get messy when the project size grows. Defect rates seem to be correlated with the addition of new features. Stable projects only including bug fixes with good test coverage become more stable over time. This is all regardless of language.
There may be a case that typed languages ship with fewer initial defects in new features but I'm not entirely convinced it's always competitive with the return in development speed and simplified testing you can get staying untyped. Particularly when your underlying problem is not CPU bound.
Solo project or very small team then? When everyone understands all code?
Of course it's faster to go type less then.
Add 4 more people and you'll end up debugging runtime errors because it was intuitive what you should send to $COLLEAGUE's functions but in reality they expect something else.
Or at best, $COLLEAGUE will document the type info in comments :)
It is not at all "say no to JS". It's "use my preferred flavour of JS instead."
I want to return to the pre-JS internet and especially the pre-JS Web.
Say no to Javascript at all in any variant. Also say no to PHP. Nothing of lasting value to humanity would be lost if both of them went away completely, forever.
What about dynamic websites? For example, a platform-independent chat app.
Javascript has a place, although that place would be better filled by another language. PHP... yes, PHP can be completely replaced by other server side frameworks.
An exact example of the kind of thing I'd like to get rid of.
The UK PC vendor Elonex had the first ever webmail system I saw, called HTMail. It was impressive but it was a private in-house tool to give remote workers email access without needing their own machine with an email client. Wrong sales model.
It the was followed by the indie HoTMaiL, based on NetBSD servers I think, which had the right model: a free public standalone service, paid for with ads. Of course MS bought it and ruined it.
Webmail doesn't need Javascript and worked with pre-JS browsers and servers.
> For example, a platform-independent chat app.
Good. Let's eliminate them, too. They are bloated slow things that allow companies to hijack their own commercial clients' data.
Stick to standard protocols, extend them if necessary -- XMPP 2, Matrix, whatever -- and document and publish the protocols. Make it possible for 3rd party client apps to connect. Pidgin was great and it takes about 1% of the RAM of a bare handful of these crappy Electron efforts like Slack.
What you are citing as reasons to keep it are the reasons I want to see it dead.
These things don't have to be bloated. For example, I wrote a web chat once, called minchat (minimal chat) [0]. The frontend is written in plain HTML, CSS and JS, totalling ~5kb. The backend is written in Rust.
There is room for programs that do not need to be installed. Examples are Flash, Java applets, and Javascript. Personally, I think some sort of UI thing based on WASM might be the way to go, but that's just my opinion. Can you think of any other way to run programs from the internet without installing them? Yes, SSH, telnet, remote access, remote X11, but with all of them, the programs are running on a different computer, whereas with web apps, they're running on your own computer, without costing them money, other than hosting costs.
I never thought I'd be speaking for web apps, but I guess I'm not, not really. What I'm saying, is there is a niche, and that is currently filled by web apps.
It was about Lisp, so it’s an ancient thing now, but it still has truth.
As far as the Unix/Linux/xBSD world goes, it can be generalised like this:
Level 1: Any sufficiently complicated [container or VM management system] contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of Plan 9.
Level 2: Any sufficiently complicated [bytecode VM or runtime environment] contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of Inferno.
Wasm to me still smells very much like a second-hand, poorly-conceived, half-assed version of Dis.
> There is room for programs that do not need to be installed.
Sure there is room. But is this a desirable thing? Is it worth the price in inefficiency and insecurity?
If it is, and I am not 100% convinced of that, then design it right into the OS from the outset. Any effort to bolt it on later will be fatally flawed.
I thought this was a parody of Guardian-style opinion columns at first. You know, "I have a strong opinion and here are Y meandering and mildly amusing/lighthearted reasons why" op-eds.
I like opinion columns and would love to see more about software development, but this one feels like it's going for the lowest of hanging fruit. Anyone who cares about JavaScript either way will already have an opinion and won't be won over by a humorous take.
I do like the author's style though, so don't interpret this as crapping on his work. Looking at the "More from this author", it seems this is his genuine style, and I found some of his other pieces to be good reads. More please.
I'm a fan of TS, and have no issue with people's opinions on programming languages. But come on, the whole "built in a week" thing is pretty tired at this point. There have been many, many major iterations on Javascript since the 90s. There's nothing inherently wrong with vanilla JS these days. It has a few quirks like every language does, but overall generally does what you expect it to do.
This kind of rant, culminating in a hackneyed "created in a week" insult, usually comes from backend developers who jumped into frontend work thinking it was a silly little thing that could be mastered in under an hour, discovered that it was a whole separate field, and still failed to adjust their priors.
This time it comes from a "former Delphi product manager" turned clickbait writer. I just hope that my visit with adblock enabled didn't generate any form of income for him or his website.
I think you're dismissing his points too quickly. Even if he could be biased and his points could be presented better, I still think that, as a rule of thumb, anything past 1000 lines of code should be statically typed. If you don't have static typing, you have to keep track of the types yourself. It works for small scripts, but IMO it scales quite badly.
I love JS. Well, that's not true. I love it, and then I hate it, and then I love it again. And I am not sure how to respond.
It has warts. I have seen a staggering amount of flavors / styles of JS.
It is a really expressive language. But that is kind of a cope. You will figure out how to express your wildest ideas. But you will struggle to read others code.
Multithreading is...weird to say the least. Are people spinning up a server per core? Using PM2? Have they discovered the world of testing...without mocks.
If we don't criticize JS it will never get better. So writing off the criticism of the especially hateful BE dev stereotype isn't doing anyone any good. Take it in stride. Nobodies feelings need to be hurt.
Many languages evolve into other languages. JS does not really have that luxury, and I don't know of any langs that preceded it that were similar (my own ignorance).
It is amazing for what it is.
But...if we could start over with what we have learned over the years many things would certainly be very different.
At this point my only hope is that they bake TS into the JS engines so that we could use type information at runtime. It's too entrenched to replace otherwise unless we jump into a new UI paradigm.
The issue I take is that the criticism is vague and outdated. "It was built in a week" is the only direct piece of criticism, which is simply no longer valid. The JS that was built in a week is long dead.
In fact, the whole article is about how TS = good and JS = bad. Except that Javascript is valid Typescript. So every wart or issue that exists in JS also exists in TS, with the exception of a layer of type safety.
> Ultimately, JavaScript was the right thing at the right time. It ended up being folded, spindled, and mutilated to serve purposes that it isn’t well suited for
Counterpoint: many quirks in the language were addressed, e.g. introduction of === and with ESLint you get many of the practical advantages of a type checker. And when you need more safety, sprinkle TypeScript on top.
What I really want for Christmas is a TypeScript-to-native compiler.