HN user

dashersw

33 karma

Building things at the intersection of AI, systems, and real-world products.

CTO / founder. I spend most of my time designing multi-agent systems, experimenting with LLM reasoning, and shipping actual products instead of demos. Currently focused on autonomous agents, orchestration, and making AI useful beyond toy use-cases.

Background in software engineering, distributed systems, and teaching. I’ve worked with startups, governments, and enterprise teams—usually stepping in where things are messy and need to scale.

I care about: • shipping over talking • clear thinking over hype • systems that actually work in production

Expect posts about AI, architecture, dev tooling, and occasional strong opinions.

Posts6
Comments50
View on HN

Here is the author of Gea Stack. There is no browser in the device, none of these devices could run one with 512KB of RAM (+2-8MB of PSRAM). We instead transpile TypeScript and CSS into native code, so the UI you build with web technologies look and behave identical on a microcontroller.

I am pondering about this, but would love to see an example to make it more concrete. The way I see it is that this reactivity is completely on the compiler's side, and there's no more ambiguity or pitfalls than misrepresenting a dependency array in a react hook.

[dead] 4 months ago

As an open-source builder and a streamer, I'm afraid I will leak keys on stream any time soon. And fun story—I did leak the API keys to my smart lights once, and the company (Govee) had a 30-day grace period for any revoked keys!

It still looks too tedious to manage all this—curious to see if there's an easier way. Currently I use 1Password in my teams to share .env config, but we basically c/p to local git folders, so there's still a lot to lose.

I'm especially worried about the growing number of supply chain attacks. Curious to see how you tackle these.

Feel free to question anything you like and I'll help you find the answers.

This is a well-trodden path. All aspects of object mutation and its effects are obvious and well-known. What is pass by ref and what is pass by val is also pretty obvious. One can easily pass in primitive values and not worry about two-way binding if they choose to. One can also easily not mutate any props they receive from their parents. This is already the best practice in eslint for like 10 years. This is not easy, this is trivial.

I'd rather see some real concerns.

I don't want to recurse into philosophy but one could argue an assignment is more declarative than a function call :) Solid is function calls everywhere, and extra code, vs plain objects.

I see your point. I designed Gea to be one-way binding only first, and then decided to add two-way binding for props passed as objects. People can still easily only use one-way binding. Maybe this becomes a preference in the compiler config?

The argument for Gea to support two-way binding is basically circular and I believe well-made at this point. I want a framework to respect a language. Breaking two-way binding when it's a concept in the underlying language is like breaking Liskov's Substitution Principle. You can do it, but you probably shouldn't.

JSX is more succinct and efficient than raw DOM API because it's declarative, where the raw API is imperative.

Thank you for the discussion, I find it very interesting and I'd love to understand how you think. Why do you think setStore and produce let you model your application more succinctly and efficiently than just a direct assignment?

And what kind of types of boilerplate do you see Gea is opting out of?

Gea in fact supports regular HTML strings out of the box—that's what the compiler turns the JSX into anyway. However IDE tooling is still in the works for syntax highlighting regular HTML.

What syntax would you prefer from Svelte? Like for hooks / stores, or rendering?

Heh, sorry, I (the author) wasn't the one who created the post. But the idea is reactivity in JS shouldn't require new syntax.

Gea works best with the compiler, I documented a non-compiled (only compiles JSX) browser usage here: https://geajs.com/docs/browser-usage.html but this obviously requires manual store observers and manual DOM updates, which means it's not _really_ benefiting from Gea.

Very interesting benchmark results... well, I guess that's proxies for you.

Getters in Gea are designed to be used as computed properties by the components' rendering cycles, and in that, they don't need explicit memoization. I believe users can implement their own memoized computed variables if they require repetitive access—in which case each store's `observe` method could be utilized in updating the memoized value whenever a specific value changes in the store.

And for the async case, for now the compiler doesn't handle this scenario. It could be added, but as you expect, for now the same `observe` method could help here as well to listen to changes on store0.url and refetch accordingly.

Thanks for your insights. I was originally hesitant about the performance of proxies, too, but they turned out to be great. The benchmarks (https://geajs.com/benchmark-report.html) also show good results. Both in terms of memory and CPU cycles, even though proxies are obviously adding an overhead, it's not day and night (https://jsben.ch/proxy-vs-object-performance-benchmark-dtxo6 is a good test for this). With a proxy, you can set a property 25 million times per second (on my M4 Max machine in Safari) with only 4% perf loss vs defineProperty, and Chrome is about half the perf with 20% loss vs defineProperty. So, still, 12.5 million setters per second is pretty good. Of course if your use case demands more performance, nothing beats a hand-optimized vanilla JS code.

Since Gea doesn't rerender the template _at all (well, for the most part, at least)_, in theory we wouldn't really gain much from getter memoization, mainly because we create proxy observers for computed values that update the DOM in place only when the underlying value updates.

And since stores are plain old JS classes, there's no need for an "async store" concept. Just update a value in the store whenever you want, track its loading state however you want, either synchronously or asynchronously, and the observers will take care of them. If you refer to another pattern that I'm not aware of, please let me know.

Because JavaScript _is_ the language and people know it. I never understood the concept of a "React developer", for example, although I saw many junior devs who were very well-versed in React and didn't completely understand JavaScript.

In the end, it's a design choice. Of course frameworks don't inherently _need_ to be beholden to the standards of the underlying language, but I think this is just simpler, therefore a worthy goal to pursue.

I wish I could bring it to React! That would save so many developers and so much natural resources!

I've been working on the library for 6 months, and it's built upon my previous libraries tartJS (2011), erste (2017) and regie (2019). I just like to squash my commits before I make a public release, and that just happened 4 days ago :)

I understand this bit. The bit that I don't understand is how you compare the two invented concepts like `setStore` and `produce` to just `state.users[2]?.loggedIn = false`. To me it's very clear Gea's syntax requires you to write less code, while also requiring you to know less concepts.

In fact the precedent to Gea, my previous framework erste made use of `pug` tagged template literals! I started with that base, but then decided to ship with JSX instead. This would be a great addition to Gea and would love to see it as a community contribution. I'm hesitant about web components but if we could help web components to feel more "plain old JS" to write, it would be awesome!

This is an interesting idea, though, thanks for bringing it up! I will think about it and try to add it to the compiler. Especially native objects like `window` would be great to create handlers for in the compiler. It would make life really easy for the developer.

I'm not following—the `new` keyword has been with us since JavaScript's inception. You might be confusing it with the `class` syntax, but before that we could always `new` functions.

And yes, Solid has signals that require you to know how to write and work with them. I answered another comment on the thread about Solid stores—they also introduce a couple of gotchas and weird syntax. You just can't do `this.users.push(...)` or `this.users[2].loggedIn = true` in Solid stores.

Therefore `createStore` is less native than `new Store()`, because `new Store()` just gives you a plain (proxied) object you can manipulate in various ways and reactivity will persist thanks to the compiler.

And Gea's design goal is also fine-grained reactivity, which it delivers without getter functions in the code that the developer writes, but rather, the handlers are generated via the compiler.

Solid stores are a great improvement over raw signals, but they still come with their own gotchas. First off, it's an entirely new syntax. You need to learn its documentation. You always have to use setStore, and it has a weird syntax like `setStore("users", 2, "loggedIn", false)` and even pushing items to an array is weird. In Gea it's just regular JavaScript: `this.users[2].loggedIn = false` or `this.users.push(...)`. MobX also comes with its own syntax.

In the end Gea is basically as simple as a plain old JavaScript class, made reactive by its compiler.

Solid is honestly a beast, and I love it! It was a great challenge to even match its performance, let alone beat it. While on several metrics they are within margin of error, select row, swap rows, remove row, and clear rows performances are significantly better on Gea's side.

Having said that, pure performance wasn't the goal as much as the developer experience. I wanted to build something that felt _native_ to the language.

And thank you for the comment on accessibility—I just updated the website and the docs to make the text more legible.

As the author... I somewhat agree :) But I really like synthwave and ever since I came across the design trend I wanted to use it somewhere. And I put twinkling stars on purpose, there's even shooting stars if you wait enough. I understand it comes across as generic AI slop, but this is an early project and it will evolve. I will work on a planetscale-style webpage and maybe I can add it as an option you can toggle on :)

Thank you for the thorough comments! I wholeheartedly agree. And while I believe React invented most of its problems (mostly because we've been engineering GUI solutions since mid-70's and, as I always say, Excel, the god of all UI apps, shipped in 1985) I also acknowledge modern problems like suspenses that occur as a result of elevated expectations.

Gea is frankly very new, and for example doesn't ship a solution for suspenses or fine-grained error recovery yet. And since noone, including me, built a very complex Gea app yet, we don't exactly know if the simplicity will hold up.

But Gea is the 3rd generation of my frontend frameworks, and I've been building vanilla JS-esque frontends since 2011 (when I released my first library, tartJS). The main feature of a good framework is to contain code complexity as the app grows and I believe as GUI engineers we have some good patterns to flatten the complexity. Gea is just trying to hide repetitive DOM updates behind a compiler, and while it has proven somewhat difficult to account for all the different ways people (or AI) write JavaScript, I'm constantly improving the compiler with new patterns.

That's why Gea ships with several GUI app implementations—my approach is kind of simple. If I can get AI to generate several different UI apps in different domains, I can capture a good enough set of complexities for which I can deliver solutions. I've already fixed tens of bugs that I could only see as a result of building a UI with the library.

Having said that, it's still very early for Gea. I guess only time will tell if we will have to resort to different, non-idiomatic solutions to handle more complex demands. At least the philosophy is very clear—Google built its original web 2.0 apps with Google Closure Library, an imperative UI framework, with lots of repetitive boilerplate. And that was enough to give us maps and google docs, etc., so I am hopeful for the future that we will be able to find idiomatic solutions.

Heh, sorry it comes across as LLM-y, honest and human-written answers here only. I'm tired of AI slop as much as the next guy, but, yes, I _really_ took my time with Gea. I've been working on writing JS frameworks for 15 years, this is actually the 3rd generation of similar ideas, following tartJS (2011) and erste & regie (2017-2019). It took me several years to solidify what I expect from this generation, and I've been working on Gea for the past six months. That's why I thought about and evaluated many aspects raised here.

And thank you!