VanJS (Vanilla JavaScript): smallest reactive UI framework
github.com
github.com
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.
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.
Anywhoo congrats on shipping something.
Unless it's Swing, where a "lightweight" component is one that uses enormous piles of slow Java code to duplicate native platform functionality.
Vanilla Javascript refers indeed to "javascript without a framework". So creating a framework and calling it "vanilla javascript" is... wrong?
https://plato.stanford.edu/Archives/Fall2012/entries/liar-pa...
Does it seem vanilla compared to vanilla? Haha..
It's still not part of the common browser API, so yes it's easy to add, but no, it's not vanilla.
> it's not vanilla.
Hate to interrupt, but vanilla is a flavor. And it's a pretty good one, dammit!
"Vanilla JavaScript" implies "without anything added".
It's 3KB of barely documented code.
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.
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".
This is Vanilla JS:
fetch('/readme.txt')
.then(response => response.text())
.then(data => console.log(data))
.catch(error => console.log(error))
This isn't: awesomeLib().goesBrrrrr()
> Trying to make Vanilla JS a strict definition seems pointless to me in the first place.Being able to name things, and having clarity in a community about what names denote, is anything but pointless.
Minor nitpick, third party library and framework does not modify your browser. They all still run on unmodified browsers.
> The majority of the world's vanilla is the V. planifolia species, more commonly known as Bourbon vanilla.
Also, yes, bourbon (spirit) is a good accompaniment to late nights in JavaScript.
https://en.wikipedia.org/wiki/Plain_vanilla
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.
bourbon.js it is?
Also has the smallest footprint:
0 bytes uncompressed, 25 bytes gzipped!
Compression Considered Harmful
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 ?
Vanilla is a sophisticated flavor, not to mention a precious and expensive ingredient. Most people have never consumed real vanilla in their lifetime.
> 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.
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?
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.
And now I want to create a library/framework/whatever called NaN.js...
I do like the idea of it. A lot of value of React for me is in the composition model and could see this being useful for small projects
window.$ = (selector) =>
applyExtendedTools(Array.from(document.querySelectorAll(selector)));
Oh noes, I'm now using a defacto Framework, even if I wrote the applyExtendedTools and the $ function to give me something like a lighter jQuery.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."
I was confused reading the page and expected a description of a pattern I could use in actual vanilla JavaScript without any dependencies.
The term 'zero-dependency' played a role in my confusion. "VanJS" is a dependency.
We've somehow accepted that nomenclature.
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.
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.
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...
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.
Also, using rollup would be trivial.
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.
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.
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.
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
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.
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?
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.
https://github.com/vanjs-org/van/blob/3f98060971a8ff141179ef...
And a very simple system that replaces the dom from scratch each time any data changes:
https://github.com/vanjs-org/van/blob/3f98060971a8ff141179ef...
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.
I find this quite strange. Wouldn’t javascript be to the browser what Bash is for the terminal? This is after all just another library.
So VanJS will make the simple things easy and anything else nigh-on impossible?
It's working surprisingly well for a client that I'm working for.
Very on brand. (˃̣̣̥‿˂̣̣̥)
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
I share the opinions of others in this thread that the current name is an unlucky one.
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.
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.
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.
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.
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.
I keep seeing an advert for a Principle Frontend Dev at Reddit on LinkedIn. Maybe I should apply...
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
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:
const Hello = () => html`
<div>
<p>Hello</p>
<ul>
<li>World</li>
<li><a href="https://vanjs.org/">VanJS</a></li>
</ul>
</div>
`;
Such template strings can contain any HTML - any tag, comment, attribute, entities, SVG, etc.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.
And it still allows to provide specific types for the known HTML elements: https://github.com/vanjs-org/mini-van/blob/57b686ced075754ee...
Cool stuff
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>.
- https://redom.js.org 2kB
- https://nanojsx.io 1kB
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.
Also I’d like to see how they handle mount/unmount logic like event listeners.
There is an example in the tutorial about how state are handled [1]. [1] https://vanjs.org/tutorial#state-binding
import { createRoot, createSignal, createRenderEffect } from "solid-js";
function SomeComponent() {
const [count, setCount] = createSignal(0);
const result = document.createElement("button");
createRenderEffect(() => result.textContent = "++ (" + count() + ")");
result.onclick = () => setCount(count() + 1);
return result;
}
createRoot(cleanup => {
const appv = document.getElementById("app");
appv.appendChild(SomeComponent());
});nowadays, most small project can use vanilla javascript, if they don't need a framework, they really don't need it.
if we are building a large project, why not use react/vue/svelte ? better docs, better features, better community.
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.
const Hello = () => div(
p("Hello"),
ul(
li("World"),
li(a({href: "https://vanjs.org/"}, "VanJS")),
),
)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.
The approach to local state is also similar to Preact Signals, which is cool.
Very similar to: https://github.com/jehna/longwood
closes tab
And yes it’s nice to build something on your own, but this project is clearly aiming to convince other people to use it in their projects.
const a = 1;
let b = 2;
console.log(a, b);
bun build --minify a.js // bundles this to: var o=1,l=2;console.log(o,l);
It's not even using const or let, it's flattened these multiple statements into one 'var' statementIt’s because of your thinking that we got bloated webpages.
Not caring about memory usage, data usage, speed is the reason why software is so brittle and broken these days.
a({href: "https://vanjs.org/"}, "VanJS")
I would have gone with this shorter way a("VanJS").href("https://vanjs.org/")
And make it chainable and allow class names as second argument as in a("About us", ".big.red").href("/about.html").target("_blank")href() isn't a function name. One doesn't 'href()' anything.
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:
const transaction = await makeTransaction(...);
const signature = await sendAndConfirmTransaction(...);
const tokenAccountsByOwner = await getTokenAccountsByOwner(...);
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.