moostee

Proposed variant optimised for human readaiblity...

```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`.

show comments
codedokode

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.

show comments
bedroom_jabroni

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?

show comments
afavour

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.

show comments
abosalehworld

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

Are reactive updates based on deep equality or reference equality?

show comments
DylanMerigaud

Clean launch, good luck!

show comments
ahmedhossamdev

Great work!

show comments
bosmarcel

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!

hamburglar

> 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

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
    }
  })
handles reactivity.. https://github.com/digplan/vanilla-light
show comments