In the magical world of WebDev, things move fast. Because of this you should be aware of what the hot new things are, but more importantly, you should be looking for "boring technologies that just work". Practical tools will save you years of hassle and headeache. But most importantly is to kill technologies that serve no purpose any longer.

  • Types
  • JS Frameworks
  • Testing
  • Bundling, treeshaking, live-reloading, HMR, etc
  • Local JS runtimes/package managers
  • Styling
  • Linting
  • Browsers

Types

  • JS is and always will be a dynamically typed language. There is a lot of power and convenience that comes with this. But with power comes dangers. There are those that dedicate themselves to JS and know it well enough to have no problem working around the danger and still taking advantage of this power.

"TypeScript solves problems I don't have, in ways I don't like."
– Kyle Simpson, Author of the highly influential "You Don't Know JS" book series.

  • But if you don't want to be an expert, or just want a tool to make sure you don't run into these problems, that's where TypeScript comes in.
  • TS hype hit its peak a few years ago and has mostly plateaued. It solves some problems, but also creates a lot of new ones.
    • Though adoption has slowed down, it is still extremely widely used, and there is wide support across the ecosystem and tooling for it. Though having to deal with so much tooling could be avoided by using the next option:
  • Some people use JSDocs + ESLint-Plugin-JSDoc to solve the same problems differently without all the downsides TS comes with.
    • Svelte, for example, switched over to this approach, and many others (myself included) have as well.
    • The JSDoc approach is fully compatible with the TypeScript Compiler (tsc) and the TypeScript Engine (used in editors like VSCode), and is also recommended by the TS maintainers.
    • JSDocs isn't a "cool" or "sexy" option, but it is very practical.

JS Frameworks

  • React is still the "most used", but is also quickly becoming quite unpopular.
    • It has consistently been the worst option every year since its inception. Despite massive improvements over the years, its just never been able to keep up with the rest of the landscape. For example, in the past ~5 years all JS frameworks have introduced some form of "signals-like" API. React was the last one to the party, releasing their attempt at this concept less than a year ago. Even Angular beat them too the punch. But with all these years, and all these other examples to look at and learn from, their API was still somehow the worst designed of them all.
    • React, to this day has still, never come up with a solution for how to deal with styling that doesn't have huge drawbacks.
    • It has thousands of weird idiosyncrasies that require you to learn entire books of bandaid patterns to work around these react-exclusive problems.
    • It's just plain slow and painful. The only people using it now are newbies that have never tried anything other than it. or people that are forced to by their jobs.
    • The current trend for those stuck with using React is to try to obfuscate it as much as possible behind Next (mediocre meta framework). Next has had a lot of controversy recently though due to its security issues and the company that owns it being dicks or something, I don't know, I don't care about this ghetto-ass basic-bitch drama. Fuck anyone still using this trash.
    • Because no one wants to deal with this garbage anymore, there are tons and tons of "red flag" React jobs that flood all the online job markets, which perpetuates the stereotype that everyone is hiring for it, which makes newbies think they need to learn it, and it makes other companies think it's a good idea to use it. It's basically the same problem we saw with PHP in the 2000's and early 2010's.
    • Similarly I think the only path forward for React is for the community to relentlessly mock it, like we did PHP for over a decade until PHP finally fixed all of its issues. New generations need to be warned away from React the same way we warned them away from PHP.
  • Svelte
    • It has the most hype at the moment. Its main claim to fame is that it does not use a Virtual DOM, and instead requires a compilation step to produce render functions that mutate the DOM directly. It is the fastest JS framework. Its templating system isn't the best, but it's much better than JSX (commonly used by other JS Frameworks, like React, Solid, etc). It has a much smaller ecosystem. However, because it's mutating the DOM directly, it's more compatible with existing "vanilla js" libraries, which sort of helps. But ultimately you use a framework for the ergonomics, so having libraries built specifically in the same style with it in mind will feel better to use, there just isn't a lot of that.
  • Vue - Still the best option, though hype has completely died off at this point.
    • Vue's hayday was back in 2018 where it out-paced React in GitHub stars and was the open-source darling saving us from a miserable life of using React and Angular (the worst, and second-worst frameworks that were consequently the most and second most used 🤦).
    • Because of Vue having the best templating system in all of JS, despite using a virtual DOM, it ends up being ~99% the speed of Svelte. A very close second place. Vue renders 2-6 times faster than React. It's all component-dependent, but Vue's worst case scenario will still be twice as fast as React's best-case scenario.
    • They are currently trying to add in "vapor" mode, which would allow for toggling using the real or virtual DOM on a per-component basis. If that every comes out (who knows), they would be the only framework with this ability, unlocking speed advantages no other framework could offer.
    • Vue can be compiled, just like Svelte, but it can also be used directly in a browser, via CDN for simpler use cases.
    • It comes with the most important innovation in Frontend since the V8 engine, "Options API". This is a built-in way to write your components that is self-organizing. Solving the hardest problem in frontend, how to keep your code organized. I can go to any Vue component in any repo in the world, and as long as it's using Options API I will instantly know where everything is. This is the one feature every JS framework needs to steal from Vue, but as of yet, none have.
    • It also offers access to atomic reactivity functions, which can even be used as a replacement to Options API if you prefer to write spaghetti code. I jest, but it is very useful to have this low level access to the world's most advanced reactivity engine. However, I would not recommend using it for components in an application, it is better used for rare advanced usecases or building libraries.
    • Vue has the second largest ecosystem, after React. But more importantly, it has the best secondary libraries of any JS framework, which is the real reason you use it.
      • State Management - Pinia is a goddamn miracle. It is perfect. No notes. I would not change a single thing about it. It solves every problem I care about, and every problem I could imagine someone caring about. We do not deserve it.
      • Client-Side Routing - Vue-Router. It is officially maintained by the Vue core team. It used to be slightly easier to use, but it's still by far the best solution in the JS landscape to this problem.
      • Dev-Tools - There is the browser dev tools, however you're better off pulling in the Vite-Vue-DevTools plugin. It's great, works with Vue, Pinia, Vue-Router, etc.
      • Testing - Vue-Test-Utils is really solid. Gives you great control for writing frontend unit tests. Pair it with the Vue3-Snapshot-Serializer for a much easier way of writing unit tests that no other JS Framework can compare to.
      • Component Documentation - Vue-Doxen is as easy as it gets. It's just a Vue component that you pass your component into and it does all the rest. Extremely extensible and customizable. Again, this is Vue-exclusive benefit. No other JS framework has anything like this.

Testing

  • Unit: Jest and Vitest are like 98% identical and are both the best option today, all other options are pretty shitty in comparison.
    • Jest is slightly faster
    • Vitest is slightly slower, because it prioritizes correctness over speed (be thankful that it does)
    • Vitest is architected in a way to take better advantage of "Shadow Realms", an upcoming JavaScript feature. Once added into Node.js, it will allow Vitest to go much faster than Jest
    • Under the hood they share about 80% of the same code, and their API's are almost identical.
    • I prefer Vitest, but both are good and practically the same.
  • E2E:
    • Cypress: This was the go-to option for a long time, but has so many weird API choices that feel very much like the jQuery era of JavaScript it was created in. In the past 5 years Cypress has gotten much faster, which is great for those with large codebases already in it, but ultimately going from 50% as fast as Playwright to 80% as fast, is good, but still noticably slower.
    • Playwright: This is honestly the only good option for E2E currently. The way it allows you to organize and write tests feels much more modern and cleaner. It's the fastest option, but ultimately it will still be orders of magnitude slower per-test compared to writing unit tests.

Bundling, treeshaking, live-reloading, HMR, etc

  • Webpack: It's long dead, no one misses it. Technically it is still useful in the sense that it can handle like 5 different JS module systems. But now-a-days if you are using anything other than ESM you are doing it wrong.
  • Vite: From the creators of Vue.js, the best JS framework, come the best JS Build tool. It is extremely fast, because it only supports ESM. Under the hood much of the underlying tooling has been re-written in Rust to make it as fast as possible. The config tool for it is also pretty straightforward and easy to use. Vitest (mentioned in unit testing) is built on top of it, and uses the same config file, making everything simpler.

Local JS runtimes/package managers

  • There are options like Bun and Deno, but 99% of people still just use Node.
    • Bun uses the same JS engine that Safari does, giving it some cool tricks. Its main purpose is to be as fast as possible. It's VC funded and many are skeptical of its long term utility.
    • Deno is from the same person that created Node, but this time "done right". What that means, is your imports can point to URL's, and everytime any module tries to access the file system or make a network call, it has to ask for permission first. This is much more security minded, but also a massive pain in the ass to deal with.
    • Both Deno and Bun are basically just "Node, but with TypeScript support". In the sense that they can process TS to JS, or can use .ts files directly without having to process them first. But the latest version of Node can also do this (kinda). When fed a .ts file, Node will now just ignore all the TS syntax (as if they were comments), and execute it as though it were normal JS. Because of this, there's really no one using Bun or Deno, except for rare, specific usecases.
  • Package managers
    • Yarn - Dead, this was around for a few years. It came out with 12 features npm did not have and was much faster than npm. But then npm became faster than Yarn (and still is), and over time all Yarn-specific features got added to npm, so no one bothers to use Yarn anymore, as it does the same thing and is slower. Facebook created it, then handed it over to the OpenJS foundation to maintain it because they were done with it. If you are doing a monorepo (which you probably shouldn't be, but if you are), there are options like npm Workspaces, Lerna, Turbo, and Yarn. They are all basically the same and most people will be fine with npm Workspaces, but each has some unique thing it does the rest don't, so that's really the only thing Yarn is still used for. Some people need its niche monorepo features.
    • npm - Basically 100% of people use npm. It's fine, and works well enough.
    • pnpm - This does a few things differently, mainly using less disk space than npm, but who cares you have so much disk space, this isn't the 90's. Performance wise, in some cases it is much faster than npm, but not in a way that you care about as a human. The percent of people using it is a rounding error. Its got some niche edge case uses, but most of them are deprecated or recommended not to use by the maintainers.
  • Volta

    • omg you guys, Volta is so fucking good
    • Don't install Node or npm yourself, just install Volta
    • Put this in your package.json:
    {
      "volta": {
        "node": "23.11.0",
        "npm": "11.3.0"
      }
    }
    
    • With this, when you cd into your project, you will already be on the correct Node/npm.
    • You can run volta pin node@latest or volta pin npm@latest and it will update the version in your package.json for you. Works on all platforms. Highly recommend.

Styling

  • Sass
    • Sass was used for decades as a simple tool for everyone. Though it was extremely powerful, most of the people using it were just trying to get these main features:
      • Variables and nesting in CSS
      • File modularity and automatic concatenation/minification
    • We all use tools like Vite now that handle the concat/minify for us.
    • CSS as a language has added in CSS custom properties, which, are much more powerful than "variables", but can also be used as them. It also added in CSS nesting which has wide browser support now too.
    • With these common problems solved outside of Sass, its utility has waned. So the maintainers of it pivoted and the new versions of the Sass language are no longer focused on being "an easy tool for everyone to use" and instead are now "a complex and powerful tool for people building large complex CSS systems and frameworks".
    • So it doesn't get used much anymore
  • Bootstrap was for over a decade the go-to solution for "please god, just do CSS for me, I don't want to learn CSS". But it has fallen out of favor, as Tailwind and component libraries have taken its place.
  • Vue has really good solutions for styling. It has component specific scoped styles, supports Sass, Tailwind, and CSS Modules.

Linting

If you will be working in a project for more than 5 days, you need to set up linting, it will save you so much time and hassle. Any time you say "I don't get it, that should have worked, why doesn't that work", the first thing you should do is run the linter. If you are lucky it will solve your problem in a few seconds and save you 20 minutes of banging your head on the desk looking into why your code doesn't work just to find out you forgot a semi-colon.

  • ESLint is still the king, nothing else comes close. However, they've recently externalized all their style-based linting to a plugin called Stylistic. There are actually a bunch of really good plugins for ESLint to handle things like organizing ESM imports, accessibility, etc.
    • Config Generator - Creates an ESLint config with a bunch of preset (TJW) options to make your life easier, while still giving total control right in the ESLint config file.
    • AntFu Config - A JS function you import and run, passing options into. Handles a lot of cases, and offers some control, but not full control. May be too much of an abstraction for some.
  • Prettier - This is a technology that conflicts with all other technologies including itself. There really isn't anything it can do that ESLint can't do. It has a lot of really dumb default settings that don't match what anyone in the JS ecosystem uses, and most of its settings can't be changed. I seriously can't warn you against this enough, it causes so many problems with other tools. ESLint can auto-fix things on save as well if you want that.
  • There are several other smaller linting tool alternatives. ALL of which are much faster than ESLint, however, none of them support the insanely large ecosystem of plugins ESLint has, which is really the reason you use it.

Browsers

There's really only 3 browser engines in use now. Everything is either a derivative of Firefox or Chromium, or it's Safari. All Firefox based browsers will use Gecko and Spidermonkey. All Chromium based browsers will use Blink and V8. So you should manually test in at least one browser for each of those, and maybe Safari if you feel like it.

  • Chromium - There's really only one option, Ungoogled Chromium. Despite there being a bunch of Chromium based browsers, this is the only one that doesn't actively spy on you, or come with a massive amount of preinstalled junk and ads.
  • Firefox - Sadly, Firefox recently removed all mentions of "we do not sell your data" from their license, website, and legal docs. Which... means they sell your data. Sad times. But fortunately there is Waterfox. Been using it for a while and it's literally just "better Firefox". Doesn't spy on you or sell your data. Has better Tab UI customization. No built in "Try our Mozilla VPN" or any other product ads. Better default settings overall. It's just better.

Kill your darlings

Technologies come and go, new ones fix the problems of the old ones and we move on and evolve. This happens faster on the web than anywhere else, and so we must be vigilant not to get attached. Rip those bandaids off.

The following are my recommendations based on being completely practical and objective, based on the pros/cons of these technologies.

  • TypeScript is completely replaceable by JSDocs. It has all the same abilities (even enums/tuples), plus more, and none of the downsides. Some people don't like the way TS looks, some don't like the way JSDocs looks. But between the two, you can code-fold the JSDocs comment blocks (Ctrl+K,Ctrl+1) and you don't need to look at them. So even for this non-practical, personal preference, they win out.
  • Webpack is slow and hard to configure and use. Vite is faster, simpler, and easier to maintain. It has become the recommend approach by all major JS frameworks.
  • React is so bad that if you use it I will make fun of you, just use anything else. Vue is the obvious winner, but as long as you aren't using React, I really don't care what you are doing instead.
    • Except Web components. These never got off the ground. There's no good tooling or options for them and they just flat out don't work in production.
  • nvm, nodist, n, and nvm-windows are all buggy, and platform specific. Just use Volta, it's cross-platform, stable, reliable, and doesn't require you to manually switch Node versions. You'll never be on the wrong Node version again, it's so good.
  • Yarn is long past it's prime. npm is faster and can do all the same stuff, and everyone else that switched to Yarn has switched back to npm.
  • Cypress has been usurped. Playwright is much faster, easier to use, and allows for better code organization and test writing.
  • There are a lot of unit testing tools (Jasmine, Chai, Ava, Tape, QUnit, etc) and they are all very dated compared to Jest and Vitest. Just use Vite and Vitest together. They use the same config file, so it's much simpler.
  • Unless you are doing a very complex CSS framework, you're better off moving away from Sass.
  • Uninstall Prettier from your editor. Disabling it probably won't be enough, it is extremely aggressive about doing it's one job (conflicting with other tools). Get rid of it. Use ESLint, it's worth the extra time to set it up, you'll get more out of it. You can also have multiple ESLint config files if you want to run a subset of your linting options for faster linting of specific folders with unique npm script commands.
  • It's a good day to switch your browser. Try one that actually respects you.