I am intrigued by "less js is more fun" approaches like htmx and alpine.js but that still leaves a range of options on how to organize things and some may bring you dangerously close to what OP describes.
I am intrigued by "less js is more fun" approaches like htmx and alpine.js but that still leaves a range of options on how to organize things and some may bring you dangerously close to what OP describes.
Ironically enough, the last paragraph of the article? About hating node while refusing to switch to bun or deno? That kind of decision might have prevented some of the pain mentioned in the previous paragraphs.
I don’t have an object-level answer for your question, and I’m not trying to mislead you into thinking it’s possible to actually have a minimal setup for JavaScript web apps - it’s always going to be painful. But with a commitment to maintaining minimalism you can pick a stack to start with and mostly keep it that way. The grass might be greener on the other side, but the fences are made of razorwire!
As systems evolve, they always get more complex. Web front ends are evolving to keep up with users, app archetypes, and business needs. People choose tribes to identify with, angular vs react vs vue. People are ambitious and pushing their own frameworks while tearing down others. Its just programmer politics, no different from windows vs linux vs osx.
I learned react, stuck with it, and it has worked out.
Had to choose a test for an interview. Some UI required.
Ended up using Blazor Server, got it done..
There must be a sweetspot of tools and designs that helps organize a modest code base to get the benefits of reusability and readability without too heavy a penalty.
Imho frontend people gladly walked into the trap of "excess complexity" as this elevated this niche into a "serious" business. Whenever some aspect of tech doesnt make sense, follow the money and this usually clears things up.
The issue you might run into as you scale up is managing the state and synchronization of a large, complex UI. This is where having a reactive, declarative interface can help out a lot - which is why you arrive at React and tooling around that, or something much like it. That's where most large UI projects end up, frontend or backend.
You must be joking, Mr. jrajav :)
Native DOM APIs are just as bad as they always were. Because they are stuck in the 90s era of heavy imperative APIs.
There are a handful new additions that are somewhat nice, but all of them either underdesigned, or with warts you need to be aware of (querySelector, querySelectorAll and native fetch come to mind).
Building a UI from scratch with them is just as cumbersome and awkward as it was in the early 2000s, and you'll end up re-implementing half of jQuery at least in the process.
1. Use npm. Well, I didn't try yarn, probably it doesn't matter.
2. Use vite. It sets things up good enough and pulls only 15MB dependencies. Tiny!
3. Use TypeScript. I can't imagine writing untyped code.
4. Use eslint to complement typescript checks. Takes some time to set it up first time. Use default rules, they're good.
5. Use prettier to format code. I use vscode and with corresponding plugins, it just gets out of the way. It's good thing to have and works with minimal setup.
6. Use react. Well, it's pretty much standard nowadays and things are mostly fleshed out. But it's pretty complex so beware of steep learning curve. But once you learn it, it's not going anywhere. At this point I consider react a fundamental knowledge, worth spending time to learn.
7. For state management use react-query (yes, that sounds strange).
8. Use built-in to vite methods to access CSS (I think it's called module CSS).
9. Don't add any more dependencies unless you absolutely feel like it. Don't add CSS frameworks or things like that, just write your CSS by hand.
This was the least pain setup I ever had and I consider it to be minimally viable.
Better use pnpm, faster for those that don't have 1 Gbps uplink and live outside the usa.
> 3. Use Typescript
Better use jsDoc, d.ts files are scary and are really complex, you need a typescript wizard la matt pollock just to tell you are mistakenly trying to concatenate a string and int.
> 5. Use prettier
yes use prettier but don't forget to configure eslint to work with prettier otherwise you are going to have a bad time.
> 6. Use react
Use whatever fits your problem but if you are going to really use rect then do it with Next.js, no point in still using CRA/CRACO
> 7. state management
Avoid using state, try to solve every problem with pure functions, if you must use state then consider redux/react-query
> 8 & 9.
You should still recommend stylelint, specially if you are going to write css by hand otherwise don't just use tailwind, tailwind is bootstrap with extra batteries (change my mind).
Can you elaborate? I'm using eslint and prettier with pretty much default settings and never had it conflict with each other. My impression was that they work on different aspects. May be there're some overlapping eslint checks, but they're not enabled by default (or I didn't stumble upon them yet).
Why would you use d.ts files and not just... .ts files?
Personally i think typescript isn't going to be around much time on the frontend side, maybe on the backend by some people that still believe in adding another compiler layer to their build time.
Thing is, most of the problems described in the post aren't related to low-JS front-end libraries like HTMX or alpine. You can write React without a linter, bundler, build tool, unit testing, or linting (or dependency manager, for that matter!). But with any of these projects at scale, you start wanting more:
- If you want to write unit tests in JS, you need to choose a test runner (probably Jest or Vitest -- until the built-in node testing module becomes more common).
- If you want linting, you need a linter (probably Eslint). If you want type safety, you need a type checker (probably Typescript).
- If you want to create smaller JS files to ship to production and to automatically handle assets, you need a bundler.
- If you want to use new language features while supporting old browsers, you need polyfills.
- If you want to use all these things together, you need something to bring it together (like Webpack).
So it really depends what you need! You may not need any. But as you can imagine, in many professional projects with multiple developers it's very nice to have unit tests, linting, and type checking :) (And you start caring about end-user performance a lot more, in which case optimizing the shipped bundle is important.)
Take all that, and then compare to a language like Rust, which has most of the "ecosystem stuff" built-in. In Rust, you get the test runner, the linter, dependency manager, type checker, and documentation tool all included. Easy! Thankfully, Rust doesn't have to care about whether users support modern language features (because it compiles down to lower-level code ahead of time), or whether the binary shipped to the client is optimally organized for downloading immediately over the internet.
It's a problem in JS because A) you have to care about more problems than many other languages since JS needs to load instantly over the wire in a web browser, and B) there is a huge amount of choice and not a lot of standardization in web tools. (And what standardization there is (Node, npm), there are still competitors trying to even further reduce the pain points.)
I think that in ten more years, we'll be in a better place, because there is push back (like this post!) against these problems, which will encourage more tools trying to solve the explosion of tools. Which seems counterintuitive, but these tools were created to solve very real problems. So I see it as a pendulum which has swung too far, but will likely swing back to a more balanced place. And you see that with tools like Vite gaining popularity.