[HN Gopher] Show HN: Hyper - Standards-first React alternative
___________________________________________________________________
Show HN: Hyper - Standards-first React alternative
Author here. This is an attempt to simplify frontend development:
1. Standards first: User interfaces should be assembled with HTML,
styled with CSS, and enhanced with JavaScript. 2. Less
abstractions: UI composition should be easy and require as few
idioms and abstractions as possible, both on client and server. 3.
Design Systems: Design should be a separate subsystem, easily
accessible for developers who care about and understand design. 4.
Scalability: Complex UIs should retain simplicity as the
application grows. Eager to hear your thoughts!
Author : tipiirai
Score : 48 points
Date : 2025-05-09 13:59 UTC (9 hours ago)
(HTM) web link (nuejs.org)
(TXT) w3m dump (nuejs.org)
| jitl wrote:
| How do you virtualize rendering of a table with 100,000 items
| with Hyper?
| tipiirai wrote:
| When you go pass 100k-200k records on the client side,
| typically fetched with event sourcing pattern, you must resort
| to WASM. Here's a RUST based example with 150k records to
| tackle the situation: https://mpa.nuejs.org/app/?rust
| madeofpalk wrote:
| > you must resort to WASM
|
| Where does the 'must' come from? A react component will
| trivially handle 200k records with list virtualisation with
| just javascript
| tipiirai wrote:
| There is an offset (depending on the app) where JS crashes
| with stack overflow exception, and only WASM can continue
| from there. On the Nue example with user records the
| treshold was around 150k records (only slightly depending
| on the browser).
| madeofpalk wrote:
| What? Nue will just crash with a stack overflow if you
| have an array of over 150k items?
|
| This seems like a pretty deep flaw. It would be okay to
| have poor performance, but flat out crashing seems bad.
| tipiirai wrote:
| No. JS crashes. Try out yourself
| jitl wrote:
| The React example w/ the complicated table API will work fine
| for zillions of records. Virtualization is not complex math,
| and there are many libraries that will implement it for you
| in various languages.
|
| I just tried making an array w/ 1 million items in it in my
| browser console `Array.from({ length: 1_000_000 }, () => ({
| id: ++nextId, data: Math.random() }))` without issue.
| Virtualization is just simple arithmetic to select the
| firstRender and lastRender indexes in the array. I don't
| think you need WASM for this.
| __jonas wrote:
| Can you elaborate on that?
|
| https://bvaughn.github.io/react-
| virtualized/#/components/Lis...
|
| This example seems to be able to do 200k+ rows without any
| problems at all. For me it's smooth up to 10,000,000 even
| with dynamic row heights. Is there something I'm missing?
| brylie wrote:
| I would recommend pagination for a table of that size.
| tipiirai wrote:
| Agreed. No reason to show more than 100+ entries on a single
| table. Event sourcing isn't about UI patterns but rather one
| level beyond it: the "back of the frontend" [1]:
|
| [1]: https://bradfrost.com/blog/post/front-of-the-front-end-
| and-b...
| CafeRacer wrote:
| AgGrid, for example, virtualises the dataset and easily
| render a 100k records: https://www.ag-grid.com/example/
|
| On our app we render large datasets (e.g. 40-50k records) and
| provide filtering/searching with rxjs.
|
| Search even uses a levenshtein distance and the entire
| collection is sorted based on the similarity score.
|
| Works like a charm.
| drcongo wrote:
| This got posted (and flagged) the other day -
| https://news.ycombinator.com/item?id=43902525 - which was somehow
| before the published at date on the article.
| tipiirai wrote:
| You're right. This post has major corrections to the orignal
| post.
| rustc wrote:
| Can you change the React code to also just have one "card"
| class and nothing more? It shouldn't be 4 times longer than
| Nue.
| tipiirai wrote:
| I sure can. How should I change the code? I'll do it right
| away.
| vessenes wrote:
| I love utopian projects like this. And I'll say there's lots that
| is appealing about the sample code, not least its terseness, a
| factor that is going to really matter in the next era of agentic
| coding.
|
| Unfortunately, we don't live in paradise - we need to consider
| say a ratio score, of how much complexity is required, in the
| platonic sense, to deliver React's core feature promises, vs how
| much complexity modern react actually demands.
|
| Whenever I code react I'm certain that number is at least 3:1,
| and I long for a simpler system.
|
| But I think I am probably wrong - I think for the feature surface
| area react covers, it's close-ish to the same complexity level as
| utopiareact(tm). React does a lot. If that's true then a
| framework _could_ be much simpler, but it would then necessarily
| be delivering fewer features.
|
| Upshot: the safest path to keeping this thing simple seems to me
| to be extremely wise about _what_ it promises to do; picking and
| choosing from a "full" feature stack to optimize value-for-
| complexity.
|
| I guess as I write this is a long winded way of saying that react
| is at a point in the feature-complexity Pareto curve. Arguably
| pretty high on the feature axis. It's worth deciding if you want
| to live somewhere else on the curve (big simplicity gains in
| exchange for features) or try and shift the curve in.
| tipiirai wrote:
| Thanks. The utopia is real. React absolutely dominates the
| market and has a certain, monolithic way of doing things. Hyper
| attempts to show that timeless software patterns, namely
| separation of concerns (Remember Gang of Four?), can bring
| significant benefits to the frontend scene.
| rizky05 wrote:
| What if nue way of doing differ with what I want ? How do you
| customize anything ? IMO React win because it tries to do all
| of that.
| tubthumper8 wrote:
| Can you expand more on the Gang of Four comment? Which
| separation does GoF describe that is applicable in this
| context? And what is the definition of a "concern"?
| nicce wrote:
| How would you say that this solves the similar problems as React
| Server Components?
|
| E.g. yesterday's discussion -
| https://news.ycombinator.com/item?id=43929054
|
| Basically, how do you remove the gap (network implementation)
| between back-end and front-end, so that you don't need to think
| about the difference. You define the components in same place,
| and can add dynamic features for client-side when you need them,
| but the rest of the code can be even compiled to static in a
| seamingless way.
|
| Without solving this, I wouldn't really use a new framework that
| doesn't challenge the similar problem.
| tipiirai wrote:
| The challenge is that there is a difference. Client is
| "reactive" and server rendering is static. The SSR output needs
| to be some sort of hybrid, which Hyper is absolutely going to
| tackle. This is another area where simplicity shines. Hyper
| components renders exactly the same on server and client, but
| when SSR detects a dynamic piece it renders a "stub" to be
| filled by the client part.
| superchris wrote:
| Really like what I'm seeing so far. It looks a lot like Sprae:
| https://github.com/dy/sprae one of my favorite things that no one
| seems to be paying attention to :) I use it on live-templates,
| which uses Sprae to connect a template to stateful backend in
| Elixir over Phoenix Channels:
| https://github.com/launchscout/live-templates
| skrebbel wrote:
| Hey wow, sprae looks very nice indeed. Kinda what I had wanted
| Alpine to be.
| rustc wrote:
| What's up with the code comparisons under "Complex components"?
| Why does the React version include so much more stuff than the
| Nue version? Does Nue automatically inject all those features in
| your app with just a "card" class on the top level element? The
| React version has full styling, icons, sortable columns, etc.
| tipiirai wrote:
| This is a prime example of how complexity grows and how simple
| components remain simple. Just look for the button example: the
| one button being larger than the entire app. Consider going on
| from there. Think legos: the 2/4/8 units scale, while the more
| complex units struggle to fit together.
| pier25 wrote:
| I don't love or use React but these examples are
| disingenuous.
|
| It sounds like you're arguing that "React devs don't know how
| to manage complexity" which is a completely separate issue
| than React itself.
| tipiirai wrote:
| I definitely want the examples to be exact. How to fix
| exactly?
| teg4n_ wrote:
| I mean even basic stuff is different. You have thead and
| tbody in the react example but not in the hyper example.
| It adds number of lines differential which I guess is
| supposed to be impressive but when I see stuff like that
| it makes me think the whole comparison is worthless since
| it can't be trusted.
| pier25 wrote:
| Only use 1:1 markup/features instead of adding those
| "modern react" examples.
| Timon3 wrote:
| You ask this every time, but never incorporate the
| feedback. Why even bother?
| tipiirai wrote:
| Where is the feedback?
| rustc wrote:
| Your table does not have the same features as the React one,
| so this comparison does not make any sense.
| tipiirai wrote:
| What's the difference? I can easily add the missing peaces.
| rustc wrote:
| Did you run the React code you wrote in the blog post? It
| has sorting, icons, filtering, typescript types.
| tipiirai wrote:
| Yes. The React example restricts to sorting and filtering
| only
| jonplackett wrote:
| These examples are deliberately misleading. The react code
| does not need to look like this mess.
| tipiirai wrote:
| I want the examples to reflect real-world scenarios. Please
| explain how to simplify the React code. I'll fix it
| immediately.
| nicce wrote:
| Why not just include equal features to comparisons? New
| framework should also handle the real-world scenarios.
| SebastianKra wrote:
| This happens every single time this framework is posted.
|
| - The post makes some outlandish, to-good-to-be-true claims.
|
| - It traction because A: it mentions React and B: who doesn't
| sometimes wish development could be simpler.
|
| - Readers call out the claims for being misleading or outright
| lies.
|
| - The author deflects with "I could easily add that", "you
| don't need that", or "keyed lists are unnecessary"[^1].
|
| [^1]: https://news.ycombinator.com/item?id=37735353
| andrewmcwatters wrote:
| If I'm already writing against web standards, why would I want to
| use Hyper? I'd just be hitching my work against something that
| had nearly no risk, but just enough dependency risk to not be
| worth it.
|
| At my business, we've moved from using React for client work to
| completely eschewing it in favor of web components. In fact, we
| basically don't use any major frameworks anymore. There's Express
| on the backend, and that's about it. I'd like to swap it out for
| more Go, but that's digressing.
|
| I suspect that now that the front-end is a bit more stable than
| it has been in previous years, the remaining friction will
| increasingly become the remaining distraction for many
| developers.
|
| I don't want React changing minutiae on my team for pointless or
| ideologically pure reasons. I just don't care. The changes bring
| no tangible improvements. And we also use basically no tooling.
|
| Really mature software projects want as few dependencies as
| possible to minimize unnecessary friction. Your audience for this
| is a group of developers who are already pointed in this
| direction.
| internetter wrote:
| See https://news.ycombinator.com/item?id=43543241 -- Announcement
| post for Nue
| ohcmon wrote:
| Please, not another `strings` programming language
|
| `<tr : for="user of users">`
| tipiirai wrote:
| I see your stance! There are two ways to this: JS-first (React)
| or HTML- first. Hyper takes the latter: purely focusing on the
| semantic HTML structure when assembling interfaces. Focusing on
| pure structure (like React 1.0) and delegating design and logic
| to concerns that master it the best.
| mpeg wrote:
| You should take a look at markojs, it's also html-first but
| the syntax is IMHO more elegant as it extends html
| (especially the alpha of 6.0 syntax)
| kakuri wrote:
| My thoughts exactly. JSX provides the best templating syntax I
| have seen - it's just JS, and it uses curly braces to delineate
| JS. Putting JS, or worse, custom syntax in strings is terrible,
| and every other delineator choice is less idiomatic and uglier
| than curly braces.
| silverwind wrote:
| JSX is good but still has room for improvement:
|
| - Original HTML attribute names, `class` instead of
| `className`, `for` instead of `htmlFor`
|
| - Let expressions and components return multiple elements
| without the need for `Fragment`.
|
| Could make a JSX 2.0 which would be much closer to actual
| HTML.
| mpeg wrote:
| Stringly typed templating language
| dleeftink wrote:
| Is this the next step for Riot.js? Or a new direction? I've
| always been interested in riot's approach and wonder about its
| influences here.
| tipiirai wrote:
| It is! (I'm the original author of Riot)
| dleeftink wrote:
| Any parts of riot you are taking with to Hyper? Do we still
| need to compile?
| mg wrote:
| Hyper syntax: <tr :for="user of users">
| <td>${ user.name }</td> <td>${ user.email }</td>
| <td>${ user.age }</td> </tr>
|
| EJS syntax: <% for (user of users) { %>
| <tr> <td><%= user.name %></td>
| <td><%= user.email %></td> <td><%= user.age
| %></td> </tr> <% } %>
|
| I prefer EJS, because all you need to know is "<% begins JS" and
| "%> ends JS". Everything else is just plain HTML and JS.
|
| The EJS website: https://ejs.co
| tipiirai wrote:
| The core difference here is "reactivity". You cannot build
| large-scale apps without state management and domdiff.
| mg wrote:
| How is that related to the syntax?
| tipiirai wrote:
| Not related
| __jonas wrote:
| Interesting, what is the origin of that syntax (EJS)?
|
| I know it from Elixir [0] and strongly dislike it there, I was
| under the assumption in comes from Ruby [1] since so much of
| Elixir is Ruby-inspired, is this JS version the original one?
|
| [0] https://hexdocs.pm/eex/EEx.html
|
| [1] https://github.com/ruby/erb
| EGreg wrote:
| Why not just embed html templates in js at this point? Why js
| in html?
| __jonas wrote:
| > This is an oldschool example using external CSS, which is no
| longer the "idiomatic" way to build React compomnents:
|
| Where does this claim come from?
|
| classNames and an external CSS file is literally the first
| suggested way to do styling according to the docs:
|
| https://react.dev/learn#adding-styles
|
| I don't doubt that tailwind and shadcn and such are popular, but
| they are not even mentioned in the react docs, so I don't think
| you can call it the 'idiomatic' way
| tipiirai wrote:
| This comes from the "real world". React ecosystem deliberately
| loathe CSS. Just give me _one_ professionally designed website
| where CSS is used as intended, using modern features like
| @layers, calc(), and --variables. I 'm super curious! Hoping
| I'm wrong :)
| __jonas wrote:
| I'm struggling to understand what you're getting at tbh - I
| definitely see the disdain against vanilla CSS in a lot of
| React users / projects, and I'm with you in being critical of
| that, I quite enjoy writing plain modern CSS and haven't had
| any real interest in Tailwind and tools like it.
|
| The point is that React doesn't impose any of that and even
| suggests the "classic" CSS approach in the official docs, so
| I don't think you can use it as point of criticism of React,
| the framework, which you seem to be doing since you are
| drawing a comparison between React and your own framework.
|
| The "ecosystem", which certainly does it's own thing, doesn't
| have anything to do with that, especially since I'm guessing
| Nue does not have an "ecosystem" at this point (that's not an
| insult!) so the comparison seems a bit pointless?
| tipiirai wrote:
| I see your point. But can you give me a link to one React
| project with professional design, implemented with extenal
| CSS?
| pacifika wrote:
| https://news.harvard.edu/gazette/ Source: day job
| tipiirai wrote:
| Thanks! A rare one
| mock-possum wrote:
| I'm really not a fan of the comparisons between the react code
| and the nue code - it comes off as disingenuous.
|
| Just as an example that catches my eye - the complex table react
| example includes sorting icons, but the nue example doesn't. If
| you remove features then of course there's going to be less lines
| of code.
|
| Feels like it's strawmanning rather than ironmanning.
| lern_too_spel wrote:
| There are dozens of "better React" web frameworks, so it is
| impossible to get any traction with that value proposition
| because any attempt at building a new ecosystem will be diluted.
| That ship has sailed. New frameworks should solve problems that
| are very difficult in existing frameworks. https://qwik.dev/ is a
| good example.
| bandoti wrote:
| I'm starting to feel like Tommy Lee Jones in No Country for Old
| Men.
| faefox wrote:
| The Angular/Vue approach of sprinkling application logic in HTML
| attributes demos really well - wow, it's like magic! - but it can
| only end one of two ways: either it's too simple to keep up with
| real-world requirements so you end up implementing everything in
| JS anyway, or it tries to be everything to everyone and you end
| up with hideously convoluted and slow DSLs like the abomination
| that is ngFor.
|
| Personally I think attacking the problem from the other direction
| and making JS more fluent at generating markup is the much more
| practical approach and that's why JSX won.
| dleeftink wrote:
| I've been getting productive with Facet's approach, especially
| its 'templates as mixins' paradigm [0]. This gets really
| powerful when you consider how template scripts are
| automatically scoped.
|
| But there is much more to like. In fact, while a scripting
| escape hatch is there, this microlibrary asks you to touch JS
| as little as possible.
|
| [0]: https://github.com/kgscialdone/facet
| streptomycin wrote:
| So many front end frameworks that they can't even all have unique
| names https://hyperdom.org/
| librasteve wrote:
| I admire the goal of concise and expressive code.
|
| Here is the basic table example presented in the post recast in
| https://harcstack.org functional HTML (well this is the entire
| website)... sub SITE is export { site
| index main table :thead[<Name Email
| Age>,], do {[.name, .email, .age]} for @users
| }
|
| Note to self - never, ever do "like-for-like" comparisons with
| code.
|
| To be fair HARC Stack doesn't have a table component with
| sortable, filterable cols yet - but it is HTMX centric so should
| be pretty fun to spin one up.
|
| And never mention that this is raku code.
| slenk wrote:
| I wish open-source projects checked to see if other projects
| share the same name.
|
| Especially since there are packages in NPM already about hyper.
|
| https://hyper.is/ has been around for a while and is kind of big
___________________________________________________________________
(page generated 2025-05-09 23:01 UTC)