I really don't want to be that guy, but... Vanilla JavaScript already exists as a popular term for JavaScript without any framework. No jQuery, no React - just JavaScript. Calling a library VanJS (as short for "Vanilla JavaScript") is just going to cause confusion.
The repo's own description uses the phrase vanilla JavaScript in this way, and even mixes both meanings within a single sentence.
If the author likes the theme, I'm sure they can still use it indirectly. eg. "icecream.js: add a scoop of vanilla to your project". Or "Go nuts and sprinkle in some Reactive syntax". It's still very punnable, I assure you.
I clicked the download link to see what would happen, and it did indeed download a zero byte vanilla.js file. Zipping it using the OS X 'compress file' menu option gave me a 713 byte zip file however.
> Most people have never consumed real vanilla in their lifetime
What exactly is the "vanilla extract, vanilla beans" in Ben & Jerry's ice cream then?
Supposedly Haagen-Dazs ice cream is made from "5 simple ingredients": cream, milk, eggs, sugar, and Madagascar (sic) vanilla (which is "real" vanilla I assume?)
And what about the vanilla extract which I have on my shelf, whose ingredients are "vanilla bean extractions in 35% alcohol?"
Have we all fallen victim to a diabolical vanilla conspiracy?
Even though the main character of the universe, you, has consumed real vanilla, the point stands. Almost everything labeled "vanilla" does not actually contain real vanilla.
It's not similar. Unfortunately, "original" is one of the words with a couple of very close but different meaning. This one even goes first in the dictionary:
> Existing at the beginning of a particular period, process or activity.
The original meaning of the root "origin" comes from Latin: to rise -> beginning, source birth.
The relationship between Bourbon (spirit), primarily distilled and aged in Kentucky, and Bourbon (vanilla plant), primarily grown in Madagascar is one of fascinating cross-convergence of "things rich French speakers loved", plus the coincident accident of Bourbon, Kentucky being a shipping port (and Oak as an aging vessel high in imparting vanillins). Both are a reminder that vanilla as a flavor was long a spice for (and named after) kings and to be enjoyed mostly by the rich. It is still hilarious to see things like "vanilla JS" meant to imply "boring" or "cheap" when historically that's very inaccurate.
Also, yes, bourbon (spirit) is a good accompaniment to late nights in JavaScript.
Vanilla historically being fancy but then becoming an attainable and cheap additive is probably somewhat responsible for it becoming the default ice cream flavor, and thus flipping the idiomatic meaning.
Though note it was primarily the invention of artificial vanilla substitutes that made vanilla seem cheap/attainable. (Real Bourbon vanilla from Madagascar, for instance, is still far more expensive than most people realize.) There may even be a larger useful metaphor there, too, that "plain" vanilla is most often "fake vanilla".
Lots of dessert / ice cream recipes use vanilla as an ingredient regardless of what the final flavor is meant to be. This also leads to the vanilla === plain misconception, imo.
I've been managing that since more than a decade. Having neither jQuery nor bourbon was a challenge at first but browser APIs evolved and I fell in love with green tea.
It’s 93 lines, less than most CSS resets. Small enough to copy paste to the top of your index.html in a script tag. You can use it without NPM, webpack, a special compiler pass, or a template language. Seems pretty vanilla compared to the full fat, popular alternatives.
No it doesn't, same as "automobile" doesn't seem pretty Saturn-5, despite the fact that both are moving under their own power.
Terms have meaning, including meaning derived from communities by and large accepting that a certain term has a certain semantic meaning. And the accepted semantic meaning of "Vanilla Javascript" is "runs without a framework besides the browsers own API".
If my code works out of the box in an unmodified browser, then it is Vanilla JS. If I have to load a framework for it to work, then it isn't, period. And it matters exactly nothing whether the framework in question has 900,000 or 9 lines of code.
So loading an external library or framework isn't Vanilla JS, but if I copy/paste the VanJS source into a script tag, nothing gets loaded, there's no syntax magic, just some function calls, so that's Vanilla JS, right? If the latter isn't Vanilla JS by your definition, can I at least copy/paste something from stackoverflow?
Trying to make Vanilla JS a strict definition seems pointless to me in the first place.
I think we don't have to argue about the distinction between the library code and the application code. It doesn't matter how the library is loaded. You can get it from a CDN at runtime, load it from a scriptbundle, copypaste it into a <script> tag, it doesn't matter.
It's still library code that the rest of the application depends on. As soon as that is the case, it's no longer what the JS community by and large calls "Vanilla JS".
When you do it this way isn't even a framework is just a helper library (at his best). There is another concept for this kind of micro-libraries but calling "framework" to something that will not establish a frame of work for you.
> If my code works out of the box in an unmodified browser, then it is Vanilla JS. If I have to load a framework for it to work, then it isn't, period.
Minor nitpick, third party library and framework does not modify your browser. They all still run on unmodified browsers.
I understand the confusion, given the existing terms but it seems the intent behind the name 'VanJS' is to highlight the simplicity and 'bare-bones' nature of this new framework, aligning it with the 'vanilla' aspect.
While it might lead to some confusion initially, with clear and transparent communication about what 'VanJS' offers, it could still work as a brand that distinguishes itself by simplicity - or pivot to Van rentals
Might ?? Come now, be an adult and a thinking person ! Go down the hall find 10 js/frontend programmers. Ask them what do they think "Vanilla JS" might mean ?
SolidJS is probably the closest thing to a vanillaJS framework that you can get, in that 90% of the time it's doing the same DOM manipulations you would be doing, but with a nicer interface. So if an update causes a class to change, there's no tree to diff - that class attribute gets changed directly.
The non-Vanilla stuff is the signals implementation, which is kind of an RxJS-esque observable system, but more lightweight, and more push-based. It's very similar to Svelte, but with a React/hooks-like API (although far fewer rules to remember!) As I understand it, this system is pretty efficient, which means for simple use-cases, it's not adding much overhead over basic vanilla stuff.
The disadvantages (because there are always some) mainly come from the small ecosystem - there's not many off-the-shelf design toolkits, the documentation is a bit scratchy, etc. That community is still growing though, so that stuff will get there.
Or a software development platform a "no-code" solution.
Apparently all the cool marketing kids now want you to call your widget company "widgetless." Paraphrasing EJD's critique of Ada, "This stupid idea will take 5 years and a billion dollars to kill."
Yea kinda felt the same, when reading the name and desc. Whats the value of names or terms if we keep reassigning a different meaning to it ? Especially in the tech industry.
Also it's almost immoral calling "a new" project "lightweight" and "small".
Of course it is lightweight and small, it's a new project ! Wait for bug submissions, feature requests, feature parity, time, edge cases etc.
So now we have a framework that doesn't want to be a framework? They might call it "VoidJS" instead, as in void = vacuum = so lightweight it's almost as if there's nothing there?
It's very effective naming strategy. It's called VanJS not Vanilla JavaScript. But it's kinda hard to remember Van, or any letters really. By association of it's main quality which is small size/simplicity with common term such as vanilla JavaScript, suddenly VanJS becomes memorable.
Similarly vanilla js was named like that, after common term describing plain flavor of icecream. Which was weird to me, and I learned that as a non-native speaker only after I heard about vanilla js.
It's been explained well. If you want to point out a fact that paints someone in a bad light, but you are concerned about the fact rather than making people feel bad, you say "I don't want to judge, but [what I say here implies a judgement.]"
For example: "I don't want to judge, but I bought a gallon of milk three days ago and didn't get to use a drop of it." My concern isn't that you feel bad about drinking the milk or to paint you as a milk thief to others, my concern is that I bought milk and I didn't get to drink it. I'm being forced to offer a judgement in order to talk about my own experience.
>If you want to point out a fact that paints someone in a bad light, but you are concerned about the fact rather than making people feel bad
What you do is that you just don't say it... that's what you do if you're actually concerned about painting someone in a bad light / don't know if the fact applies at all.
No. Reality is that people will disagree with other people. And pretending that an opinion has no value because it might upset someone or apply to a generalization or group that isn't intended to mean "all of Group X" so much as "many/most of Group X, from my experience" as a disclosure doesn't mean that the rest of the statement, that could be impersonal or even offensive to some has no value.
If the only person being discussed is the author of the library, and you don’t know them…. what relevance is someone’s experience with other people who share a trait?
The idea of “pretending” here is interesting, I find the whole “ I don't want to judge him” to be its own form of dishonesty….
I am happy to see that the guy has rejected the idea of renaming the project. I am judging him: he is just as arrogant as any other Googlers. I'm sorry I didn't wanted to judge him, or that I even implied it. He deserved all the judgement. Long live the new definition of Vanilla JavaScript!
The "Hello World" example is a really good example of why React, Vue, etc are better than something more minimal like this library if you're optimizing for speed. The page will show nothing until the script runs, which requires downloading the VanJS lib and the script itself. You could inline them into the page, but that gets seriously messy at scale. A modern React app that's using some serverside rendering for the initial page load will send the user a page of HTML that can be streamed (rendered as it downloads) so it'll display pretty much instantly (if you're concerned about styles you could inline for the important stuff and defer for rest). The React "Hello World" will be a lot bigger but it'll display a lot faster on a slow connection, and it'll work if the user has JS disabled.
Obviously it's early days for VanJS and the authors could add all sorts of fancy SSR and clever scheduling, but if they do they'll lose the tiny size and end up making something that starts looking very like React (or more likely, Preact).
It's all a trade off. Sacrificing speed and complexity for size and DX is fine. You just need to be aware that's what you're doing, and neither is 'better' for all aspects of web app dev.
I'd argue that SSR is somewhat orthogonal to React or VanJS. I don't see preliminary reasons to suspect that VanJS will be unable to plug into meta frameworks and eventually get SSR.
There's a bit of work to do to make a JS framework work server side. You need a mechanism to render in Node, which assumes you don't use any browser APIs that aren't available in whatever DOM library you use. Then you need a way to stream the HTML to the client, but that's easy with Express. Then when the page has loaded on the client you need a way to know what the server rendered and attach listeners to the reactive bits (and optionally to rerender in the background on the client to check things are working properly). That's assuming you don't bother with things like lazy loading and dynamic imports, which will make devs a bit cross because those are really nice things to have.
It's not a huge amount of effort and it's definitely achievable by a single dev leaning on some existing libraries, but it would mean giving up on some of the lightweight aspects of Van, and, like I said, you'll end up half way to building your own React library...
Given that van replace the whole tree each time a value changed, SSR for van is simpler. You run chrome server side, capture the DOM once van has finished its first execution and modify the HTML of the page to includes the new nodes.
Sure that's doable if the site is static only. I was going off the SSR terminology which usually means the html is rendered at the time of request instead of built one ahead of time (SSG)
If you know what you are doing you can achieve full state restoration of a large SPA before CSS paints to the screen. In my personal app I am able to complete state restoration within the first 80ms of page load on old hardware. Vue and React are not capable of providing this.
Just encapsulating css and js inside the html works perfectly fine. In a SPA you nowadays use history api for navigation and make dynamic dom changes on the fly. You only have to make sure than you serve the minimum amount of js and css on an initial page load. Then when the page is loaded you load the rest. Slight inefficient cache model when lots of initial page loads from different urls, but usually that's never happening (people are entering a site at one specific url)
I have a SPA, full size is about 3mb of js files. Separate html files containing only that page are max 20kb. Super fast rendering. Nothing server side.
I often find splitting the difference is useful... embedding the CSS with the HTML, as different routes from the server, delivering the same html will still result in more cache being used, and lack of caching if a user shares/bookmarks something different from what a user may already have cached. async loading for routes and splitting on the bundler can help a lot as well. Similar to async load any graphing/charting libs only on components that need them too.
In the end, it depends on what you are doing... if you're wanting to do paged records against a database, then client rendering can help... The direction of React server components, next.js and the like bridge these gaps well. Combined with edge services like deno deploy, cloudflare pages/workers and others make this even more of a no brainer for many use cases.
There's also a place for pre-rendering most content... I don't know why any marketing or content sight like blogs wouldn't be static rendered at this point. JS enhancement for things like sharing or comments.
Two way different scenarios where this would be used, so different I wouldn't even compare them.
I'd use this to prototype a basic web interface to interact with something like an IoT device. React would be overkill, and I doubt React would be faster to render than this for that scenario.
On a slow connection, the fully rendered interface could well be more bytes than this plus some data. I would say first to render depends entirely on what you're doing.
React is used in _way_ more places than a blog or ecommerce site.
> The "Hello World" example is a really good example of why React <...>. The page will show nothing until the script runs.
Until the script runs! Nothing! Blank page of death! As numerous research articles have proven times and again, if visitors see a blank page of death for longer than 0.00068 picoseconds, 96% of them will leave the site, with that number reaching 97% if that time goes over 0.0124 picoseconds.
When users visit your site, your page will show nothing, unless you use React. React is awesome. React shows you the page before the script runs. Even if the script runs on the server, React will show you the page. Because React is full of optimizations. The rumors are, the cases were reported when React showed the page even before the browser completed the DNS query.
You have pretty much described the "php way" of developing things, is funny js-driking cool-aid guys talk about "SSR" being the thing to have, when we already had that, we already found that it can't scale without lots of money and started pushing computation to the client and now we are bring them back because it's not fast on the initial load...
damned we have come to full circle whats next, an assembly language so we can run binary code inside the browser kinda the way activex and applets just used do it... wait isn't that the whole point webassembly? sight you f** javascript developers have done it again sight
This is fairly reductive. SSR is less about rendering HTML on the server, and more about having both the initial render and the client-side updates use the same process. Contrast this with other ways of rendering the front-end where either the client needs to build the entire view itself, or you need to write a separate application to do any client-side manipulation that might be necessary.
As with everything in software, it's all about tradeoffs. Using PHP to render your templates works great if there's limited client-side interaction (say, blogs, forums, documents, marketing pages etc), while frontend rendering allows you to build much more complicated applications that can react much quicker to user interaction, but will be slower to load the more complicated they become. And SSR tools try and have the best of both worlds, but make other aspects more complex in exchange.
There's a "mini-van" renderer and examples on usage for node/deno on the library's website. I actually found that probably more compelling than the JS client library usage.
For me what's missing is wiring with a larger state machine (jotai or similar) and async importing of components at runtime.
In the end, I'm not completely convinced this is better than React/Preact/Inferno, and even then, adding a UI library like mui will get even bigger. It's the patterns and the size/scale of what you're building and how many other devs you would have to develop with that should determine things like this. Are your using on generations old phones where access is akin to slow 3g, or is everyone on a modern 1440p+ desktop with over 30mbps of bandwidth?
The cliëent lib could be 2kb and the speed difference between first render vs server side render is less than 10ms. In fact the client side render version could be faster if the compiled output is larger than 2kb. Which then normally must be pushed from the server
You are comparing apples to oranges. The author could probably couple their library with https://vite-plugin-ssr.com/ and have something comparable within a day.
The reality is most running React apps today are still traditional SPAs, and chances are likely the same apps can be rewritten with VanJS (or any other SPA framework) and the users would not notice a difference.
They would notice because vanjs trashes the entire DOM at the root of every state update so users will lose focus, animations will interrupt, and big perf hit layout reflows will occur.
That's bad for performance (recomputing the style/layout and repainting even for minor changes), bad for accessibility, breaks focus, etc.
It's unlikely the smaller bundle size compared to preact and friends wins anything once you've abandoned all reuse of the rendering engine computations.
The diffing algorithm for preact is super simple, I think it's along the lines of a dozen lines of code. I'd wager the code to directly updating the DOM will be larger than preact + usage code
Using tagged template literals with Lit or Preact + htm is more readable than Van.js, is much faster on update, and is also completely vanilla JS (no JSX and so no build step needed)
You are not really getting anything in the size difference between this and something like preact, you are going to end up bottlenecked on something else like waiting for CSS to load. This is fine if you just want to write the code in a minimalist style, but I really doubt cutting things back to this extreme has tangible performance benefits for like 99% of applications.
Hard to see a real-world use for this but reading the code and docs is pretty interesting. The code taught me some cool tricks. Good job!
Some of the binding API is a bit weird, like that object with `deps` (State-derived properties). Maybe providing a function for this would be more ergonomic.
Would seem that it's not difficult to come by a framework tiny and functional. The question is, how long are they valuable to maintain and how tiny they keep if you cater for all the corner cases and fix bugs
We probably saw since React came up at least 20-30 of these "smallest reactive UI frameworks" with similar API but none of them named itself "Vanilla" for a reason.
I share the opinions of others in this thread that the current name is an unlucky one.
This narrative (https://vanjs.org/about#story) about modern JS tooling being opaque, exclusive, and hard to learn is frustrating.
If all you need is HTML rendering and basic state, any modern web framework will do that extremely simply. The barrier to entry is really not that high!*
*Except maybe at Google. I hear their internal tooling is a huge pain to work with.
Web development is going to come full circle once everyone comes to terms with the fact that web development has been overcomplicated and you don't need 1000 packages and abstractions on top of abstractions just to interact with some DOM elements.
you don't need 1000 packages and abstractions on top of abstractions just to interact with some DOM elements
I don't think many developers believe that you do. Most of the complexity around 'modern web dev' isn't about achieving the basics of moving DOM nodes around. If that's what you're doing then it's hard to argue that a framework adds much benefit.
Frameworks bring two benefits:
Firstly, they push you down a specific path around the shape of the code. When you're on a team of 20 working on part of an app that shares data across n other components then you need something to keep the code from turning into a swamp. Frameworks bring that experience. You don't need it on a small app or if you're a lone dev, but even then it kind of helps if you're not especially disciplined. If you want an example, have a look at some of the demos from the react-three-fiber team. It's so much nicer to work with a declarative API than imperative vanilla Three.js code.
Secondly, frameworks used well enable you to eek out additional perf. Building an app that renders a complex page in under 16ms isn't that easy if there's a lot going on, and leaning on a scheduler like the one in React makes it simpler. It's still far too easy to get it wrong and kill all your perf even in a framework though.
> Building an app that renders a complex page in under 16ms isn't that easy if there's a lot going on
We struggle to render a few boxes and some text under 16ms while games with vastly more complex sound, network, physics, UI and whatever else systems render frames in < 8ms at 4k.
We struggle to render a few boxes and some text under 16ms
Only if a dev has screwed up. Most simple sites are fine. You have to push the DOM quite hard for the browser to be the bottleneck. I've worked on apps that have DOM trees with 60,000+ nodes that remain under 16ms (because very few were actually changing at any given time..)
games with vastly more complex sound, network, physics, UI and whatever else systems render frames in < 8ms at 4k
The Servo project is bringing a lot of what makes game UIs fast to browsers. It's a massive shame that it's not a Mozilla/Firefox backed idea any more but it's still going. Hopefully it'll get a bit more mainstream one day.
> Only if a dev has screwed up. Most simple sites are fine. You have to push the DOM quite hard for the browser to be the bottleneck. I've worked on apps that have DOM trees with 60,000+ nodes that remain under 16ms (because very few were actually changing at any given time..)
You mentioned that frameworks like React make it simpler to get better performance but based on my observations it's quite the opposite and React is often a double barreled gun where one of the barrels is constantly pointing at your feet. With vanilla JS (not the one from this post) you have to put effort to get everything to update properly. With React you put effort to get the least amount of things to update. It's not even about DOM size but about managing state and how much code gets run on state change.
To give you an example - Reddit is a simple website. You have a list of posts which are either text, image, or a video and each of them has comments. Absolutely nothing complicated about that, yet the performance on their React frontend, even with all analytics JS and ads blocked, is horrendous. You would assume that at Reddit's scale they'd be able to hire competent React developers.
The day they make native web components as useful as using Vue or React without needing a single third party library, that is when this might happen. Until then, I dont think its happening any time soon.
Since the other comments are complaining about something or other, I just want to say that this looks great! I can imagine using this for something that needs more than jQuery and less than react.
I use the same Html-in-JS syntax for my own project and it works really well. The good folks at solenya have written a converter: https://www.solenya.org/convert
HTML-builder APIs like this are a pretty bad idea, IMO.
They assume that HTML is a closed system with no new tags, and don't account for custom elements or new tags. It doesn't even have support for existing tags like <track>, <b>, or <i> (<i> is used by some systems now for icons). It doesn't appear to have a way to emit comments.
We have the ability to embed real HTML strings, with expressions, directly into JS, which means that the rendering library doesn't have to have any knowledge or opinion of what the tags are.
This is what Lit does with lit-html templates. The example in the Van readme would be:
You can just add a generic version tag function that takes a tag name as its first param to solve that issue. Lets you create your own generator functions with ease for tags that aren’t included by default. Don’t see any reason you can’t add a comment() function either.
If you use a template string like that then you lose a lot in terms of type checking/IDE tooling/etc unless you add a ton of complexity, which is antithetical to this library’s goals. I definitely think they went with the right option.
This is somewhat alarming. <i> is still a valid tag and used, e.g., for marking up titles of artistic works, etc. (which is not a use case for <em>, nor for <cite>.) Similar goes for <b>, which is (semantically) different from <strong>.
For most icon libraries that use <i> for their icons, it's usually just a suggestion and using <span> instead works fine. They mainly use <i> because it's "pretty".
I like this, but https://github.com/vanjs-org/van#ultra-lightweight should really list svelte, which is only 1.6-1.8kB compiled last I checked (though it's possible it makes some of the compiled markup that gets shipped larger than the source due to component style scoping)
nanojsx looks great!
I don't really get why mini-van don't use JSX.. Maybe some people just don't want any html tags in their project ? Or maybe their template engine allows a lighter approach.
Makes me think that jquery may have missed a boat to integrate reactive elements (as there was clearly a need for them for a long time before angular, react etc took of) and retain relevance.
Maybe for projects that don't aim to replicate desktop app functionality there is a "small-is-beautiful" yet all-inclusive js library that is missing.
To my eye, this makes vanilla JS more like React rather than making vanilla JS reactive. I'm basically looking for an even lighter Svelte if I can get it. Maybe this just isn't for me!
> if they don't need a framework, they really don't need it.
I don't think it's an "all or nothing" situation. I do UIs without big frameworks, but that doesn't mean I don't use any library for some needs. I personally appreciate anything that needs no transpiling.
This is what we were doing before React and Babel came along. No dependencies, no transpiling, light weight, no IDE setup, were all a given and not special features.
I like it! Its minimal, super straight forward and easy to understand, dont need a transpiler. I'll use it with my next upcoming project and see how it fares.
Until i run into a big bottleneck in react and cannot find a way to overcome it, i am not gonna switch from react to yet another new framework. Time is better allocated for more important things.
That's not the point. Imagine wanting to do a quick prototype, for example. A miniframework like this could be a great fit. Or when you code something (probably not too big) from scratch.
i'm also a bit confused why e.g. they have an explicit rule that they only use `let` instead of `const` when declaring variables, "for reducing the bundle size", which seems like a bad trade-off in order to save maybe a couple dozen bytes at most?
I’m a bit confused why they made it in the first place given the dozens of similar ultra minimal spartan frameworks to choose from that nobody uses (every other comment here is plugging one).
This library actually has some pretty unique ideas, like the use of Proxy objects which is not commonplace in javascript frameworks. Even if it didn't, sometimes it's just nice to build your own take on something.
Do you use JS or TS currently? We've had async/await since ES2017, it's supported everywhere you want, and there's no reason to see .then() chains anymore outside jokes regarding early 2000's film classic "Dude, Where's My Car?".
Pasting some code and cutting out the boring bits:
Even back when .then() chaining was used: chaining only existed because that was the only way we had to handle promises, rather than because it was a desirable syntax.
Why would you be so snarky in your answer? Always better to be humble and assume you might be wrong. In this case you are: Nobody chains promises anymore.
Tag functions being implemented with a Proxy (https://vanjs.org/tutorial#api-tags) could make that a little cumbersome, and would break the abstraction that `div(...)` just returns an HTMLDivElement you can do whatever you want with.
Yeah, plus I realized after posting that for nesting children it would mean having the properties at the end, not very dev-friendly, maybe the way this lib does it is the best way (without JSX or anything like that)
Maybe, but I bet this way would be slightly faster, because the library wouldn't have to loop through keys if they write functions for all the most common attributes (href, rel, className, type, etc)
The repo's own description uses the phrase vanilla JavaScript in this way, and even mixes both meanings within a single sentence.
If the author likes the theme, I'm sure they can still use it indirectly. eg. "icecream.js: add a scoop of vanilla to your project". Or "Go nuts and sprinkle in some Reactive syntax". It's still very punnable, I assure you.