It's purely demo code. I personally subscribe to the "modules should be deep" school of thought (Ousterhout).
> tests test the same thing twice: once with a unit test, and once with an integration test
Again, purely a demonstration that Playwright handles E2E, integration, and unit tests equally well, not an endorsement of testing the same thing twice. Note the absence of jest, mocha, etc.
> somehow better
Hopefully, you can achieve similar gains to [0], e.g. 50% less time to load and 95% less bandwidth in that case, by avoiding frameworks and other runtime dependencies.
> more sustainable
Hopefully, code produced this way is less susceptible to framework churn and other changes in the environment. Also, knowledge gained by following the approach will be about the standard web platform, not about a particular framework (and version thereof).
FWIW Vite would indeed handle the responsibilities of sass, typescript (partly), s4d, terser, cbst, vendoring (but not eslint, stylelint, prettier, playwright, c8, exdom). It's certainly a good option!
One thing to consider is that Vite promotes a plug-in ecosystem, of which many plug-ins are maintained by individuals. I think this increases the chance for incompatibilities over time significantly.
Also, having more documentation is not necessarily good. Each tool in Vanilla Prime has its own documentation, but they are self-sufficient. Vite combines lots of things in the background, which already have documentation, then adds their own documentation, and often requires additional plug-ins that take care of integration.
Maybe Vanilla Prime could be the car you can repair yourself, whereas Vite is the modern car that is so tightly engineered that repairing without external support becomes difficult.
I like to look at it as a spectrum from "truly vanilla" to "same old bloated". I've previously looked at the dogmatic vanilla approach here [0] and wanted to try something else this time, on a different location on that spectrum.
In all honesty, I've never got to properly look into Vue, but it has been mentioned multiple times in the comments. Time to study it I guess :)
The "src/js" directory was initially called "src/scripts" but it kind of clashes with the top-level "scripts" for the shell scripts. Agreed it's not ideal though.
Not sure who said it but I was aiming for the "Simple Ain't Easy" trope here ;)
I agree that the JS build scene can be churning a lot as well (e.g. ESLint's recent config changes), that's why I tried to make everything as orthogonal and disposable as possible.
I was pondering if "vanilla" should be part of the name as well. In the end I felt I got sufficiently close to the vanilla flavor you describe, and the name conveys the "as little as possible" approach. Hope it's not too misleading!
I do like the "plus" idea, now that you mention it! Will think about it :)
Original author here, thanks for the comment! I also think that backend would be an interesting subject to try and reduce, if only to not constantly wade through 100s of Dependabot pull requests... It's a very different scenario where you will want to optimize different things (code size usually does not matter as much, for example) and you have various deployment options (serverless, containerized, edge, ...) etc. so quite the Pandora's box, I think. Interesting nonetheless!
I find "web platform poorly designed, therefore frameworks with 100s of dependencies" a bit too easy, especially when the user experience suffers in the end. I also believe that not every complexity needs to be solved with code. Isn't it a worthwhile exercise to figure out if something can be solved with (significantly) less code?
> It has to be somewhere.
I tend to agree; I think I'm just trying to not shift it to the user device's runtime.
Original author here. No, you don't need all of it; everything is optional (as stated in the article). It's just a boilerplate with some tools and conventions, so "using it" has little implications, I think. Other than that, I'm just trying to have fun out here :)
Thanks for this, gives my intuition some words to back it up!
I find especially compelling how the author separates concrete problems like reconciliation (hard to argue against) from the abstract principle of "everything should be a component" (can be argued more easily IMO).
Shamelessly plugging https://github.com/morris/vanilla-todo here; in this try-hard-to-stay-vanilla case study there are similar conclusions: Reconciliation is hard, CSS global namespace is problematic, etc. - I also did not use web components, but could not explain/justify that decision well (until now!).
Original author here, thanks for sharing! The case study has been discussed back in 2020 [1] but there have been quite a few updates (ES2020, local dev, testing, etc.) since then. Happy to chat!
> The point is requirements change, features are added, and when an abstraction becomes wrong, tear it out.
I like this phrasing a lot, thanks for this!
I'm still wondering if there's also potential in avoiding the wrong abstractions in the first place. For that we'd need a "cheap" way to decide whether an abstraction is good/bad/something else.
Is there generally applicable, widely accepted principles or research around this? A quick search only revealed random blog posts; nothing I'd consider widely accepted.
Did some research on this a while ago and I‘d wager that 5x in LOC & growth is a bit off: https://github.com/morris/vanilla-todo - probably it’s more around 1.5x (which can still be problematic). Would be interesting to rewrite the study declaratively and compare again.
Not sure about the interruption handling, maybe I need to do more research there.
But totally agree with the last parts - currently, typical SPA implementations are often misguided and create more problems than they solve (if any) compared to a server-side approach. That does not mean that pure server-side is always enough to provide good UX, especially with interactive/offline apps.
I've heard the Assembly vs. C analogy a couple times now, and find it hard to apply:
Assembly languages come in many flavors whereas C is a single, standard abstraction over these.
DOM is a single, standard API whereas frameworks/libraries come in many, ever-changing flavors and provide different abstractions over the DOM.
It's a very different situation. Also, the level of abstraction that C provides over assembly is amazing. The level of abstraction that React provides over the DOM is comparably low (they are based on the same programming language).
True, we should respect all the resources of a device, at best. Also true for desktop (Slack's memory usage comes to mind).
A major result of the study is greatly reduced bandwidth (and consequently, shorter parse time) compared to the original TeuxDeux, so I'm working towards respecting these resources, for what it's worth.
To be clear, the study does not care about doing SPAs or not. The results are applicable to server-rendered HTML as well (write a function that enable some behavior on an element, mount by class name, done). I agree that many use cases (e.g. blogs) should mostly be server-rendered and only progressively enhanced with JS for some UX improvements.
But highly interactive apps (drag & drop just being one example) will not have comparable UX without client-side rendering. I do not want a 100-1000ms delay (or an error message) after dropping an item in some list because of a server-roundtrip. This is not good UX.
Also, when filling out a form, I do not want to lose data or context when clicking submit while I'm in a tunnel. I'd rather have a client-side rendered UI that keeps my context and tells me "Sorry, try again when you're connected again".
Even better if it works fully offline and syncs the transactions I've done with a backend once I'm connected again.