I decided to make my own mini jQuery years ago because I wanted a lightweight library. Also, I wanted to stay close to the native DOM API & vanilla JavaScript. Looking back, it paid really well. Then React & Vue JS happened.
In my opinion, the reactive UI approach bought a huge productivity improvement from the perspective of the developer. Also, it enabled a lot of beginner developers to navigate the programming landscape more easily.
However, this shift also moved people away from the core stuff that’s happening under the hood. As a result, sometimes we have to struggle a lot to find solutions within the library’s limits, which are sometimes hilariously dead simple & performant to implement with native APIs.
CalDOM tries to solve this by being 100% interoperable with the native DOM. I hope this will be helpful for developers with similar requirements.
The best approach for myself has been implementing the thing I use to some degree as a learning exercise. Not as in "production ready and feature complete" but rather as an exploration of the major mechanisms and basically playing around. It's fun!
There is clearly a need for a lightweight (on the order of 3kb seems good) "framework" that embraces everything the modern browser lets you do as natively as possible, basically the new jQuery, or maybe more accurately the new Backbone.js.
In that scenario I can understand how the build step could introduce complexity, but I'm a bit surprised to see Svelte lumped in with the others simply because it introduces a compiler. If size is a concern, it's hard to beat Svelte emitting framework-less vanilla JavaScript (whether as a complete single-page app, or as piece-meal components you sprinkle throughout a more minimal site).
* write stateful UIs (native, jQuery)
* have a Virtual DOM (React, Vue)
* use a template language that is JIT or AOT compiled (Angular, Svelte)
Those are your choices.
Good luck with your lib.
Instead of pulling you into a library-specific magical world, CalDOM let you fully access the DOM directly while keeping the reactivity. A 2-in-1 virtual-DOM & no-virtual-DOM approach if you will.
So you could take full advantage of native APIs & mix it with other libraries to gain superior performance & flexibility in the development process.
CalDOM does not require any dependency or tooling. It does not introduce any new syntax. Just pure JS.
This is the first time I’m publishing something like this. This was a simple jQuery alternative I made myself years ago & kept on improving it slowly. Worked really hard during the last few months to add reactivity and get it to this level.
Please check it out & let me know what you think, the good, bad & your suggestions to improve it.
Also, it's great if you could contribute to the project: https://github.com/dumijay/CalDom
Nice work from what I see so far.
Actually, I was very nervous about "meh, whatever another JS lib" response.
I'm relatively new to HN. This community is awesome!
I picked it mainly for 3 reasons. In my opinion,
1. _ kind of hide itself & give more prominence to the rest of the code (logic) 2. If we pick a long name like CalDOM, it becomes a PITA when it repeats so many times. 3. Not to be conflicted with jQuery by using $
To avoid conflicts, CalDOM provides an official workaround to define the alias before loading: https://caldom.org/docs/#_cal_dom_alias
If you don't like the underscore, there's an official way to alias it: https://caldom.org/docs/#_cal_dom_alias
I actually forgot to mention this in the documentation, your feedback prompted me to do so.
Rest is just the nature of JavaScript my friend. I hear you on Python.
For the latter Python encourages slug_case_naming_schemes and _ is a valid identifier in Python too. So there's nothing going on here beyond normal Javascript syntax which can be closure heavy -- a main feature of Javascript.
Are Caldom instances itself always synced with the DOM? e.g. If I create a Caldom instance for all ‘button’ and add an event handler for ‘click’. Now another piece of JavaScript adds a button to the page, will the event handler also trigger for that button or just the buttons when I first instantiated Caldom?
No, it's not synced. When you use CalDOM without its reactive features, it's just a wrapper around the native DOM Element (similar to jQuery).
_("button").elem === document.querySelectorAll("button")[0]
Regarding capturing events of future elements: You can achieve this by setting an event listener to the parent.
Eg:
_("body").on("click", e => { if( e.target.matches("button") ) //Do something });
Source: https://twitter.com/_developit/status/1412451442946981890
I highly recommend React/Vue folks to check it out, it's literally 2x'd my productivity and completely obliterated the mental RAM i had to keep in order to "think in react"
I'm assuming state is a proxy and you're using the single threaded nature of JS to make render functions dependent on accessed variables?
Also, there's .react(new_state), which is synchronous.
If one prefer not to use Proxies (old browsers, etc), it can be disabled via .react( state, { ..., watched: false } ) and then can call just .react() manually after state changes. Which is also batched(async).
These new “super lightweight frameworks” are only 3kb and as fast as vanilla js because they really don’t do much...
They always end up getting in the way though one way or another.
Writing a state and updating the DOM when the state changes really isn’t complicated at all.
People who don’t know how to do it need vanilla js template projects, not frameworks...
Your reply encouraged me to experiment a little bit.
Turns out, CalDOM already seamlessly merge with native Web Components. I just didn't see it previously. :(
It can be used to create reactive, stateful & native Web Components. Check out this example: https://caldom.org/#web-components
If you happen to play with it, please let me know your suggestions to improve it.
Thanks!
In my opinion, this is the future. Especially, Native Web Components will take over in this decade. CalDOM's long-term plan is to seamlessly merge with native web components when it's widely supported.
Basically, CalDOM's reactivity system does not care how the Element is created as long as it's a Native DOM Element/Node.
It could be _("+div") or document.createElement("DIV") or even jQuery("<div></div>")
See example: https://caldom.org/#reactive-native-node
Also, a CalDOM instance is just a wrapper around Native DOM Element(s).
_("div").elem === document.querySelectorAll("div")[0]
This interoperability allows for powerful integrations & to update the DOM directly by avoiding expensive virtual-DOM diffing.
In React's world, everything is micro-managed(there're pros & cons), accessing DOM directly can be chaotic & usually not recommended.
In Sciter DOM and vDOM are equally honored.
This CalDOM's (DOM + vDOM population):
_("#output-1")
.append(
_("+h1").text("Hello World!")
);
In Sciter is document.$("#output-1")
.append(<h1>Hello World!</h1>)
And this reactive CalDOM: let app = _().react(
{},
{
render: state =>
_( "+h1", `Hello ${state.name}` ) //This is XSS safe
}
)
_("#output-2", app );
//Edit below line to update state
app.state.name = "World Reactively ";
in Sciter is class App extends Element {
name = "unknown";
render() {
return <body><h1>Hello { this.name }</h1></body>;
}
}
document.body.patch(<App />);
document.body.componentUpdate({name:"World Reactively "}); // will invoke render()This blunt dismissal is very rude when you don’t even mention that you are the author of sciter.
Consider these features as an idea for browser vendors / W3C to extend DOM that we all use.
With these features (JSX & element.patch(vdom)) we don't need whole class of JS frameworks like React, PReact, Mithril. Vanilla JS (ES2020 spec) can be used instead. See: https://github.com/c-smile/sciter-js-sdk/tree/main/docs/md/r...