Hacker News new | past | comments | ask | show | jobs | submit | vanviegen's comments login

If you're spending $1.9 trillion per year more than you're earning (projected for 2025), accumulating debt, I think it's fair to say you're living well beyond your means.

We're talking about $5600 per inhabitant per year.


I didn't say Americans aren't living beyond their means. Just that on the face of it they aren't living beyond their means due to their currency's status if that status gives them some means to buy more. OP just didn't really provide a rationale as to why it's this currency issue in particular that you can point to to say Americans are living beyond their means.

Lots of countries have a lot of debt, many are in similar boats or worse as USA when you look at various metrics like debt per capita, per gdp, etc. Politicians and their "experts" and economists etc generally insist this is perfectly fine. I also get the feeling they're probably lying about that and many other things, though I don't know enough about the subject to actually know myself.


Don't let the $ fool you! :-)

I admit that it takes some getting used to, but the fact that it's just JavaScript is a feature!

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);

Ok, I see! Thanks!

You're right. Updated, thanks!

> I don't dislike it

That must count for something! :-)

Re "Vue": https://news.ycombinator.com/item?id=43937303

When running a function through `$()`, it will keep track of proxied data that was read, and of all DOM changes made. When data changes, DOM changes are reverted, and the function is rerun. As at least such a function exists for each DOM element that has children, it's pretty finegrained. Also, Aberdeen is smart about reactive iteration.

With enough transpiler magic, impossible is nothing! :-)


While in a rendering scope, `getParentElement()` will get you access to the raw DOM element. As long as you don't detach/move it, you'll be fine letting third-party code loose on it.

Aberdeen has one life cycle callback: `clean`, which is called right before rerunning or destroying a scope.

I think that's enough for just about anything you'd want to do.. ?


I've tried to address the technical difference (as far as I understand Solid) at the top of this comment: https://news.ycombinator.com/item?id=43940144

Yes, it's an easy trick: just rerender the tiny parts of the DOM that actually need to change. Like Svelte does, only with run-time magic, instead of compile-time magic.

Thanks!

Yes, there's some similarity to Solid.js, but also two big differences:

1. A Solid.js signal contains a single atomic value that can be subscribed to, while an Aberdeen proxy can wrap around a complex object (containing arrays containing objects, etc), and subscribe to only the primitive values that were read.

2. If I understand correctly, Solid.js can only redraw entire components (which may not be great at it, like Aberdeen, doesn't use a VDOM), while Aberdeen creates observer scopes every time you nest DOM elements (or manually, if that is not enough for some specific case).

So Aberdeen is more finegrained on both counts. And there's no need for createMemo and createEffect.

Re "Elegant and simple": the Aberdeen internals are far from simple, but I think its semantics are very simple to understand. Especially when compared to monsters like React. But I'd settle for easy. :-)

> "And in many ways, it's more natural to express DOM structures as JSX-ish components."

Yeah, until you want to add some loops and conditionals in there. That's what regular programming languages are really good at. But it's a trade-off for sure.

> "this is just plain gaslighting" ... " and you end up having to solve all the same issues as with all those libraries"

I don't think that's the case. In my (admittedly colored) experience, Aberdeen allows you to do the same things while having to learn far fewer concepts.

But reading back my text, the claim could have better just said that, as replacing a ton of complex concepts with a ton of different but equally complex concepts is not better. I've updated the site.

> You are pretending that this library does away with a lot of things that are the bread and bones of other UI libraries but then your UI library still needs all those things.

My claim is that we don't, in fact, need all those things. As Aberdeen takes a rather different approach, we do of course need some other things (as you pointed out earlier), but I believe this approach allows us to have less of them.

Re "Diamond problem": I haven't heard the term before, but Aberdeen solves this by a) batching updates (using a setTimeout 0 by default) and b) rerunning all dirtied scopes in the order that they were initially created.

> but trying to frame it in a way that it is superior to using something like JSX seems like gaslighting to me.

I'd be happy to add more downsides to the why-NOT-to-use-this list, but my rose colored glasses seem to prevent me from articulating something that makes sense there. :-)

Re "TypeScript" safety: It says `"strict": true` in the config file. Any other settings you'd want on? Also, the lib has 100% test coverage, if you're into that sort of thing! :-)


Re 1, SolidJS also has a `createStore` primitive which works the same as your $proxy. That said, based on your other comment that I relied to, it sounds like your internal signals implementation is based on the nested, mutable object case, which is fascinating - I believe most other signals implementations go the other way round, starting with atomic signals and then nesting them to create fine-grained reactivity.

Re 2, no SolidJS works basically the same as this. For example, in SolidJS,

    <div>my name is {name()}</div>
will transpile to something like (very approximately)

    const el = _render("<div>...");
    const textNode = el.children[1];

    createEffect(() => {
      textNode.nodeValue = name();
    });
The render call creates the element once per instance of the component (i.e. not rerendering on ever change), and the `createEffect` is doing roughly what `$(() => { /* */ })` is going - i.e. rerunning the function ever time the called signal changes. This means that when `name()` changes, only one specific node in the DOM will change, and no other work will get done, making the update about as fine-gained as it's possible to get.

Aberdeen looks like it should be able to do something similar like

    $("div", ":my name is", () => name)
Which I'm guessing would only rerender the "name" node, right? Although I imagine in most cases it's easier to be a bit less fine-gained for the benefit of slightly easier-to-read templates when developing.

I do like this as a no-build alternative to SolidJS, and I think the syntax works really well for creating mini templates. I can imagine this being great for dropping in little components on traditional server-rendered, mostly static pages - no need for a large library, just something providing the bare essentials in a clean way.

You mentioned somewhere that in benchmarks, this seemed to be running at around React performance (albeit a lot more lightweight). I suspect you can get a lot more performance by fiddling with the signals implementation. It might even be worth pulling in an existing signals library as a single dependency, or at least exploring how some of the more performant ones are implemented and taking those ideas. Especially as things get more complicated and you end up with more nested `observe`s, getting that to work efficiently is going to be difficult.


You're right about Solid, of course, I forgot about its compiler doing magic!

  $("div", ":my name is", () => name)
Close.. but $() doesn't act an return values of function arguments. You'd need to do:

  $("div:my name is", () => $(":"+name.value))
Or:

  $("div:my name is", {text: name})
Or, if indeed you don't care about recreating the <div> (which would normally be the case):

  $(`div:my name is ${name.value}`)
Re performance: Aberdeen is already pretty well optimized, so I don't think a lot more could be squeezed out. Aberdeen performs pretty well on js-framework-benchmark, but not spectacular. There's a certain amount of overhead involved in having many fine-grained observers and fine-grained observable. What you gain from that, is a lot more flexibility in where state can live, and not having to worry about things like memoization.

Where Aberdeen does really shine, performance wise, is reactively displaying lists ordered by some specific function. Other frameworks generally require a sort() and complete list VDOM redraw for each little change, while Aberdeen can just redraw a single row (using a skiplist to determine its (new) position in O(log n)).


Hello, congrats on the release of your framework! I myself also wrote a reactive library for my own projects long ago when jquery was still widely used.

Anyways, these days I moved from React to Solid.js so I know a bit how Solid works.

1. Solid.js also has "stores" and "createMutable" which allow deep tracking of objects and are also built on Proxy objects. Signals are great for single values, but Solid stores and createMutable are for more complex data.

2. Solid.js doesn't redraw entire components. (It's not like React.) It is fine grained and only updates the minimal exact DOM nodes required. This is why it is so fast and topped benchmarks when it first came out. https://dev.to/ryansolid/introducing-the-solidjs-ui-library-...

I found https://blog.theodo.com/2023/07/solidjs-beginner-virtual-dom... which might be a good intro explanation to it.

> Yeah, until you want to add some loops and conditionals in there. That's what regular programming languages are really good at. But it's a trade-off for sure.

Solid's <For> and <Show when={}> and <Switch> tags are actually quite nice and very easy to parse visually.

Regarding the "gaslighting" comments, I kind of feel the same way as the grandparent. No offense meant and I support everyone coding new open source frameworks, but it does kind of feel like that.

I suggest doing a deep dive into Solid and even checking Ryan's blog https://dev.to/ryansolid or YouTube channel. There are a ton of concepts and good ideas to learn. He and tanstack are like at the forefront of web dev today.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: