Rendered at 15:11:47 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
codedokode 15 hours ago [-]
The syntax looks a bit too verbose for me. And function names like "read" and "write" are confusing too, given that "read" function isn't made for reading values. Cannot we use a single function for binding, like this (and name it "bind")?
let counter = proxy({ count: 0 });
bind('.counter', (el) => el.textContent = counter.count);
counter.count++; // Queues DOM update
Also,
> Mador is distributed as an ES module.
This means it cannot be used on a page opened from disk, and the user needs to set up a HTTP server which is time-consuming and distracting. And you cannot distribute an app as as HTML file.
inbx0 7 hours ago [-]
> And you cannot distribute an app as as HTML file.
<script type="module">
console.log('Hello World!')
export const a = 5
</script>
Inline module scripts work fine in HTML.
You can't import this, but if you'd anyway need to do some "building" (at least doing some string concatenation as a build script) to get any JS baked into the HTML, so why not just concat the library and your own code to one module script in the HTML.
Works fine.
I think it's good that folks are starting to end distributing prebuilt code in every possible format that somebody could ask for. Waste of disk space for most people.
ESM is how it's done now. If you don't like it, build it yourself to some other format.
There are many standalone plug-n-play implementations of the signal primitive in JS. To name a few: preact/signals, vue reactivity, etc, there's even a TC39 proposal for a lang feature. Is this meant to stand out by doing things differently or reinvent them?
nxobject 15 hours ago [-]
(Just for (my) reference, the TC39 proposal is here:
The TC39 proposal seems pretty much dead :(; it doesn't look like much is happening. If I understand it correctly, it's really just about agreeing on a protocol, and it's ultimately up to frameworks to implement it, there isn't anything (yet?) that can run directly in JavaScript.
bosmarcel 18 hours ago [-]
Honestly, mostly for the fun of building it and seeing how small and simple I could make it. While big solutions like Preact or Vue are great, sometimes you just want a tiny zero-dependency script without the overhead.
And it turned out to be quite nice as I may say so
bedroom_jabroni 17 hours ago [-]
preact/signals-core has 0 dependencies, your project could also benefit from mentioning what primitive is being implemented for the reader's information. The size difference is negligible. The readme creates a false dilemma where there's either Mador or "having to use a framework" but it hasn't been the case for ages - as I mentioned above the major frameworks have decoupled versions of their reactivity available. This makes the other reply where "the frontend community deserves tools like this" sound weird because it ignores the great tools that have been available for a while.
Good learning experience but a very weird presentation.
kevinfiol 9 hours ago [-]
It's not that weird of a presentation, just different ergonomics for the same problem.
preact/signals-core is great, but since HTML elements have no way to subscribe to signals, you have to handle that yourself:
Anyways, I love projects like these that try to make working with the web easier with minimal tools.
bedroom_jabroni 5 hours ago [-]
I wasn't referring to the ergonomics - the weirdness was from the way it was worded like "Here's one trick Big Framework doesn't want YOU to know" as if React, Vue and such were gatekeeping their reactivity while they're actively maintaining and sharing standalone versions of it.
bosmarcel 9 hours ago [-]
Great post/reply, thanks a lot
bosmarcel 17 hours ago [-]
That's a fair distinction, but I think they solve different problems. Signals are great, but they usually require managing primitives individually and don't map directly to deep, nested JS objects the same way. Mador is specifically about dropping in a plain, nested object and working with it like normal JS without .value "boilerplate".
Appreciate the feedback on the README phrasing though—I'll tweak it so it doesn't sound like a false dilemma!
bedroom_jabroni 5 hours ago [-]
The .value comparison is not fair because it's a single value vs an object property. A better comparison would be against something like Vue's reactive() where it doesn't require you to add this "boilerplate".
afavour 16 hours ago [-]
First time I’ve seen Preact described as a “big solution”!
moostee 18 hours ago [-]
Proposed variant optimised for human readaiblity...
O yes, thanks, appreciate it!
I'm tired now, but i will find the time tomorrow to make it more readable!
afavour 16 hours ago [-]
I’m curious to know what performance looks like. In the recesses of my memory is the belief that proxies are not good for performance but I have no idea if that’s well founded (or maybe once was but isn’t any more).
It’s a very smart idea though, I like it.
codedokode 16 hours ago [-]
It depends on count of variables and dependencies. The much worse problem with proxies is that they can be confused with raw values, for example, you can add a proxy into a Set, and then check for existence of a raw value. Or confuse raw value and proxy in dictionary's keys.
abosalehworld 16 hours ago [-]
I love the minimalist approach here. Using Proxies for state management without the heavy overhead of large frameworks is really elegant. Keeping it under 80 lines is impressive. Great work!
PoignardAzur 18 hours ago [-]
Are reactive updates based on deep equality or reference equality?
bosmarcel 18 hours ago [-]
It is based on ref. equality, so assignment through '=' will trigger an "effect".
DylanMerigaud 18 hours ago [-]
Clean launch, good luck!
bosmarcel 18 hours ago [-]
Thanx a lot!
ahmedhossamdev 18 hours ago [-]
Great work!
bosmarcel 18 hours ago [-]
Thanks, I really appreciate it!
Hope others will feel the same. The frontend community needs and deserves simple tools:)
antonvs 18 hours ago [-]
This makes me think of a version of that comic where in the last pane, you get thrown out the window for suggesting such a sensible thing.
bosmarcel 17 hours ago [-]
Hahaha! Exactly
bosmarcel 18 hours ago [-]
Hey HN! I wanted to see how far you can push modern JavaScript Proxies without all the heavy overhead of a traditional framework. The result is Mador: a tiny ~80-line reactive state tuple ([r, w]) that lets you make any DOM element reactive using a simple CSS selector, automated dependency tracking, and batched microtasks. No build steps required—just drop it in.
I built this over the weekend just to experiment with clean, zero-dependency reactivity. Would love to hear your thoughts or see where you'd run into limits with something like this!
boldaxolotl 3 hours ago [-]
[dead]
favori995749721 7 hours ago [-]
[flagged]
hamburglar 17 hours ago [-]
> Hey HN! I wanted to see how far you can push modern JavaScript Proxies without all the heavy overhead of a traditional framework. The result is Mador: a tiny ~80-line reactive state tuple ([r, w]) that lets you make any DOM element reactive using a simple CSS selector, automated dependency tracking, and batched microtasks. No build steps required—just drop it in. I built this over the weekend just to experiment with clean, zero-dependency reactivity. Would love to hear your thoughts or see where you'd run into limits with something like this!
Unsure why this comment from the author was flagged/dead but it certainly doesn’t seem to run afoul of HN guidelines.
dpweb 18 hours ago [-]
The core idiom I've used for years is deliberately tiny: fully encapsulated custom Web Components that simply re-render when matching an attribute and `window.state` changes. Data model is simply:
window.state = new Proxy({}, {
set(target, key, value) {
target[key] = value
document.querySelectorAll(`[data="${key}"]`)
.forEach(el => el.render?.())
return true
}
})
> Mador is distributed as an ES module.
This means it cannot be used on a page opened from disk, and the user needs to set up a HTTP server which is time-consuming and distracting. And you cannot distribute an app as as HTML file.
I think it's good that folks are starting to end distributing prebuilt code in every possible format that somebody could ask for. Waste of disk space for most people.
ESM is how it's done now. If you don't like it, build it yourself to some other format.
https://github.com/tc39/proposal-signals)
Good learning experience but a very weird presentation.
preact/signals-core is great, but since HTML elements have no way to subscribe to signals, you have to handle that yourself:
Anyways, I love projects like these that try to make working with the web easier with minimal tools.```js import mador from "mador"; const [read, write] = mador({ count: 1 }); read(".counter", ctx => ctx.el.textContent = ctx.count); write(".increment", "click", ctx => ctx.count++); write(ctx => ctx.count = 0); ```
## Read
Dependencies are detected automatically when the read function is run during initiation.
```js read(".counter", ctx => ctx.el.textContent = `Count: ${ctx.count}`); ```
## Write
Immediate:
```js write(ctx => ctx.count++); ```
Event-triggered:
```js write(".increment", "click", ctx => ctx.count++); ```
Event writes expose `ctx.el` and `ctx.event`.
It’s a very smart idea though, I like it.
Unsure why this comment from the author was flagged/dead but it certainly doesn’t seem to run afoul of HN guidelines.
Imho, custom elements are great, but very limited in a way that they almost always require knowledge of the domain.
Perhaps I can figure out a way to combine mador.js & custom elements.