I don't know who originally said it but "If you're not using a framework, you're building a framework". This repo even has the following caveat:
(2) These usually end up becoming a custom micro-framework, thereby questioning why you didn't use one of the established and tested libraries/frameworks in the first place.
That said, I don't hate it. For quite some time, I've taken the stance that a web development team needs an opinionated framework, but it's fine for it to be a bespoke creation rather than off-the-shelf. The biggest value of choosing React, Vue, Svelte, etc is, in my opinion, less about it doing the heavy lifting for you with the DOM and more about adopting an established valid opinion to guide the team's development.
> These usually end up becoming a custom micro-framework, thereby questioning why you didn't use one of the established and tested libraries/frameworks in the first place.
Often a custom micro-framework better suits the needs of a particular project.
I've written micro-frameworks for specific projects intentionally, because they did a few things that the established frameworks either didn't do, or it was very difficult to get them to do.
An additional benefit was that using the micro frameworks ended up being simpler, and the startup time was much, much faster.
Whether or not you use an existing framework depends on how much effort it is to write and test a custom framework vs the amount of effort you'd need to put in to use an existing framework.
The ones I've written have been pretty quick to develop, and were also intended to be used for a few different projects that had similar needs.
Edit: Just for clarification, the micro frameworks I've written are server-side, if that makes any difference.
Framework churn is real. I no longer recommend JS frameworks simply b/c the opinion of the framework developer drastically changes over time. So, you are constantly re-writing completely valid and working code to keep up with the latest version of the framework. The JS language itself, on the other hand, seems to be very stable with long deprecation cycles and steady improvements. So, it is much easier to build on.
I think the problem with bespoke frameworks is that many career driven developers won't want to become a specialist in proprietary tools that won't transfer. However...
I have this strong suspicion that most projects that use something like React don't really need it. Like, if you're creating something that actually acts like an application and data might be shown in many places it makes a lot of sense, but for something that's just displaying data from a db on a page hit it can be massive overkill.
Thanks for reading - original author here. For the precise quote you mentioned I came up with somewhat format rules which prevented building a framework (code-wise) for this case study. The "caveat" you mention is just an explanation for the chosen ruleset; I believe I haven't introduced any general-purpose DOM/UI code in the case study and instead only describe patterns (correct me if I'm wrong!). I agree with your view of framework value as I professionally use React on a daily basis and will continue to do so, for similar reasons :)
Using frameworks is far more about hiring and human resources than technology I feel.
However, if your "micro framework" follows language idioms and is thin enough you get the best of both worlds, whilst releasing yourself from some of the downsides that come with using a general purpose framework.
With es6 template strings you can do a lot of heavy lifting with some very simple code. This example still uses es5 to mr that’s insane who on the web is still using ie6?
Can I claim I don't violate the "No general-purpose utility functions related to the DOM/UI" if I use only one such function? O:) https://github.com/stefanhaustein/notemplate (the demo is just TodoMVC, though)
> adopting an established valid opinion to guide the team's development
Different requirements allow for different settings. Coming from an Enterprise Application background, I found this being more often the case or the only case.
Working with different teams, developer fluctuation, different time zones, different skill sets, a framework guides the development process far better.
Vanilla JS is something that should be avoided in team setups. There is too much mental overload that is usually not justified by the benefits. It is like deliberately choosing assembler language when Java or C# would do the job better.
Frameworks got a bad rep. For me, they are tools that should be used.
I have experimented with something like this for a new side project. The plan was to have a TypeScript class for each component, and a render function to render them on dom. Then the listeners would be handled directly via addEventListener. Eventually I started having thoughts like - "maybe I could have the render function parse attributes and auto-attach dom events".
It became obvious it would become a side project of its own and not a smart use of my time. I settled down for Svelte and I love it.
It's amazing that a repository like this is even a thing. A demonstration that you don't need 3 million dependencies and a giant framework to build a simple application in the environment where a language was created to support.
I would question the choice to use ES5, as it makes it significantly more complicated to handle dependencies between modules in a scalable way. I understand the point of avoiding a build step, but if the code can run in modern clients without it I don’t think it breaks the spirit of the project to use a bundler to support certain older browsers. It’s a lot like using polyfills when needed.
Agreed, I originally thought this might be an older project from a couple of years ago because of the ES5. “Vanilla” doesn’t have to mean “supports IE11” in 2020 (before anyone jumps on me, yes, depending on your users you may very well still need to support it, but it’s very clearly on the way out - finally)
I love the motivation behind the repo though. The author’s write-up is fantastic and refreshingly reasonable in the dogmatic webdev world. It gives great insight into the places where real value _is_ provided by frameworks and build tools
Original author here - thanks! Yes, ES5 is a huge pain. However, I believe 5% of users (see other comment) are not a joke for many apps. There's always the question of minimum critical APIs required: If you build a 3D or webcam app you can forget ES5 altogether, of course.
> It’s a lot like using polyfills when needed.
Never thought of it this way, thanks for that! As is state in the conclusion, the study would likely be more convincing with ES6 and build steps. So yeah, ES5 is questionable :)
> Naively re-rendering a whole component using .innerHTML should be avoided as this may hurt performance and will likely break important functionality such as input state, focus, text selection etc. which browsers have already been optimizing for decades.
I think this statement deserves some serious scrutiny. In many cases the performance hit may not be relevant or noticeable. I know this because I've been very productively using the following approach to build dynamic webapps for my personal use:
1. Compose HTML strings using Javascript, especially with string interpolation
2. Slap the resulting strings into div/span elements with innerHTML= statements.
This approach results in extremely clean and simple code - much cleaner than the OP's code in my view. I have never noticed any kind of performance issues, the updates are always instantaneous. I don't know what the author means by breaking functionality like text selection and focus, but it's never been relevant for me.
Sorry :D nothing wrong with server-rendered HTML and forms for many use cases. Unfortunately, by the limits of connectivity, if you want to build something that is interactive, data-driven, and responsive at the same time you will always be forced to render on the client-side at some point.
I read it all despite my short attention span. Beautifully written study.
I hope to leave productive feedback later.
I do hope people don't miss the point that I think OP was trying to be modest about. This study is not for or against frameworks, it is a detailed and informative reflection of the current state of client JavaScript.
as someone who has made money as front-end developer, & saw the error in my ways. I will say the industry is not interested in simpler things. they're not interested in making the web faster for everyone. your typical insert framework here web app is slow on a laptop and even worse on mobile. now throw in hiring, it means everyone thinks their app should be on react or whatever, when it doesn't warrant it to be. look at Basecamp for apps that work without a major framework.
things like htmx exist but community is small.
so yeah, props to the author for making a proposition for something that would work.
but nah, frontend work this days is about making everything complex from getting the project running to the build steps and even deploying the project.
though one area, I will say frontend is now better on is testing: cypress, jest and react-testing library are nice things to work with.
I know in this community the overloaded value for vanilla in this context means just javascript without other people's javascript. But "vanilla web" should really mean HTML and CSS.
Sure, so which subset of HTML are we talking about?
Because unless I'm misremembering things, HTML 2.0 (literally the first version intended to be a standard going forwards) came out exactly the same year that JS dropped in a commercial browser (1995), and superseded the previous HTML and HTML+ markups.
So surely you don't mean HTML with things like file uploads, or GIF support. Because that's not "vanilla" in your world.
I know I'm nitpicking here, but I always find this phrase confusing, and I think this way of explaining unidirectional data-flow is problematic for those new to the concept.
If you want to persist something from a child component, the message that represents the action contains the data needed to make that state change, which sort of exposes the flaws in the up/down analogy.
Unidirectional data flow doesn't have an "up" and a "down". It doesn't even follow a single path. It's more like a ladder with several water slides connected to it. The pool is where the state lives. The slides are the child components. The people are the data. Climbers are performing state propagation. People who are sliding are creating actions. People who are landing back in the pool are updating the state.
Edit: no, it's not lost on me that the example I ended up using involves up and down motion--it's just not a very easy concept to convey using real-life analogies (which I think also contributes to the learning curve).
Thanks to everyone who took the time to read it, and thank you all so much for all the feedback! I'm quite overwhelmed by the response :) looking to address as much of the feedback as possible by the end of the week.
A major weakness seems to be my choice of ES5. I wanted an almost absolute minimum, which ES5 seemed to be at the time. I was lead by the fact that most bundlers produce ES5 by default, which may very well have been a mistake.
Interestingly, if ES5 is really dead (which it might be, I'm not sure) and ES6 is the minimum target, the study's results would actually improve drastically (less verbosity, actual modules, etc.) and further support the claim that vanilla can be maintainable (even without build steps). For anyone interested, let's continue the discussion here: https://github.com/morris/vanilla-todo/issues/6
I appreciate this project a lot! As someone exploring webdev as a hobby, everything is new to me and there are a variety of frameworks. I'm hesitant to start from somewhere that isn't "vanilla". As someone only a little familiar with JavaScript, the script seems surprisingly comprehensible.
I love it! It's definitely an exercise worth taking. Nice transfer size, and I'm happy to see that the code is quite maintainable.
I do my wordsandbuttons.online in similar spirit: no dependencies, and all the pages are kept below 64KB. However, as the code base grows, I'm starting to employ scripts to do the grunt work for me. So while I don't have dependencies per se, code patterns become dependency it its own right.
I've tried but I (surprisingly) found the string array to be the most readable way to do it without helpers. It's also easily replaced by ES6 templates when upgrading.
Not separating the state from the DOM (more than necessary, that is - at the client/server boundary) makes a bunch of things much easier. You can just manipulate the DOM and the state stays with the DOM, so there's nothing to sync internally within the JS app. You only serialize from DOM and to DOM at the server API boundary. No need for the "rendering" in response to state changes. You just change the DOM intuitively, and that's that.
And that makes "vanilla" browser apps easier to write too.
We use task management apps to save us time and give more visibility over the work. However, the app can become so complicated to use by itself, that we may choose to go for very basic note-taking apps to avoid the complexity.
I was looking for a minimal, simple and user-friendly app for daily task management, so I developed Renoj.
Fast to-do task management in Desktop for ultimate productivity.
No, I'd consider them a standard and a candidate for implementing the case study. When I started the study I was thrown off by this: https://caniuse.com/?search=components - and very huge polyfills. In hindsight I'm not sure if I dismissed WC too quickly.
This is probably thin ice, especially since I've never built anything with WC, but they always seemed slightly over-engineered. I will try to learn about WC a bit more and maybe elaborate on my reasoning here.
On a side note, the TeuxDeux app they cloned is wonderful. It immediately clicked for me. As someone who's been managing five big projects simultaneously, this is going to significantly help with cognitive load. I love the lists below the calendar.
[+] [-] sfrinlan|5 years ago|reply
That said, I don't hate it. For quite some time, I've taken the stance that a web development team needs an opinionated framework, but it's fine for it to be a bespoke creation rather than off-the-shelf. The biggest value of choosing React, Vue, Svelte, etc is, in my opinion, less about it doing the heavy lifting for you with the DOM and more about adopting an established valid opinion to guide the team's development.
[+] [-] wtetzner|5 years ago|reply
Often a custom micro-framework better suits the needs of a particular project.
I've written micro-frameworks for specific projects intentionally, because they did a few things that the established frameworks either didn't do, or it was very difficult to get them to do.
An additional benefit was that using the micro frameworks ended up being simpler, and the startup time was much, much faster.
Whether or not you use an existing framework depends on how much effort it is to write and test a custom framework vs the amount of effort you'd need to put in to use an existing framework.
The ones I've written have been pretty quick to develop, and were also intended to be used for a few different projects that had similar needs.
Edit: Just for clarification, the micro frameworks I've written are server-side, if that makes any difference.
[+] [-] madoublet|5 years ago|reply
[+] [-] overgard|5 years ago|reply
I have this strong suspicion that most projects that use something like React don't really need it. Like, if you're creating something that actually acts like an application and data might be shown in many places it makes a lot of sense, but for something that's just displaying data from a db on a page hit it can be massive overkill.
[+] [-] morrvs|5 years ago|reply
[+] [-] ehnto|5 years ago|reply
However, if your "micro framework" follows language idioms and is thin enough you get the best of both worlds, whilst releasing yourself from some of the downsides that come with using a general purpose framework.
[+] [-] shams93|5 years ago|reply
[+] [-] dukoid|5 years ago|reply
[+] [-] _the_inflator|5 years ago|reply
Different requirements allow for different settings. Coming from an Enterprise Application background, I found this being more often the case or the only case. Working with different teams, developer fluctuation, different time zones, different skill sets, a framework guides the development process far better. Vanilla JS is something that should be avoided in team setups. There is too much mental overload that is usually not justified by the benefits. It is like deliberately choosing assembler language when Java or C# would do the job better. Frameworks got a bad rep. For me, they are tools that should be used.
[+] [-] mcjkrw|5 years ago|reply
It became obvious it would become a side project of its own and not a smart use of my time. I settled down for Svelte and I love it.
[+] [-] noir_lord|5 years ago|reply
With React and particulary svelte (for now) it's a mishmash of possible choices.
Where that bites is when you have 3 choices to make with 4 options.
4^3 === 64 - so any project you pick up/come onto has a 1/64 chance of using a stack you've seen before.
[+] [-] austincheney|5 years ago|reply
[+] [-] tobr|5 years ago|reply
I would question the choice to use ES5, as it makes it significantly more complicated to handle dependencies between modules in a scalable way. I understand the point of avoiding a build step, but if the code can run in modern clients without it I don’t think it breaks the spirit of the project to use a bundler to support certain older browsers. It’s a lot like using polyfills when needed.
[+] [-] rablackburn|5 years ago|reply
I love the motivation behind the repo though. The author’s write-up is fantastic and refreshingly reasonable in the dogmatic webdev world. It gives great insight into the places where real value _is_ provided by frameworks and build tools
[+] [-] morrvs|5 years ago|reply
> It’s a lot like using polyfills when needed.
Never thought of it this way, thanks for that! As is state in the conclusion, the study would likely be more convincing with ES6 and build steps. So yeah, ES5 is questionable :)
[+] [-] brodo|5 years ago|reply
[+] [-] d_burfoot|5 years ago|reply
I think this statement deserves some serious scrutiny. In many cases the performance hit may not be relevant or noticeable. I know this because I've been very productively using the following approach to build dynamic webapps for my personal use:
1. Compose HTML strings using Javascript, especially with string interpolation
2. Slap the resulting strings into div/span elements with innerHTML= statements.
This approach results in extremely clean and simple code - much cleaner than the OP's code in my view. I have never noticed any kind of performance issues, the updates are always instantaneous. I don't know what the author means by breaking functionality like text selection and focus, but it's never been relevant for me.
For an example of the coding style, see the reDispActiveTable in this code, which draws a table of TODO list items with some operations like edit/delete/mark complete. https://github.com/comperical/WebWidgets/blob/main/gallery/m...
[+] [-] mark_and_sweep|5 years ago|reply
[+] [-] morrvs|5 years ago|reply
[+] [-] throw_m239339|5 years ago|reply
[+] [-] thomasfromcdnjs|5 years ago|reply
I hope to leave productive feedback later.
I do hope people don't miss the point that I think OP was trying to be modest about. This study is not for or against frameworks, it is a detailed and informative reflection of the current state of client JavaScript.
[+] [-] morrvs|5 years ago|reply
[+] [-] dzonga|5 years ago|reply
so yeah, props to the author for making a proposition for something that would work.
but nah, frontend work this days is about making everything complex from getting the project running to the build steps and even deploying the project.
though one area, I will say frontend is now better on is testing: cypress, jest and react-testing library are nice things to work with.
[+] [-] superkuh|5 years ago|reply
[+] [-] horsawlarway|5 years ago|reply
Because unless I'm misremembering things, HTML 2.0 (literally the first version intended to be a standard going forwards) came out exactly the same year that JS dropped in a commercial browser (1995), and superseded the previous HTML and HTML+ markups.
So surely you don't mean HTML with things like file uploads, or GIF support. Because that's not "vanilla" in your world.
/s
[+] [-] dbtc|5 years ago|reply
no framework js = topic of this link
vanilla = a bean, or a flavor
[+] [-] twodave|5 years ago|reply
I know I'm nitpicking here, but I always find this phrase confusing, and I think this way of explaining unidirectional data-flow is problematic for those new to the concept.
If you want to persist something from a child component, the message that represents the action contains the data needed to make that state change, which sort of exposes the flaws in the up/down analogy.
Unidirectional data flow doesn't have an "up" and a "down". It doesn't even follow a single path. It's more like a ladder with several water slides connected to it. The pool is where the state lives. The slides are the child components. The people are the data. Climbers are performing state propagation. People who are sliding are creating actions. People who are landing back in the pool are updating the state.
Edit: no, it's not lost on me that the example I ended up using involves up and down motion--it's just not a very easy concept to convey using real-life analogies (which I think also contributes to the learning curve).
[+] [-] morrvs|5 years ago|reply
A major weakness seems to be my choice of ES5. I wanted an almost absolute minimum, which ES5 seemed to be at the time. I was lead by the fact that most bundlers produce ES5 by default, which may very well have been a mistake.
Interestingly, if ES5 is really dead (which it might be, I'm not sure) and ES6 is the minimum target, the study's results would actually improve drastically (less verbosity, actual modules, etc.) and further support the claim that vanilla can be maintainable (even without build steps). For anyone interested, let's continue the discussion here: https://github.com/morris/vanilla-todo/issues/6
[+] [-] lynndotpy|5 years ago|reply
[+] [-] okaleniuk|5 years ago|reply
I do my wordsandbuttons.online in similar spirit: no dependencies, and all the pages are kept below 64KB. However, as the code base grows, I'm starting to employ scripts to do the grunt work for me. So while I don't have dependencies per se, code patterns become dependency it its own right.
[+] [-] armandososa|5 years ago|reply
[+] [-] morrvs|5 years ago|reply
[+] [-] masswerk|5 years ago|reply
[+] [-] dsego|5 years ago|reply
The neat thing is that it starts from scratch and adds things, like pub/sub, then models, controllers and so on.
[+] [-] megous|5 years ago|reply
And that makes "vanilla" browser apps easier to write too.
[+] [-] ribaldev|5 years ago|reply
I was looking for a minimal, simple and user-friendly app for daily task management, so I developed Renoj.
Fast to-do task management in Desktop for ultimate productivity.
Website: https://ribal.dev/renoj
[+] [-] simlan|5 years ago|reply
[+] [-] spark85|5 years ago|reply
If not have you considered trying to update the repo to use them
[+] [-] morrvs|5 years ago|reply
This is probably thin ice, especially since I've never built anything with WC, but they always seemed slightly over-engineered. I will try to learn about WC a bit more and maybe elaborate on my reasoning here.
[+] [-] boplicity|5 years ago|reply
[+] [-] morrvs|5 years ago|reply
[+] [-] z3t4|5 years ago|reply
First write the app in spaghetti code, then turn it into pure functions.