Hacker News new | ask | show | jobs
by recursive 760 days ago
I've also struggled with React's insistence on immutability. What if mutability was the only way to update state? I implemented a JSX-powered react-alike that explored the concept[1]. To my lack of surprise, I found the resulting environment easier to get stuff done in. I'm not subjecting my employer to this, but I would totally use this on a solo project that I had to support.

[1] https://github.com/tomtheisen/mutraction

3 comments

One problem with this that I've found through similar endeavors is: the act of making the library results in you knowing how it works on a deep level. It's likely you don't know React on such a level. This inflates your perception of how easy to use it is. If you did know React that well, you'd probably be able to use it very effectively!

Anyway I did take a look at Mutraction and it looks great actually. I've just made a lot of abstractions at work, and always been a little surprised by how hard it is for people to get used to them. Of course maybe I'm just bad at it. But ultimately it's made me kind of anti-abstraction all around. If everyone was as good with vanilla HTML, CSS, and JS (actually I'll approve TS) as they are with React, the web would be a better place </opinion>

Before I built this, I spent a couple of weeks reading the react source code. Of course, it's huge, and I didn't touch most lines. Probably never saw most of them. But it was enough to understand dispatchers, work scheduling, and fibers.

But you're right though. I still understand my own library better. However, I've really made an honest try to understand react (at least the client&DOM parts) as much as I practically could.

I think I'm on-board with your anti-abstraction POV too.

To be fair, this (like many applications of reactivity) is conceptually very different from embracing mutability. And at least at a glance, it looks conceptually much closer to React than that.

Where React differs isn’t immutability, but where the mutation of state/effect boundary is (at the component/hooks-rules, versus something more fine grained).

In every possible approach, a state change needs some orchestration to produce rendering updates. The approach taken here looks like a subset of a common reactive approach, not dissimilar to say Solid with its createMutable Proxy-based store. That’s much more palatable to me (and I expect it would be to even a lot of React devs) than a less disciplined free-for-all mutability take (which effectively devolves to “build your own state<->render abstraction, or just maintain state in the view itself, probably both”).

Solid's proxy-based approach was indeed one of the major influences. It's also similar to reactive() in VueJS. There's one novel thing in mutraction that's not in either though, which is the undo/redo log. It might not be very useful in practice. I'm not under the impression that I really created anything fundamentally new here. I just scratched my own itch.

Really, I think the main difference is that there's nothing in mutraction like a virtual DOM. Conceptually, it's dead simple. There are only real DOM nodes. This eliminates most of the use case for DOM refs as used in react, As you can just assign a JSX expression straight to a variable.

I've seen the word "orchestration" used before with respect to UI framework architecture. I must confess, I don't understand what it means. By default, in mutraction, most mutations are immediately applied to the corresponding DOM elements. You can wrap blocks in transactions, but probably most of the time, you wouldn't. Is that orchestration?

> There's one novel thing in mutraction that's not in either though, which is the undo/redo log. It might not be very useful in practice.

On the contrary! That alone is cause for me to give it another look. Stuff like state history is sorely lacking in the industry in general, and can enable powerful things like time travel debugging. I’m super curious to look into how it works when I get a chance.

> Really, I think the main difference is that there's nothing in mutraction like a virtual DOM.

Clarification (as I presume you know this, but in case anyone else isn’t familiar): this is also how Solid works.

> I've seen the word "orchestration" used before with respect to UI framework architecture. I must confess, I don't understand what it means. By default, in mutraction, most mutations are immediately applied to the corresponding DOM elements.

That’s exactly what I meant in this context. Without something like reactive Proxy tracking and binding to the produced DOM nodes, you’ll have:

1. Some mutable state, like objects and arrays and reassignable variable bindings.

2. Some view DOM.

3. Some code that manually assigns 1 to 2.

4. Some code that manually handles events in 2 and applies mutations to 1.

5. Recurse.

This can be as “bare metal” as direct DOM interaction, but usually tends to look more like jQuery. As popular as that is in HN comments, it’s really hard to manage in applications beyond a certain level of complexity (interactivity, feature scope, etc).

This is awesome. Thanks for making it.