Live data from Hacker News

Show HN: Aberdeen – An elegant approach to reactive UIs

aberdeenjs.org

101–110 of 138 posts

Re: Show HN: Aberdeen – An elegant approach to reactive UIs

#101
post #98

Earlier quoted context omitted.

Correct! As far as I know, Vue has always had its own HTML-based template engine, with special HTML attributes for conditions, loops, etc. Different trade-off. Since Vue 3, it does indeed rely on `Proxy` for its reactivity, like Aberdeen. The idea is the write whole applications without HTML. We've done some pretty big projects in this style, and in terms of DX and velocity it's actually really good. Recycling (tiny)…

Aberdeen looks a bit like the venerable Mithril in terms of DX.

Yes, I noticed that similarity too a bit -- from the use of a "HyperScript"-like approach (although Mithril can be used with JSX too). https://mithril.js.org/hyperscript.html

Aberdeen is innovative in that it's great to be able to avoid the VDOM in a technical sense. For fun, years ago, I messed around with a different technical approach of just rendering HTML from code directly (similar to Aberdeen to that extent), but instead of an observables-ish idea, I used Mithril's approach of hooking into the event listening system to trigger redraws by wrapping event handlers. Of course, I quickly ran into the issue of losing state like cursor insertion points in editors when re-rendering (which is what motivates the vdom approach). I can wonder if maybe the HTML standard itself could be upgraded somehow to support that approach of replacement of HTML widgets but with retained widget state if an ID or such remains the same?

While I applaud Aberdeen as an experiment, with Aberdeen, it seems problematical developer ergonomics to have everything be a reactive pipeline of some form of observables or signals. It's not especially more terrible than many other systems (e.g. Angular in practice, encouraging the use of RxJS Observables as a new way of encouraging writing hard-to-understand code). As Aberdeen has the previously mentioned innovation of avoiding the vdom, overall it might be a win for people who like that style of coding.

But by comparison, I have found Mithril is so much easier to work with -- given the core idea of just assuming the UI is "dirty" after any listened-for event happens and re-rendering it.

It's true though that Angular has a "Zones" approach to redraw when state changes which hides a lot of complexity but has OK developer ergonomics similar to Mithril in that sense -- until you get mired in RxJS code encouraged by the platform (at least when I last used it seven or so years ago). And then Angular code get mired in various other Angular-isms which requires bloated code in practice with lots of files to do the simplest component. Yes, you can try to work around a proliferation of files, but that is not the Angular way, or at least was not several years ago. And Angular advocates would argue the standardization is a big win for larger projects with multiple developers. YMMV.

Also, dsego, thanks for submitting to HN in 2022 the essay I wrote on all that (which I just saw thinking prompted by seeing this article to check if it had already been submitted somehow): https://news.ycombinator.com/item?id=25194873

For others, this the essay which goes into more depth comparing developer ergonomics of React, Angular, and Mithril from my experience: "Why I prefer Mithril over Angular and React" https://github.com/pdfernhout/choose-mithril

For a simple Mithril example with no special Observable or signal magic, see, say: https://kevinfiol.com/blog/simple-state-management-in-mithri...

    let count = 0;

    const Counter = {
      view: () =>
        m('div',
          m('h1', 'Counter'),
          m('p', count),
          m('button', { onclick: () => count += 1 }, '+'),
          m('button', { onclick: () => count -= 1 }, '-')
        )
    };

    m.mount(document.body, Counter);
The state is stored in just a regular JavaScript variable ("count" in this case), not a wrapped something or other special object (like Aberdeen or any other Observable or signal approach requires). This is made possible in Mithril in this case by the onclick method being transparently wrapped bu the HyperScript "m" function (or JSX equivalent) to call m.redraw() after the click event is handled. As with Mithril's HyperScript approach of leveraging JavaScript to generate HTML instead of inventing a weird non-standard templating system like JSX, Mithril's wrapping of event handlers leverages the ability to just simply define state in JavaScript closures or objects -- or whatever other more complex approach you want including even RxJS observables (as long as m.redraw() is called as needed if you make data changes outside an event handler). Lego Horie, Mithril's original inventor, just was brilliant with Mithril at creating great developer ergonomics.

Re: Show HN: Aberdeen – An elegant approach to reactive UIs

#102
post #100

Can a component have some local state that is passed down to children? Or any data has to be in a proxy object that is outside of any components?

Sure! As long as the scope that creates the state does not subscribe to it, state can be created anywhere.

In the following example, each of the three 'things' has its own votes state:

  function drawThing(title) {
    const votes = proxy({up: 0, down: 0});
    $('h1:'+title);
    $('button:', () => votes.up++);
    $('button:', () => votes.down++);
    $(() => {
      // Do this in a new reactive scope, so changes to votes won't rerun drawThing,
      // which would reset votes.
      $(`:${votes.up} up, and ${votes.down} down`);
      // Of course, we could also call `drawVotes(votes)` instead here.
    })
  }
  
  onEach(['One', 'Two', 'Three'], drawThing);

Re: Show HN: Aberdeen – An elegant approach to reactive UIs

#103
post #100

Can a component have some local state that is passed down to children? Or any data has to be in a proxy object that is outside of any components?

Sure! As long as the scope that creates the state does not subscribe to it, state can be created anywhere. In the following example, each of the three 'things' has its own votes state: function drawThing(title) { const votes = proxy({up: 0, down: 0}); $('h1:'+title); $('button:', () => votes.up++); $('button:', () => votes.down++); $(() => { // Do this in a new reactive scope, so changes to votes won't rerun drawThin…

Ok, I see! Thanks!

Re: Show HN: Aberdeen – An elegant approach to reactive UIs

#104
post #98

Earlier quoted context omitted.

Aberdeen looks a bit like the venerable Mithril in terms of DX.

Yes, I noticed that similarity too a bit -- from the use of a "HyperScript"-like approach (although Mithril can be used with JSX too). https://mithril.js.org/hyperscript.html Aberdeen is innovative in that it's great to be able to avoid the VDOM in a technical sense. For fun, years ago, I messed around with a different technical approach of just rendering HTML from code directly (similar to Aberdeen to that extent),…

> it seems problematical developer ergonomics to have everything be a reactive pipeline of some form of observables.

Why do you think that would hurt ergonomics? You can use whatever data structures you normally would (including typed class instances), you'll only need to proxy() them to be observable.

Re: Show HN: Aberdeen – An elegant approach to reactive UIs

#105
post #98

Earlier quoted context omitted.

Aberdeen looks a bit like the venerable Mithril in terms of DX.

Yes, I noticed that similarity too a bit -- from the use of a "HyperScript"-like approach (although Mithril can be used with JSX too). https://mithril.js.org/hyperscript.html Aberdeen is innovative in that it's great to be able to avoid the VDOM in a technical sense. For fun, years ago, I messed around with a different technical approach of just rendering HTML from code directly (similar to Aberdeen to that extent),…

Here's what your Mithril examples looks like with Aberdeen:

  let count = proxy(0);
  
  function Counter() {
      $('div', () => {
          $('h1:Counter'),
          $('p:'+count.value),
          $('button:+', { click: () => count.value += 1 }),
          $('button:-', { click: () => count.value -= 1 })
      })
  }
  
  $(Counter);
  // Or just Counter() would work in this case
The '.value' is needed because we can't proxy a number directly. This extra step goes a way if you have more data to store, like `person = {name: 'Peter', age: 42}`.

Besides that, looks pretty similar yeah! Works rather differently though. :-)

Re: Show HN: Aberdeen – An elegant approach to reactive UIs

#106

Earlier quoted context omitted.

Yes, I noticed that similarity too a bit -- from the use of a "HyperScript"-like approach (although Mithril can be used with JSX too). https://mithril.js.org/hyperscript.html Aberdeen is innovative in that it's great to be able to avoid the VDOM in a technical sense. For fun, years ago, I messed around with a different technical approach of just rendering HTML from code directly (similar to Aberdeen to that extent),…

> it seems problematical developer ergonomics to have everything be a reactive pipeline of some form of observables. Why do you think that would hurt ergonomics? You can use whatever data structures you normally would (including typed class instances), you'll only need to proxy() them to be observable.

Thanks for the replies. Having to add "proxy" or similar everywhere is the ergonomics issue to me (others might disagree).

Re: Show HN: Aberdeen – An elegant approach to reactive UIs

#107

Earlier quoted context omitted.

Yes, I noticed that similarity too a bit -- from the use of a "HyperScript"-like approach (although Mithril can be used with JSX too). https://mithril.js.org/hyperscript.html Aberdeen is innovative in that it's great to be able to avoid the VDOM in a technical sense. For fun, years ago, I messed around with a different technical approach of just rendering HTML from code directly (similar to Aberdeen to that extent),…

Here's what your Mithril examples looks like with Aberdeen: let count = proxy(0); function Counter() { $('div', () => { $('h1:Counter'), $('p:'+count.value), $('button:+', { click: () => count.value += 1 }), $('button:-', { click: () => count.value -= 1 }) }) } $(Counter); // Or just Counter() would work in this case The '.value' is needed because we can't proxy a number directly. This extra step goes a way if you ha…

Thanks for the example. I agree they look very similar, which is what dsego saw intuitively and commented on.

The difference in the two examples is essentially whether things need to be proxied or not.

If someone does not mind that proxying, then Aberdeen has an advantage over Mithril by avoiding the complexity of the vdom internally. So, presumably the rendering code is simpler, which may have some benefits in performance and also debuggability in some cases. You can get surprising vdom-code-related errors from Mithril sometimes for something misconfigured in a hyperscript "m" call. Also the vdom regeneration can sometimes have issues if you don't specify a "key" for each m() widget, needed sometimes so the vdom can be sure to replace DOM nodes efficiently and correctly.

If someone does mind the proxying requirement (like me), then Mithril has the advantage in that regard of seeming simpler to code for (without the data wrappers). Mithril applications also may be easier to debug in some other cases -- because you don't have an extra proxy levels as indirection in viewing your data model.

So, both approaches have their pros and cons depending on preferences and priorities.

Re: Show HN: Aberdeen – An elegant approach to reactive UIs

#108

Congrats for reaching 1.0! Nice little library, but as it's signals based, it would be nice to make it compatible with the signals proposal ( https://github.com/tc39/proposal-signals ) At the same time for me, while it's super nice, in my opinion it just doesn't differentiate enough from other signals based frameworks to get mass adopted / make CRUD apps that much easier to make. The problem with remote server/databa…

I just read the signals proposal and was not impressed. There is a lot group thought in JavaScript, in Java too but more in JavaScript, around standardizing convenience based upon knowingly bad decisions from convenience abstractions. Managing and updating the DOM is stupid simple and that simplicity has nothing to do with state, which a fully separate yet equally simplistic concern. That is something UI frameworks m…

examples?

Re: Show HN: Aberdeen – An elegant approach to reactive UIs

#109
As a web developer of too many years, I just can't get my head around the need for these kinds of reactive libraries.

Re: the first example, the reactive counter.

First of all it mixes content and JavaScript which is a sore subject but personally I prefer to keep the two clearly separated.

Secondly it's a whole bunch of new syntax to achieve what can be done in fewer lines of JavaScript or jQuery and without mixing content with logic:

https://jsfiddle.net/tu1cqh8y/

Re: Show HN: Aberdeen – An elegant approach to reactive UIs

#110
post #24

The two downsides you list ("lack of community" and "lack of ecosystem") are not really downsides. If something is good enough, people will simply adopt it out of excitement, and those two problems will disappear entirely. See Rust and React. This looks and sounds incredibly clever, and seems to be what I always wanted React to be. I'm eager to try it out! Could you make a demo of a simple Todo list app in it that le…

I think what you're looking for is mithril. It checks every one of these boxes, except it has a nicer developer experience and still has lifecycle methods, which seem much easier to reason about and test than Aberdeen. Seriously, check it out. You'll be impressed. You can learn the API in a day, and it's super stable and thoughtful. I've been using mithril for a decade and the only time I don't reach for it is if web components solve my problem (smaller projects, non-SPAs)

https://mithril.js.org

Post reply on HN