196 comments

[ 4.6 ms ] story [ 340 ms ] thread
> I don't want to rewrite in TypeScript, because I believe the core of ESLint should be vanilla JS

why though?

The fact that they would use JSDoc type annotations and tsc instead of just typescript seems insane to me.
Yeah, surely in some hypothetical future it's not that much work to simply go back to plain JS from TS if they're worried about some sort of lock-in. Seems like you might as well just write it in TS then if it's relatively trivial to eject if needed.
Ya I am also perplexed about how people keep suggesting using jsdoc instead of TypeScript. Is it just to avoid the tooling?
I think it's to maximize potential contributor base.

JS is the front-end browser language. That's its origin story and it almost certainly will always have that job, because of web browser backwards compatibility.

That's why it's so universally known / used / understood.

Once you target TypeScript you're suddenly looking at a much smaller set of devs who know it, and you're married to a language that's effectively owned by a single company (MS, to boot).

You can get decent gains in type-checking by writing JSDoc and using tsc in your build process without adding much friction for new contributors.

I think its more that eslint at its core does not support typescript and they want to run the eslint tool theyre developing over the eslint codebase. It's hard to argue with this but it doesnt seem like the greatest outcome
I would guess that more people know how to write Typescript than annotate with JSDoc.
The kind of people who'd be willing to contribute to eslint are very probably not afraid of writing in typescript.
From personal experience, you don’t ever “just use TypeScript”. You have to install plugins, adapters, parsers for every other tool (linters, formatters, bundlers) to also make them work with TypeScript. Adding TypeScript into the mix increases the number of dependencies (dev or not) dramatically. If you use the jsdoc flavor of TypeScript, you only need to install the one dependency.

Not saying it’s the best reason, but a reason nonetheless.

Over the weekend, I converted an app from JS + Create React App to Typescript + Parcel v2.

The typescript tooling was extremely simple to setup with only a few added packages... until I had to setup eslint. That's when I had to install a half dozen plugins, adapters, parsers, etc like you said.

Granted, the linked eslint rewrite seems to have plans to make the typescript linting tooling simpler. However, I might end up switching to Rome in the meantime just for simpler dependency management.

Rome is very nice right now. My linting finishes in 50ms, as it’s supposed to, instead of minutes in eslint.

Of course they don’t have nearly the same amount of rules, but we’ll get there.

My project currently pulls in the airbnb rules, which in my opinion has too many rules. It might be nice to start from a clean slate, I'll give Rome a shot next weekend
Probably so they can run it through ESLint
I'm curious if anyone else has noticed this? It seems Rust is tending towards "silver bullet"-status, as if; if it's written in Rust, it must be fast.

I'm not here to rain on Rust's parade, but you can absolutely write unmaintainable, slow Rust code. I would even argue, beginners write fewer features that perform worse, in the same amount of time, than their main-language (in this example: Javascript) counterparts. Especially if they have years of experience.

I agree that it is completely possible to write slow code in Rust, but the idea is still that, in general with a relatively skilled developer, a compiled langage will usually result in a faster program than with a interpreted or jit-ed langage. So, assuming you are competent in said langage, you might as well write it in your compiled langage of choice, assuming performance is one of your major priority.
(comment deleted)
A jit can tune itself to properties of input data which were unknown at compile time. That's a serious advantage for long running programs that don't know much about their input, which might be the important ones.

That might still be the realm of the sufficiently smart compiler though, aka vapourware, so in practice today you're probably right.

I’m not a Rust developer and I’ve been waiting for it to bake a few more years before playing with it.

However, I do appreciate the desire for developers to use languages that allow for more performance and fewer bugs, catching more bugs at compile time.

Even small improvements are important.

Ideally, poorly written, but correct, code in such a language could be refactored more easily in such a language.

Rust does tend to make some folks starry-eyed, but that's not a good reason to avoid the language.

I imagine you're of the same mind as I am - be intentional when choosing a language for a project, and consider all the pros and cons.

I agree, of course, that you can still write bad rust code. But I don’t quite see the silver bullet case happening. Rust is a great choice for a compiler and when written, in direct competition with a JS-based compiler, has enormous capacity to be far faster.
(comment deleted)
From my reading, it's more that if written in Rust, even if it starts off slower, it can be made to be extremely fast, but that they're already bumping up against the limits of what the JS system can provide in terms of speed.
In this case, I'm concerned that they're particularly naive to think that writing only parts of ESLint in Rust will be a win.

My impression -- no firsthand experience -- is that the ser/des costs associated with FFI between node and rust when dealing with large objects like ASTs can eliminate most wins, especially if you have to go back and forth multiple times.

Related: https://zaplib.com/docs/blog_post_mortem.html

I'm also under the impression that most of the gains from rewriting Node into Go or Rust come from getting access to multithreading, which I can't imagine working well in this context if the ESLint plugins themselves are still written in JS (which, IMO, they certainly should be). A single file will still need to run on a single thread.

(Of course, you can run different files on different cores with Workers or just subprocesses, but I assume ESLint does this already)

The winning play here is to represent the node structure directly in rust, such that serialisation is a no-op. Which is admittedly tough to implement.
Still comes with the same issues. JS code will need access to the node structure, too, which means serializing it on the Rust side.
I mean have the same in memory representation in both languages such that no serialisation or deserialisation happens in either direction across the boundary. Fast but difficult to implement.
V8 stopped dropping free perf wins on the JS community every year a while ago, and people are clearly starting to notice and feel like they need to take matters into their own hands. For some, that means an adventurous rewrite of their library with nebulous end results (I hesitate to call the proposal "eslint" still, since it seems to aspire to be an omni-linter). For others, it may mean abandoning JS entirely (see rome). And yet for some others, it has made them realize, just like with the other interpreted languages, the perf probably stopped being important after some unnoticed breakpoint.

To be real, I don't think they'd get any perf gains from a wasm component - not until most of the library is wasm, anyway. The dream of offloading a small hot function to a faster, instruction-optimized wasm implementation is usually killed by marshalling costs for anything other than numbers. Even the perf of simple string functions (like `normalizePath`) often get destroyed in practice by things like unicode validation, since the string models and memory layouts between JS and Rust don't match. Still, despite all that, it's tempting to _try_ because, well, what else are you going to look into for performance gains? Once you've tracked down all your v8 deopts and monomorphized all your hot code, what's left but telling v8 to get out of the way as much as possible, while you go as low level as you can? Algorithms improvements? Those often amount to random flashes of insight - you can't plan those. So when a lot of people say "Hey, I reimplemented 5% of X in Rust and it's 20x faster!" you _could_ smugly assume it's because it's a partial implementation, or you can choose to believe that the authors don't have ulterior motives and the tech stack itself has merit and investigate it yourself. It'll be easier and more fun than thinking hard about usage patterns and algorithms all day, anyway.

> can absolutely write unmaintainable

But you CAN write fast code too! And that, for a fairly high level language (in some aspects) is quite a feature, especially in the context of the safety it provides.

In pure Python/Ruby you can certainly not write very fast code, not matter how hard you try.

> Rust-based replacements

I find it funny how Go was born to be a simpler C, but managed to get a lot of mindshare with Python developers that were writing system-level scripts and backend systems.

While Rust was born to be a better C++, but is getting a lot of traction with Javascript/Typescript developers, and you can start to see some similarities in the packaging and tooling philosophies of the two. (Ton of small packages, some that should probably part of the stdlib but anyone needs to use to stay sane: futures, thiserror, anyhow, for example. Also there starts to be a tendency to rewrite and release incompatible APIs that this time will solve all the problem of the previous iteration).

I guess the hype-driven junior developers saw how better Typescript is at managing Javascript's shortcomings, and now see static typed languages, especially one with some hype of its own behind, as the Messiah.

Let me add the disclaimer that I'm a fan of Rust before I get attacked for this controversial observation.

I’m seeing a lot of Rust in the Python world, too, which I think makes sense as people want to avoid the hostility of C/C++ and expect developer ergonomics closer to the level they’re familiar with rather than the C/C++/Go-level toil.
Not sure what you are thinking of when you put C, C++ and Go into the same category of "bad developer ergonomics" here? I found Go's developer ergonomics to be pretty welcoming, compared to C/C++ and also compared to Node for that matter...
It’s a spectrum where I’d definitely rank Go higher than the others but package management and error handling were historically a disappointment.
It helps that Rust is probably the best language to use if you are targeting Wasm, which is mentioned in the discussion. Go can be compiled to Wasm too, but the fat runtime makes it a non-starter for many use cases.

(I prefer Go over Rust for general purpose programming, and I wish that Wasm had an answer here so we can use less complex, cognitively-lighter languages.)

I'd say that Rust's crate ecosystem is of a different character than Node's. There's no culture of "microdependencies" like `is_odd` in Rust, likely because Rust's stdlib isn't small per se; it is slightly narrow (without things like HTTP libraries) but very deep (the modules that do exist are very thorough). Overall, Rust crates are "topic-oriented" rather than "convenience-oriented". Node achieves fine-grained APIs via a proliferation of small dependencies, whereas Rust does the same via feature profiles within a single crate.
And yet Rust import tons and tons of package for anything, so yes you don't have that `is_odd` but your dep tree if very often bloated.
(comment deleted)
For some definition of bloated, maybe. Our codebase at work has I think 15-20 crates in our workspace, powering two independent applications and three dev-tooling-related binaries. All of this provides the main functionality for our business.

We have fewer than 500 Rust dependencies in our Cargo lockfile, including dev dependencies.

Meanwhile, our relatively simple react frontend and graphql server written in TS have over 20k dependencies. It’s truly a different order of magnitude.

20k? I’m willing to believe you can hit 5k, but that’s already stretching credulity. At some point all the common packages are installed.
Okay you appear to be right!

Running `yarn info -AR | wc -l` gets me 3,413, and I get the same number for `cat yarn.lock | rg '^".+":$' | wc -l`

I remember running `yarn install` before we switched to `yarn 2` used to get us some absolutely insane number of packages being fetched in the 20k+ range, which is where my number came from, but I hadn't looked at it again in quite a while. I'll update my original comment. (edit: nvm it's too old to update, oh well)

Haha, no problem of course. If someone did have a 20k package lock file I would’ve been really curious what was inside ;)
Rust has been seeing a lot of adoption from Python devs too, in part because of crates like PyO3 making interop fairly easy.

I think Rust's appeal (and Go's for that matter) in these cases is that it offers high performance without a lot of the footguns of C and C++. This means that even if the language is challenging at first, the pay off is far more confidence that the compiled program is correct.

It is curious that Rust seems to be the overwhelming favourite for new JS/TS tooling. The appeal of static typing from TS carrying over to Rust seems plausible, but in this case, the developer is favouring JS over TS for the initial rewrite, so I'm not sure how true that is.

Go types are strictly inferior to Rust types.

If I wanted an ideal GC'd language with good types, I'd pick StandardML to pour time and resources into instead of go as it's a better-designed language with similar performance, better types, more simple syntax, and with better-modeled concurrency.

> I guess the hype-driven junior developers saw how better Typescript is at managing Javascript's shortcomings, and now see static typed languages, especially one with some hype of its own behind, as the Messiah.

You can see the exact same thing with the transition from NoSql to SQL.

At first it just seemed like added complexity, then that "ah ha" moment hit, and it clicked.

Ambitious!

I've always been curious about the trade-off between "second-system syndrome" and "learning from experience". Do people have examples of rewrites that went well and those that didn't?

I can think of several that didn't go well (and in fact ultimately decided as tech lead at my last place not to do one for a big chunk of our code that I was on the fence about, just because of that), but can't think of many that did go well.

Maybe Go is kind of an example where the authors used all their experience to build something new, rather than just a straight up rewrite. BurntSushi's ripgrep is an example of someone else doing a rewrite that worked out pretty well. Others?

It's a bit ironic to use Netscape as an example of a "rewrite gone wrong" as (if I remember correctly) the initial version of Netscape was a complete rewrite of Mosaic, with Mosaic developers being involved in the rewrite as well. And I think Netscape in general was quite popular, most if not all software people were using Netscape at one point if they were active during that time.
Every new program is a “rewrite” if you look back far enough. In that case they had funding to start a new company and the problem space was an order of magnitude smaller.

He’s right, that decision marked the end of Netscape as a factor.

Twitch rewrote their backend from Rails to Go.

They also rewrote their frontend in React (previously Ember.js)[1]

I know I've also seen a Twitch developer stream themselves benchmarking Rust + io_uring vs Go but I don't know if anything ever came of that.

Discord rewrote at least one Go service in Rust. [2]

Cloudflare made Pingora (Rust) to use instead of NGINX (C) though idk if that meets the rewrite criteria. [3]

[1] https://blog.twitch.tv/en/2022/03/30/breaking-the-monolith-a...

[2] https://discord.com/blog/why-discord-is-switching-from-go-to...

[3] https://blog.cloudflare.com/how-we-built-pingora-the-proxy-t...

I believe reddit was rewritten in Python (formerly Lisp?)
Major projects like this are somewhat rare in the open, and often interesting. It sounds high-risk, but if done well could make a big positive difference in the world of js-related software development.
(comment deleted)
You could write an identical comment under most JS-related threads.
I have to say, I think they'd be crazy not to write the new version in TypeScript.

Choosing to use JS without TS at this point has become a dogmatic statement of purism that, while beautiful in a sense, is so unpragmatic as to appear a little foolish.

It's like insisting on using the pre-electronics version of a powerful, dangerous machine even though the new version gives you just as much control, greater precision, and much better safety, because of a romantic notion of purity in the way things should be done. Admirable and not at the same time.

Meh. Choosing to write something in JavaScript that is wildly supported on every platform via browsers without having to deal with transpilation doesn't seem that foolish to me. TypeScript solves a small sub-section of problems that can be solved in other ways too, like extensive unit tests, but that also comes with tradeoffs, just like using TypeScript comes with tradeoffs.

Assuming everyone should use TypeScript just because you happen to like it over JavaScript seems crazy. But I guess that makes me seem crazy to you, so here we are in a circle...

TypeScript seems to have entered the same hype cycle as Rust (if it didn't do it before Rust) where people seem to think that everything written in X should actually be written in Y instead (C/C++ => Rust and JavaScript/Any compile to JS => TypeScript). Doesn't mean every project have to follow that though.

ESLint does not even support the browser. I think your first sentence is (I'm assuming accidentally) creating a straw man argument.
Yeah, you're right, it doesn't quite apply here. But I think the general idea applies. JavaScript is supported, used and known by more developers than TypeScript, no matter if it's in the browser or not.
One of the stated goals of this rewrite is to support running in the browser.
From the github issue:

> Runtime agnostic. ESLint should be able to run in any runtime, whether Node.js, Deno, the browser, or other. Runtime agnostic. ESLint should be able to run in any runtime, whether Node.js, Deno, the browser, or other. […]

I can't imagine maintaining a large JS codebase without types now. For places where you really need dynamic typing the any type is there for you.

I certainly would never take a job in a pure JS shop.

I certainly wouldn't take a job in a place where they default to using TypeScript without thinking about the tradeoffs first. Cargo-culting never ends well, and there are no silver-bullets. I'm more afraid of those two "concepts" being a part of "company culture" than having to use JavaScript without TypeScript.
I can't think of a single trade-off where choosing JavaScript would be better than having absolutely zero run-time errors in production, almost making error monitoring tools useless.

Could you please provide a list of these tradeoffs?

Would of course depend on the situation, and also I'm not employed to evaluate your use of TypeScript vs JavaScript, you usually do this at the start of each project depending on the needs of what you're building.

But if I'd want something that is optimized for ease of install, ease of contributing to and minimal build tooling, choosing JavaScript over TypeScript is a no-brainer.

As a second tradeoff, choosing JavaScript over TypeScript tend to make codebases less complect and more modular, at least in the teams I've been in who maintained codebases with both languages.

Both are your personal experiences, neither of those are a valid tradeoff.

My experience with js-land is that choosing a typescript and make use of the @types packages is _the_ modern way of doing js dev. What you describe is basically do the same people did 15 years ago.

That is not a trade-off, but a refusal to re-evaluate the situation under changing conditions.

I'm sorry but if you don't understand what tradeoffs are nor understand what tradeoffs are involved with choosing between JavaScript and TypeScript, I don't think there is much left for us to discuss.
>I'm sorry but if you don't understand what tradeoffs are nor understand what tradeoffs are involved with choosing between JavaScript and TypeScript, I don't think there is much left for us to discuss.

You've yet to provide even a single example.

The typescript compiler is slow, and sometimes you have to escape hatch the type system, or use libraries that aren't typed. Type annotations can be pretty complicated, and at least sometimes are very noisy and make code less readable. You probably have tests anyway, and depending on your problem space, type errors may be such a small proportion of your errors that a using a type checker isn't justifiable. Finding an error in your typescript code from a JavaScript error message is hard and frustrating (there is always a source map bug).

As an aside, at least to me your posts are coming off as really combative in this thread. You might get more constructive responses if you adopted a more curious, open tone.

Edit: found this on page... 4 of HN? https://twitter.com/swyx/status/1350427690814251010 .

Now that is a good example. I've encountered the problem of compile times myself. I've asked Daniel Rosenwasser about reimplementing the TSC compiler in a compiled language for a better speedup, but he said it wasn't worth the hassle because the compiler moves so fast and the spec is pretty vast at it's current state.

> type errors may be such a small proportion of your errors that a using a type checker isn't justifiable

This is a bit biased. The major advantage I see in using typescript is that you can be certain an interface is exactly what it says it is.

> As an aside, at least to me your posts are coming off as really combative in this thread

You are correct in this. Sorry. I will fix my comments to come off as less abrasive.

> I've asked Daniel Rosenwasser about reimplementing the TSC compiler in a compiled language for a better speedup, but he said it wasn't worth the hassle because the compiler moves so fast and the spec is pretty vast at it's current state.

Oh super interesting! I wonder if the solution is like, tsc becomes a reference compiler. I'm pretty sure people would absolutely love a Rust implementation that was fast but a little behind. A lot easier to daydream about than to do though, haha.

> This is a bit biased. The major advantage I see in using typescript is that you can be certain an interface is exactly what it says it is.

Yeah and I do miss this in dynamic languages. Interfaces (and typed data structures) have great descriptive power just on their own. There are run time packages for this (prop-types, etc) but... run time is worse haha.

> As a second tradeoff, choosing JavaScript over TypeScript tend to make codebases less complect and more modular, at least in the teams I've been in who maintained codebases with both languages.

[citation needed]... My experience is the exact opposite. Javascript code bases I've worked with had crazy mega functions that would accept any arbitrary input and try to return something. Typescript code bases (in my experience) tend to be more modular because the interfaces between things are clearly defined. If you want to use code written by someone else, it's immediately obvious what structure your data needs to have to work with their code.

> But if I'd want something that is optimized for ease of install, ease of contributing to and minimal build tooling, choosing JavaScript over TypeScript is a no-brainer.

I mean, they are talking about having parts written in rust:

> Rust-based replacements. Once we have a more well-defined API, we may be able to swap out pieces into Rust-based alternatives for performance. This could look like creating NAPI modules written in Rust for Node.js, writing in Rust and compiling to WebAssembly, creating a standalone ESLint executable written in Rust that calls into the JavaScript portions, or other approaches.

That looks like an _extremely_ complex build system setup compared to using the Typescript. They are also planning to document the types anyway:

> ESM with type checking. I don't want to rewrite in TypeScript, because I believe the core of ESLint should be vanilla JS, but I do think rewriting from scratch allows us to write in ESM and also use tsc with JSDoc comments to type check the project. This includes publishing type definitions in the packages.

The only possible trade-off I can think of is that type checking with tsc + JSDoc results in a faster build than using typescript directly. Personally, I find it a bit odd to use tsc + JSDoc instead of TS, but hey, they can do what they want.

I’m not sure I’d say pure JS is easier to contribute to. Having type information around your codebase makes it much easier to know what comes from where, even if you haven’t traced the source of the variable all the way to the start.

Like, you are theoretically correct, but practically the extra complexity of using Typescript over Javascript is running ‘npm install typescript’ after installing node. You certainly have less build tooling without tsc, but the benefit there is tiny.

There’s some mild reasons to go for pure JS, and a lot of absolutely gigantic reasons to go for Typescript (in my opinion).

Type-checking doesn’t take any serious codebase to “zero run-time errors in production.” It’s not a magic pill. Monitoring tools are useful for far more than telling about runtime errors.
Typescript type declarations check that the Rube Goldberg tooling du jour managed to process them, proving that the user managed to follow instructions.
I’ve worked at several typescript shops and I have certainly never seen “absolutely zero runtime errors in production.”

Even Rust, which has a much stronger type system than TS, does not prevent all runtime errors. Types can prevent a certain class of bugs/errors, and that’s great, but zero runtime errors is overstating it by a wide margin.

So you’d rather have more bugs than less? Given any piece of JS code, you can’t actually reason about it unless you also know its caller. Or you do defensive programming. At which point, why even bother.
That's not what I said at all. I generally choose to work with languages with strong, static types, because I appreciate the added documentation and security the types provide. That said, I'm not going to sit here and pretend like I can just ignore the possibility of runtime errors because I write Rust and Typescript. I'm also not going to pretend like there's anything wrong with working in a language without static typing. I'm an emacs user, so I write plenty of Emacs Lisp and have a great time with it. I used to write Python professionally before type annotations were introduced, and yet still somehow managed to produce software that worked. Types are great, but they're just one tool in the toolbox.
>Types are great, but they're just one tool in the toolbox.

Of course, everything is just tool. Its up to us to decide if we want to use it or not. What I don't understand is why wouldn't you use it. I totally understand if its fun to cobble together some webserver using only bash scripts. But if you're writing something as big, complex, and widely used as ESLint, I am very surprised if you don't choose something that is more performant and maintainable. It is almost irresponsible. I have plenty of fun side projects that should never ever be used in production because I know its really bad.

I never claimed that using Rust will magically make all your sort implementation correct. Of course this is an insane claim. But like I said, if you take any snippet of JavaScript, you actually cannot reason about it without looking at all the calls to that function, plus all the functions that calls to that. Given any variable S, what is its value? Who knows. I guess you just have to run this massive test suite that we wrote. There's WAY more possible incorrect JavaScript code than there are Rust.

I have written webservers in TypeScript and Rust. The moment I get something out of serde in Rust, I know for a fact this is a string. If the key doesn't exist, its None. In TypeScript, I don't have the same confidence. Did they wrote the correct validator? Wait did they add a default value? Does this interface match what we have? Oh its a string...but its actually Date. Wait...why does this bool keep returning false...(https://stackoverflow.com/questions/59046629/boolean-paramet...)

I could have written 1000s of unit tests...Or just use type and fail the "test" at compile time.

>there's anything wrong with working in language without static typing

Yes there are. If Linux starts going backward (as in they are starting an effort to handwrite new drivers in assembly) and move in that direction, everyone else should rightly be really worried.

Generally I agree with you about what the benefits of types are, which is why I generally choose to use typed languages.

> Yes there are. If Linux starts going backward (as in they are starting an effort to handwrite new drivers in assembly) and move in that direction, everyone else should rightly be really worried.

Frankly, I have a lot more confidence in something written in Python/Ruby/JS to not fail in a really dangerous way than I do something written in C. It's silly to pretend like all languages with types are equivalent, or that types are uniformly better for all use-cases.

Sure, the type systems in C/C++ will verify that you don't have type errors, but they can't verify that you don't have use-after-free errors, or out-of-bounds errors, or null pointer dereference errors, and so on. Even Java, which has an extensive and relatively modern type system, can't protect you from null pointer dereferences.

I never said "there's nothing wrong with working in a language without static typing for ANY PROJECT IN THE WORLD." Some projects need it, and some projects frankly don't. Linux, given its constraints, could not have been written in anything other than C. That's fine.

Very large projects in dynamic languages seem to eventually want type annotations, e.g. Dropbox (Python), Stripe (Ruby IIRC), and Facebook (PHP). But at the same time there are plenty of large, successful projects written in dynamic languages: GitLab (Ruby), Wordpress (PHP), much of emacs (Lisp), this very website (Lisp), Datomic (Clojure), CircleCI (Clojure). Sure, you can say that all of those projects should have been written in some statically typed language, but they have found success regardless, which is really the only metric that matters.

They asked for trade offs, which you did not provide. Your only retort seems to be (for now) that it's not perfect. Care to try again?
Is this comment meant to be responding to me? The comment I’m replying to said that TS prevents all runtime errors. That’s the only thing I’m responding to. There are certainly tradeoffs, but “eliminates all runtime errors” is not a valid pro for TS.
Inspecting deployed code without the transpilation noise is sometimes nice. Or maybe there's a workaround for that?
You could use source maps.

Besides, I’d imagine the deployed code would be minimized anyway regardless of whether TypeScript is used.

Are there any advantages to minimizing server code?
Source maps allow you to read your code exactly as it was written
While it does reduce numerous errors, it does not enforce or even reveal exceptions like Java / Go / Rust. Typescript is my preferred language, but IMHO if reducing production errors is the goal I think there are better choices still.
I do understand where you are coming from, and I normally wouldn't say this about any technology – but Typescript is probably the closest thing to an actual silver bullet that has ever existed in front-end tech. In almost all cases it massively improves code quality at a low cost, and if I encountered an organisation that wasn't using it I would expect them to have evaluated it and have extremely clear justifications for that decision front-and-center.
At my job, we evaluated TypeScript and thought about the tradeoffs and decided to adopt it for all new front-end code, migrating older code when possible. The decision was considered and made. Do we really need to rehash the discussion every time a new front-end gets set up? How is that cargo culting?
If the requirements and purposes are the same for every frontend project you do, it obviously makes sense to reuse previous planning and apply it without rehashing the discussions.
Of course they aren't the same, but the benefits of using TypeScript don't go away from one UI to the next.
there are no tradeoffs with TypeScript.
One day you'll want to be able to call yourself "senior" and then you'll realise, everything about software engineering is about balancing tradeoffs and every choice you make comes with tradeoffs.
... i've been a senior engineer for over 10 years. TS is one of the only technologies i have found where it is only positive, in relation to Javascript.
"How did you decide for TypeScript, and how do you benefit from it" is among my first questions in interviews for TS positions. It's ironic how rarely I get a good answer, but it offers a good insight into their tech philosophy, and mostly I'd pass on the position. (working in backend)
If anyone asked me this I’d be kind of confused. If they really don’t know how choosing Typescript over Javascript benefits them I don’t want to hire them.
Interviews are a two way street. What you've said is the equivalent of an interviewee saying "If a company has to ask me how to implement a zero-allocation sorting algorithm in an interview, they are clearly incompetent and I wouldn't work for them". In both cases, the person doing the asking knows the right answer(s) more or less - they are checking if the person across the table does too.
I certainly would not hire a dev who thinks about their own convenience (not having to write types), instead of the consumers of their code (to have types as a form of documentation). Programming is too hard?
Eng velocity is pretty precious isn't it? I would at least say the formula here is defects prevented by using typescript vs features delivered.
no one can count defects "prevented", even if it's possible that has not been done at a meaningful scale.

Which renders your formula meaningless.

Sure but, that's (one of my) point(s). I think type systems prevent some bugs, but I more view them as this analogy:

- code formatter :: style

- type system :: tests

...which is to say that mainstream type systems tend to just unify what people in dynamic languages are doing ad-hoc in their test suites. As a result, I think their contribution to safety is overstated.

All of which is to say that posts in this thread coming out swinging for all of Typescript's safety improvements, while also arguing that it has no trade offs seem pretty off base to me. We can't even tell it's working most of the time.

The point I was making is, there are a lot of things in software that have no empirical data, so suggesting data driven decision making such as benchmarking because you don't trust Big-O or quantifying typescript's benefits instead of actually thinking about them is a cop out.

> - type system :: tests

This is an oversimplification. To me types are also documents, and not a "here is the public/high level API, you don't need the details" kind of thing, it's document on public and private API.

Types are also tools that help you think about your system. I assume having a tool to think make you think more effectively, but I can't prove that.

> The point I was making is, there are a lot of things in software that have no empirical data, so suggesting data driven decision making such as benchmarking because you don't trust Big-O or quantifying typescript's benefits instead of actually thinking about them is a cop out.

Sure, empirical knowledge isn't the only knowledge there is, but this is what your proposal sounds like:

"Hi $TECHLEAD, I think we should use TypeScript because it's good documentation, and because it helps me think about the system."

My response would be: "that sounds like changing our whole development toolchain, which would be a lot of work and carries a lot of risk; what if we wrote some documentation instead?"

In A Philosophy of Software Design, John Ousterhout writes that (paraphrasing) because code is always an imperfect representation of a model, comments are required in order to fill in the gap. This rings true to me, and I'm skeptical that any type system--much less a mainstream one--could overcome what seems like a fundamental limitation of information. I'm more receptive to documentation: comments, code docs, arch docs, etc.

---

> so suggesting data driven decision making such as benchmarking because you don't trust Big-O

The reason people benchmark is because Big-O notation is incomplete: it doesn't describe n. You can't describe the performance of a system with Big-O alone. Maybe I'm digging into a poor example here, but I don't think it really fits in our discussion.

> quantifying typescript's benefits instead of actually thinking about them is a cop out

This is a little dismissive; I'm actually a person who likes types and misses them when I don't have them. I often move between languages (or the same language typed and untyped like Python or JS/TS). Consequently I have some experience across lots of different verification/validation/constraint/testing systems. My general take is that what your type system doesn't provide your tests can compensate for, and since you (should) have tests anyway, a type system's benefits are diminished. Further, tests can check things type systems can't, and can be traced to requirements. For example:

    int add(int a, int b) {
      return a - b;
    }
A type system can tell you a lot about this function: its domain/range, overflow/underflow risks, etc. What it can't do is tell you that the function has the wrong name.

Dynamic language communities have known about stuff like this for a long time. Indeed a lot of people are fans of TDD precisely for the reason you mention: tests are tools that help you think and reason about a code base. Types are not a silver bullet, there are always trade offs, software engineering is the agony of never really being sure but having to ship anyway.

No one says you have to stop writing tests when you have types. You can have less tests when you have more types. There are type systems that requires an overhaul of the whole toolchain, but what we’re talking about typescript isn’t that. You can literally run plain js with jsdoc through tcs and make your comment provably accurate documentation, rather than a decorative one.

Im just too tired at this point to address the comment that having more types is somehow a burden on eng velocity while having more tests isn’t. In reality, you never have nearly as many tests as you ideally need, but you can add more types more easily and it will help people reason about your system much easier.

Speaking of which, tests are often way too verbose it hurts readability aka the ability to reason about your system

> No one says you have to stop writing tests when you have types.

My point is that if you have tests, you probably don't need types, and since you really oughta have tests, the benefits of mainstream type systems are overstated. A lot of arguments in this thread are essentially "types have benefits you can't get anywhere else", but you can get them with tests. When it comes to verifying program correctness, tests are a super set of types' functionality.

> You can have less tests when you have more types.

Can you? In my dynamic language work the tests aren't doing type checks, usually there's some kind of validation library doing that. Generally the tests are doing work that types can't.

> There are type systems that requires an overhaul of the whole toolchain, but what we’re talking about typescript isn’t that.

I guess we can disagree about "overhaul", but IMO adding a compiler, new dependencies (types) and entirely new syntax to your toolchain qualifies. If that doesn't, what does?

> You can literally run plain js with jsdoc through tcs and make your comment provably accurate documentation

A few things foil this:

- using `any`

- using untyped libraries

- taking advantage of gradual typing

- unhelpful type soup

"Type soup" really bears expanding:

    subscribeToMore(
        options: {
            document: DocumentNode,
            variables?: TVariables,
            updateQuery?: Function,
            onError?: Function
        }
    ) => () => void
I like Apollo and use it a lot, but I would say this signature from their docs [0] tells you almost nothing. There are some nice things, in particular the "pass an object blob as args" persists in JS despite having default and optional parameter support for a long time now, so TS adds nice description there (of course it would be better to just use optional parameters). But like, surprise surprise `document` is a DocumentNode, `variables` is... `TVariables` (whatever "T" might mean here), and it returns a function that does... well who knows (docs say it terminates the subscription, which I never would have guessed). It could be called "deleteDocument", and the types don't contradict that in any way.

Further, these types don't verify any behavior. They can't prove to you that `onError` is called when an error occurs. They can't prove to you that you will continue to receive data when it's updated. They can't prove to you that you subscribed to the specified document. On and on. There's a reason that high-reliability environments use tests, even though they're using strongly typed languages like Ada and Eiffel, and that's because type systems cannot fully specify a program's behavior.

[0]: https://www.apollographql.com/docs/react/api/react/hooks/#su...

It's crazy how just a few years ago, many web (turned Node) devs insisted that static types are overrated and one can totally maintain large code bases without. Now with the TS hype, the same people preach hoe useful static types are. I think it was just a mix of stockholm syndrome and lack of experience what working with static types is like.
I mean, if you're in 2012, comparing Java 6 or C# 2.0 or C++98 to Ruby or Python, you can see how people come to that conclusion. Local type inference has done wonders for the ergonomics of static typing, and while research-y languages have had it forever (and some like Haskell even allow the scope of inference to go further), it's a relatively recent addition to the mainstream.
If you are not writing your new javascript projects in Typescript I think you are just willfully hurting yourself.
Unit tests and types don't have as much overlap as anti-type people claim. You need both, and you shouldn't write tests for most of what type errors cover.

TypeScript transpilation is easy and fast. You can emit JS even when there are type errors, and use tsc as just a type-checker while using esbuild to strip types from JS. Performance is not an issue in practice and the benefits are pretty far reaching.

> Choosing to write something in JavaScript that is wildly supported on every platform via browsers

This statement makes no sense in two ways and shows you're not as accustomed to the problems at hand as you'd perhaps like to be. First, eslint is a developer tool and not intended to run in the browser. Second, you generally do not distribute typescript code but compiled js to target platforms.

> TypeScript seems to have entered the same hype cycle as Rust (if it didn't do it before Rust) where people seem to think that everything written in X should actually be written in Y instead (C/C++ => Rust and JavaScript/Any compile to JS => TypeScript). Doesn't mean every project have to follow that though.

No, TypeScript is a superset of JavaScript that can be enabled with little cost for the gigantic benefit of bringing type safety to a language which people have mocked for its unsafety for decades.

I really wish people on HN would hold back a little with their contrarian purism at all cost.

> First, eslint is a developer tool and not intended to run in the browser.

from the linked article: "Yes, that means an officially supported browser version!"

The point still stands that an officially supported browser version can still be typescript transpiled to JavaScript.
it's even weirder to say that and then say that you will add jsdoc, use tsc and publish types = having the exact the same processes without having a .ts at the end ahah
JSdoc comments are 100% JS while TS types are not. This means you will be able to run ESLint without a TS compiler while still having types for people who want them. It's also more future-proof for if/when JS adopts a type system that may or may not be compatible with TS.

This sounds like everyone wins except the people who are overly-dogmatic about TS.

If ESLint were rewritten in TS, you would still be able to run it without the TS compiler, since it would already be compiled into regular JS when published to NPM.
Why should you be forced to deliver via NPM?

What about Deno or people using it in web-only contexts?

If they use ES-compliant modules, a build step isn't even required.

Once again, it's not that they don't have types, but the TS fanboys are now complaining that it's "not the right types".

> What about Deno or people using it in web-only contexts?

i was under the assumption that deno natively supported typescript, no?

“Choosing to use JS without TS at this point has become a dogmatic statement of purism that, while beautiful in a sense, is so unpragmatic as to appear a little foolish” honestly sounds like a dogmatic statement.
While I'm in favor of TS, I'm in favor of it for practical reasons.

Since the new ESLint is going to be highly modular, TS would shine in defining these modules' interfaces in a robust way. Whether to use TS deeper down, or whether to enforce the use of TS across the codebase, is another question. Prototyping is often easier and faster with plain JS, while typing well-defined parts later may be helpful for maintenance purposes.

> Prototyping is often easier and faster with plain JS

I disagree, especially in the realm of AST-crawling, that having type hints in the IDE has been extremely beneficial in moving fast.

I have very often seen prototype code crafted in a REPL, not in an IDE. That's where the fluidity comes in handy.

Type-level refactoring tools don't seem to be very powerful at the moment, too; without them, you can end up with some legwork when you change a design decision (a frequent thing while prototyping), even if you carefully aliased every type (which is legwork in its own right, because trivial cases like 2-tuples are plentiful).

Fortunately, TS allows you to gradually type your code, and rely on inference in many cases (not as much as Haskell, but still).

What you want is a prototyping REPL, in your IDE, that gives you type hints, type aware autocomplete, and inline type errors, but knows to back the fuck off when you want to just run the code and perform simple type-stripping rather than erroring out and telling you to fix types or GTFO.

Bonus points if it comes in notebook form so you get a nice convenient run button, a solid multiline text editor, and markdown-powered persistence format.

Thankfully, this already exists: https://marketplace.visualstudio.com/items?itemName=jakearl.... . And it supports every language your shell does!

(I made it)

Doesn't JSDoc(which the original post wants to use) also allow you to robustly define interfaces?
Jsdoc has the same issue as regular comments. It’s not the source of truth but someone’s hopefully up to date version of the truth.
AFAIK the only thing jsdoc "can't do" that typescript can is "generic types", which is just syntactic sugar for having a base type that all others inherit from.
Eh, wanting to dogfood the JS tooling you're writing is a fairly valid reason, imo. Would dogfooding on TS cover many JS usecases? Sure. But inevitably some things are different. I'm somewhat sympathetic.
"much better safety"

Every bug to to ever hit production has

* passed all manual testing

* passed all unit tests

* passed the type checker

Everyone who has died drank milk.
This is a fully general argument for debugging in production.
I have written and shipped many Python bugs that did not pass the type checker but it was impossible to run the type checker because it would not be invented until many years later.
If you had a type checker bug you didn't you manually test that code path at the bare minimum. Type check bugs are the most simplistic bugs to catch. Is it nice sure, but if you can't spot those before you ship I can almost guarantee that you have larger logic bugs that the types won't catch.

What isn't helpful is the the notion that types replace testing. Either manual testing or unit/functional/generative testing. It isn't "safer" at all, it does speed up development by catching the simple bugs so the run edit compile loop is less. If you're saying "my code compiles then it's works", I don't buy it.

> If you had a type checker bug you didn't you manually test that code path at the bare minimum.

I'm glad that you agree type checkers help avoid error prone and expensive manual testing work.

> What isn't helpful is the the notion that types replace testing.

Types are a type of testing. They are another tool in the toolbox for writing correct programs.

> passed all manual testing

Or been ignored. It happens.

> passed all unit tests

If they have been written at all. And every bugfix should come with a regression test.

> passed the type checker

If it hasn't been disabled. And I would expect that a bug that could be fixed with better typing would include making types more restrictive when necessary.

Unfortunately, tools like testing and types are seen in two conflicting ways. Some people embrace them and see that they can use them to write better code with less bugs. Others see them as obstacles that have been placed in their way due to the additional learning curve.

That's a tautology. If you have manual testing, unit testing, and type checking then of course you are only going to see bugs that pass those.

But what bugs did you not see hit production because these eliminated it?

> I have to say, I think they'd be crazy not to write the new version in TypeScript.

I disagree. The lesson learned from a decade of js tooling is performance issues.

That is why you see more and more js tooling rewritten in rust or other fast languages.

This is GOOD for js development, in the sense you end up with better faster more powerful tooling.

JS vs TS does not impact runtime performance.

Now whether you use JS at all is a completely different point, but I think the parent was making a point about TS > JS, than TS > other languages.

Not directly, but it becomes harder to reason about performance unless you're familiar with the TS compiler and/or it's output. Once you identified a performance issue related to the JS VM(s) you're targeting, it's also harder to resolve the issue. This is true for every "compile to JS" language and TS is no exception.
Realistically, that simply doesn't apply to TS, because the conversion to JS literally just removes types.
Not always, because certain operations that look trivial in TS involve more code in JS, e.g. the widespread `?.` operator. The code is usually trivial though.

It's Flow that just allows to remove any type annotations; there's no compiler, only typechecker.

You're mistaken. Optional chaining is a JavaScript feature[1]. The stated goal of TypeScript is to be valid JavaScript when the types are stripped away. That's why they have functionally removed namespaces and they want to remove enums. They're the only language features that are actually compiled instead of just stripped.

[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

Indeed I'm mistaken; this only happens when the target JS version is old enough not to support that.
(comment deleted)
In theory this might be the case, but in practice all the TS compiler needs to do to produce valid JS code is strip the type declarations from the input. There are a couple of minor exceptions (enums don't exist natively in JS, and are replaced with objects, and things get a bit more complex if you use decorators), but in general idiomatic Typescript code should look the same as equivalent idiomatic Javascript code.

This gets a bit more complicated in some setups because the typescript compiler can also transpile modern JS/TS code to older versions, doing a similar job to Babel, but this doesn't have to be the case, and in practice this tends to be fairly orthogonal to the question of Typescript: you can compile to older versions regardless of whether you use Typescript, and you can use Typescript regardless of whether you compile to older versions.

So in practice, there will be no difference between a Typescript program and an equivalent idiomatic Javascript version, because Typescript is just Javascript with syntax for type hints.

98% of typescript compilation is just dropping the type annotations; Babel for example outputs TS almost exactly as written. There’s no voodoo compiler passes going on unless you add them on top of Typescript. There’s no practical performance difference from JSDOC comments unless you’re using tsc to target ES5 or below; and in that case vanilla ES2020 would need a similar amount of Babel shenanigans to downlevel iteration.
For the most part typescript does not significantly change what you input (except, of course, by stripping type annotations, type declaration, and type imports) unless you request transpilation to earlier ECMAScript versions or a different module format. (It will also by default transform TSX to ECMAScript, but it can be configured to output as JSX instead, which could later the handled by a different JSX transpiler if needed.)

The main exceptions are enums, and decorators, both of which perform straightforward transformations. My understanding is that adding new such features are forbidden as the TypeScript team considers them to be historical mistakes. If new syntax is added in the future is should be such that it can be mechanically stripped, leaving the obvious underlying JS behind.

There also exist some historical features like namespaces or const enums that have long been considered essentially deprecated by the team (not marked as such in the documentation, as there are no plans to actually delete support for them, but they won't work correctly in isolatedModules mode for example). In practice those features are not used in new codebases since project templates will be configured with isolatedModules enabled.

I don't think this is actually in disagreement.

The advocacy for Typescript is for type safety. Using Rust hits that same benefit.

They are choosing TypeScript, they're opting into type checking with JSDoc and tsc. For a brand new code base, you could argue that it would make sense to jump in and write TypeScript, but JSDoc and tsc will get them most of the benefits. It's almost a non-issue.
It's illustrative of how crazed some TypeScript advocates have become, that any deviance whatsoever causes them to be shocked and appalled, as some have expressed in this comments section.

People, if you must be religious about a programming language, at least find a more enthralling god than a JS superset!

From the article:

> ESM with type checking. I don't want to rewrite in TypeScript, because I believe the core of ESLint should be vanilla JS, but I do think rewriting from scratch allows us to write in ESM and also use tsc with JSDoc comments to type check the project. This includes publishing type definitions in the packages.

This is such a heated debate, and so many posts here are just simply wrong about the capabilities of using TypeScript as a type checkers.

A statically typed code base is a primary goal of the author, they simply pick to do it using JavaScript and annotating the types in JSDoc comments, using TypeScript only as the static type checker, which is an available—and well supported—option in TypeScript.

> Choosing to use JS without TS at this point has become a dogmatic statement of purism that, while beautiful in a sense, is so unpragmatic as to appear a little foolish.

You’re parent is simply just wrong here, and it is quite frustrating how many posts here simply take up this talking point and repeat it.

TypeScript is great for inexperienced devs, so i dont see why they should use it for eslint. Is there any benefit in using a language that transpiles to a different language that then gets interpreted that you had in mind?
You are wrong, and the statement that it is based on dogmatism is completely baseless. A couple years ago, the Deno team switched from TS to JS for performance reasons because compiling the TS code became painfully slow. This was an entirely practical reason. Similarly, a lot of JS package authors choose to use JS in conjunction with JSDocs, type def files, and tsc (see: Preact).
> A couple years ago, the Deno team switched from TS to JS for performance reasons because compiling the TS code became painfully slow.

It doesn't seem that performance was the driving factor, but the ability to keep code idiomatic?

https://docs.google.com/document/u/0/d/1_WvwHl7BXUPmoiSeD8G8...

I may be misreading, but from the first two bullets under "Problem":

> Incremental compile time when changing files in cli/js takes minutes. This is crushingly slow and painful to modify.

> The typescript organization/structure that we're using in cli/js is creating runtime performance problems.

Either way, my point is that there are very practical non-dogmatic reasons to use JS over TS.

This decision turned me off from Deno in a big way. It's as if they actively refused to look out to the community to see if the problems were solvable before throwing in the towel. It's quite possible to have instant incremental updating of TS projects, when I was a developer on VSCode (a much larger TS/JS project than deno) a change to the source code would be reflected in my dev build in less than 100ms.
Deno integrating TypeScript at all was a big mistake, but that doesn't mean that TypeScript at build time isn't a god idea, or that transpilation can be extremely fast with tools like esbuild.
That's not the point I'm making. I use esbuild often for TS development tooling.

But if you're building developer tools or libraries and want the output to be optimized for the end-user, introducing a middleman like tsc or esbuild can have tradeoffs. This is likely what the ESLint team considered.

It seems that some TypeScript and Rust devs are converging in their holier than thou approach, never missing an opportunity to belittle people for not choosing a tool they would have chosen.
It’s because I have to work with the thing. The current ESLint codebase is almost impenetrable. I enjoy people choosing tools I would have chosen.
I'd say it's more that people are still using archaic tools because of altruistic purism and that contributing to a gigantic js only project like ESLint is a daunting task.
Jetbrains still doesn't know how to set breakpoints in third party Typescript code.

opentelemetry.js is already an architectural nightmare (clearly built by people who use J2EE), but the fact that it's Typescript makes it ten times worse because I can't set breakpoints. I have to step all the way in every single time. Through layer after layer of delegation. So much delegation they had to pull out a thesaurus to name things.

JSDoc can do a lot of the things that Typescript does. Use it.

Not seeing a "why" here, though. If you like TS, go use TS, but if you want type checking then JSDoc does that job rather well and forces you to treat documentation as a first class citizen, too. With the obvious bonus of not needing to be compiled: the code you wrote is the code that runs, while having all the features in place to perform type checking. It just goes about it in a different way.

The goal is type safe code, and there are multiple paths that get you to that goal. Pretending that TS is the only, golden path and everyone else is hopelessly wrong -requiring hyperbole to mock even- suggests having lost sight of the actual goal itself.

is there a well-maintained and widely-adopted cli type checker for jsdoc other than eslint-plugin-jsdoc though?
You had me until "though": it sounds like you're saying that you need more than the one that already works?
pros use jsdoc ts, hehe.

for real, it's less the hassle.

I twitched when I read this issue, because rewrites so rarely end well.

I'd recommend a different strategy, personally:

Write a POC linter that demonstrates the features you think ESLint is missing, with no regard for interface consistency or backwards compatibility.

Once that's done, integrate it in a few real-world projects that currently use ESLint. See what the devs scream about, as well as what they like about it.

With all that data in hand, now you come up with a plan for making the desired changes to existing ESLint, being willing to consider the option of "nuke everything in the new branch".

You'd keep continuity of history for any files that aren't completely deleted, and you might find that you don't need to gut things as thoroughly as you expect.

I could not find in the post anything saying that they are going to abandon the current ESLint and let it rot while they write a new version from scratch.

> I don't believe continually to make incremental changes will get us to where ESLint needs to go if it wants to be around in another ten years.

The scale of years for rewrite and migration seems right.

Rewriting from scratch may make plenty of sense. A completely new architecture should not be held back by any remnants of the old implementation. The old test suite is indispensable though, and the old sets of rules are an important source to consult (even if not to directly incorporate).

> I could not find in the post anything saying that they are going to abandon the current ESLint and let it rot while they write a new version from scratch.

One thing that stands out is that they haven’t grown twice the manpower with institutional knowledge overnight. You have to put a lot of effort into your rewrite, and you have to fix bugs in the existing thing.

They can avoid building most new features in the old codebase (because they belong to the new codebase), and limit the work on the old codebase to bug-fixing. This looks realistic.
I wasn't worried about the team letting current ESLint rot- just about the possibility of the team sinking a bunch of time into architecture, planning, add starting from scratch that never really gets anywhere.

I do see your point, though.

Rewrites rarely end well but that’s not a reason to never do a rewrite. The problem with rewrites is that they’re often a very expensive solution to the wrong problem. If your system is bad, it’s probably not the code at fault, it’s probably something to do with the specification or communication.

However… when code is the problem, rewrites make a lot of sense. Eslint is a very well understood program, there’s absolute clarity about what it does and what it should do across contributors, and they’re constantly battling bad code. A rewrite, in this situation, where other problems have been ruled out, is probably a good option.

Thanks for sharing your thoughts. They make sense.
There can be advantages to undertaking a complete library rewrite[1]:

- If you've worked with the library (as a maintainer/developer, not as a user) for a long time you know where the fundamental pain points are and, after a while, the desire to get rid of those pain points can become overwhelming.

- Languages evolve; what might have seemed like a good architectural decision 3 or 4 years ago may well have turned out to be a quagmire of confusion now, which new features in the language (JS examples: promises; fetch; various Array functions) can help simplify.

- Rewriting from scratch can also encourage a better, more maintainable approach to code documentation (and generating online documentation from it).

- Being able to dump outdated/questionable tests in favour of modern testing best practice is always welcome.

- A rewrite from scratch can offer a chance to reconsider the developer experience for people who consume the library in their projects/products - though there's a danger that moving too far away from existing practices can damage trust in the library.

... Of course, rewriting from scratch is always a lot easier if your library is (relatively) obscure. I imagine the ESLint rewrite is going to be performed in the full glare of the spotlight - see already the lively conversations around the decision to not rewrite in TypeScript!

[1] - Speaking from the experience of rewriting my (very obscure) JS canvas library from scratch 3 times over the past 10 years

> Make ESLint type-aware. This seems to be something we keep banging our heads against -- we just don't have any way of knowing what type of value a variable contains. If we knew that, we'd be able to catch a lot more errors. Maybe we could find a way to consume TypeScript data for this?

An ESLint plugin manages to do this well[1]. Would be nice to have this functionality built in natively although you do take a performance hit because you have to run the compiler.

[1] https://typescript-eslint.io/docs/linting/typed-linting

I'm wondering if the first stable release of Rome [1] JS/TS linter has influenced this announcement.

[1] https://rome.tools

If it did, the ESLint rebuild discussion is ignoring one huge advantage Rome has that the ESLint rebuild will not have: Rust performance.
They do state in the link that some portions may be written in rust for performance.
Actually, Rust-based implementations are mentioned under Goals, item 6.

It looks like ESLint wants to compete with all Rome can do.

I've been sensing this coming for some time given what Rome has been working on. Will be interesting to see how the rewrite pans out!

Any discussion these days around eslint reminds me of a new situation that still has me very confused where I've encountered a team of engineers that refuse to allow any formatting on their code. Are there any folks that run large JS/TS codebases with no automated linting/formatting by choice and maybe feel similarly or worked with other teams that do? I've come to expect eslint (and prettier) to be pretty much a given for a large JS/TS codebase.

For anyone wondering, Rome [1] is a new JS/TS/JSON formatter and linter written in Rust.

[1] https://rome.tools

I wish rome lint was a drop-in replacement for ESLint.
It will be pretty close to that. They are talking about a tool for migrating ESLint configs in the future.
It’s not a JSON formatter yet :P
Contrary to what seems to be popular opinion here on HN, I think it's fine they'd entertain keeping their code as JS with JSDoc, rather than TS. It's still typesafe, which is what's important from a maintenance and documentation perspective. A linter than goes all in on TS is what tslint was (and it worked on JS), and ultimately it lost to eslint in the linter popularity wars (as has jslint, and jshint, imo). If JS source is the sauce that keeps contributions coming and the downloads flowing, then so be it. There's also some value in dogfooding their own JS lints, rather than TS ones. Sure, there's overlap, but undoubtedly some differences, too (especially any rule that lints jsdoc).
I’m kind of inclined to say that eslint won because they have typescript evaluation as well. If it didn’t work on Typescript you’d see less and less people using it.
If they pull this off, does this mean we can use ESLint in a directory where I haven't (and don't need to) run "npm init"?
Seriously ... how many of us who are debating the decision to write it in JS instead of TS are ever going to submit the PR to project or will contribute in any other meaningful way ? ;)
Not sure that’s particularly relevant. I think people take issue with it because it has impacts on the stability and reliability of the result
Here is the Joel Spolsky‘s obligatory argument against code rewrites:

Things You Should Never Do, Part I

https://www.joelonsoftware.com/2000/04/06/things-you-should-...

While I don’t necessarily agree that we should never ever rewrite, he is making some good points that we can ignore at our own peril…

yeah, was thinking this.

Of course, in this space I don't think eslint has many competitors, unlike Netscape vs IE did then, so they've got time.. for now.

I'm sure 'old' eslint will be mostly ignored in the meantime, as the excitement will be with the new shiny.