document.querySelectorAll is indeed a great thing and I’m happy the last browsers that don’t support it are extinct. However, even plain old getElementbyId and getElementsByClassName were enough for a lot of use cases. Definitely enough for using the web as a GUI toolkit.
It’s just such a mouthful! I know many people recommend/do var $ = document.querySelectorAll, but meh. I prefer to use jQuery for this and other DOM API awkwardness (you can build it without SizzleJS meaning it’ll use querySelectorAll).
var $ = document.querySelectorAll
Depending on the app, I think it’s possible and advisable to create a modern web app with a little bit of plain JS. Basecamp have a whole thing about sprinkling JS on top of a solid HTML/CSS foundation, and their new email app HEY is supposedly built like that, with JS just taking over HTTP requests (links, form submissions) and applying them in-place. (I haven’t used the app, I’m just intuiting based on a Twitter thread that was doing the rounds). So basically, you’d use:
Web Components are a set of specs that as a whole should further the goal — just drop in its JS file and get a new custom component with which you interact like any other DOM element — but unfortunately there are various roadblocks, bugs, and limitations that limit their impact.
Closer to the SPA spectrum (one HTML rather than many), you definitely can have everyting in plain JS, but it won’t be a little for anything non-trivial and it will get unwieldy. I guess there are two parts to the “plain” story:
not transpiled, nor supported by any build process; this is a major spaghetti maker. Without proper support for modules, dependency management is finicky and you’re stuck with carefully putting everying in the right order in the global namespace. Support for native modules is gaining ground, but for near-universal support you can’t rely on them alone.
using the Web APIs directly, rather than relying on libraries and frameworks; definitely possible, after you develop a sense on how to organize things, but I think for larger teams it can become challenging because keeping it sane relies on devising, and following, your own rules and constraints.
My last from scratch project I built using Stimulus (https://stimulusjs.org/) from Basecamp. It’s just enough JS. That plus turbo links really made the app super simple but also SPA like.
I think we could get a long way by injected a middle path between “completely plain, download from cdn url” and “dependency hellhole full on framework with multiple compilation steps” projects tbh, it’s just that the tooling and norms are pushing you towards the latter and the type of person attracted to the former is not necessarily going to have the knowledge or patience to leverage the standard tooling in a more minimalist way.
It is possible to support stricter subsets of modern browser versions if you want to avoid a lot of back compat compilation steps with Babel or remove it entirely, it is possible to limit your dependencies to heavy well specced libraries like markdown or community standard utility libs like lodash, or at the very least be meticulous about what needs to go in build dependencies vs devDependencies. but it takes both domain knowledge and patience which don’t necessarily pay off in commercial work (until of course, they do, but by then you’ve got a massive SPA on your hands most likely and the issues have been compounded).
And this problem is of course transitive and endemic to the community norms, your well selected libraries must themselves also have been authored with an eye towards similar standards, and the bigger your project gets the more likely it is you’ll have dependencies or transitive dependencies that carry some bloated or poorly maintained package dependencies of their own. I would love to see workflows that have the flexibility of build and bundle tooling with a minimalist approach to dependencies, but it’s just quite uncommon atm.
See also: http://vanilla-js.com/