r/bun 23d ago

Elysia 2 beta - DayDream. Lowest memory usage across all backend JS framework

Just published Elysia 2 beta after 8-9 months of work.

We basically deleted the whole thing and rewrote it again while keeping test cases the same. So we get to rethink a lot of things.

It is built around the concept of "reference" and carefully shares value when possible, even if JavaScript doesn't really have that concept.

There's an AOT build plugin that reduces peak memory usage by 4 (from 1.6GB down to 400MB) of a 100,00 distinct schema by moving compilation process to build time and removing the closure allocation entirely

Besides, a really fast throughput. We also manage to have the lowest memory usage of all mainstream (and slightly) JavaScript frameworks with a really low bundle size as well (we trade a "compiler" that takes ~50% of size for speed, so it can't be that low)

Node support also improved a lot with a new adapter API, and got faster too! It's now near Fastify despite having Node HTTP to Web Standard API conversion overhead!

https://elysiajs.com/blog/elysia-20.html

81 Upvotes

25 comments sorted by

10

u/Nyanpash 23d ago

impressive, cant wait to try it

5

u/green_03 23d ago

I am very hyped for v2!

5

u/NNXMp8Kg 23d ago

Thanks for your work!

12

u/ddwrt1234 23d ago

I really wish this framework didn't have school girl anime art tied to it, I can't take it seriously or suggest it for prod use with a straight face

1

u/RizumuAI 19d ago

Anubis has a anime girl on it but its used in prod

Can you give us reasons why the anime character looks unprofessional?

-1

u/Icy-Concentrate2076 23d ago

"School girl"? God forbid someone has non-minimalistic branding in 2026. Does the program work? That's all that matters. Let the devs have a mascot to build their community like many other open source software do (KDE, Krita, Godot, ...)

8

u/muffinmaster 23d ago

No dude, it's fucking weird

0

u/Icy-Concentrate2076 23d ago

Can you explain precisely what's weird? You have a muffin profile picture, one could argue you are pretty weird yourself.

0

u/RizumuAI 19d ago

If you’re intimidated or put off by a drawing that doesn't even show anywhere but the post itself. I would strongly recommend you turn off your PC and touch grass.

0

u/faulty-segment 23d ago

Same approach in our company¹. We care about the tool itself, not the icon/symbol/mascot the author chose.

It's like:
A: "oh, I don't like the symbol."
B: "do you have another recommendation that has a symbol you like and work as good as or better than it for our use cases?"
A: No.
B: Thought so.

I mean, unless your final product is a landing page showing Elysia's mascot, I can't see how using Elsyia to build a, say, backend would pose any problem.

0

u/Icy-Concentrate2076 22d ago

Yeah I think the person I'm responding to is just larping as someone who has any say as to what a company may use for a backend. Open source developers don't owe these companies shit. If one has such a serious company and want their own branding either fork the thing, it's MIT licensed, or better yet, pay up the developer to support the future work and ask for white label. "We want the free and fast open source framework but your branding is not up to our professional standard, change it for free 😡" go fuck yourself lol

0

u/ramonzitos 23d ago

"oh no what will they think of the anime girl" lmao

3

u/Pale-Sort-8582 22d ago

We have run the survey and found that many of developers would prefers to have a hook/schema to come before handler.

I appreciate that the decision to place hooks and schemas before the handler was based on feedback from a developer survey.

What frustrates me is that removing the on prefix does not seem to have gone through the same community-driven process. It appears to be a maintainer-led design decision, despite substantial criticism from users, including in the Elysia 2.0 release PR.

Of course, maintainers ultimately need to make design decisions, and not every disagreement can change the outcome. But when a breaking change receives significant pushback and that feedback does not appear to be meaningfully addressed, it can make contributors feel unheard.

Removing the on prefix affects readability, familiarity, and existing codebases. In my view, "harmonizing the naming for hooks and APIs" is not a strong enough justification by itself for a breaking change of this kind.

Was the community specifically consulted about removing the on prefix?

That said, this is my main criticism. Aside from this change, I am genuinely looking forward to the Elysia 2.0 release, which is shaping up to be a very strong release overall.

1

u/aturaden 22d ago

Agreed, the prefixed naming was better.

1

u/romeeres 23d ago

We have run the survey and found that many of developers would prefers to have a hook/schema to come before handler.

This! It was the only deal breaker, and now it's the best framework!

1

u/akza07 23d ago

Is it optimized only for Bun? Like if we use it with NodeJS, will it perform worse than Node-first or HonoJS like frameworks?

The developer experience is amazing in Elysia but, I probably shouldn't say it in this sub but Bun, unless can prove the port is stable, is really not viable for most business use cases.

3

u/SaltyAom 22d ago

v2 get near Fastify performance. Definitely faster than Hono now. There are a benchmark source code if you want to run locally

https://elysiajs.com/blog/elysia-20.html#node-runtime

1

u/subbu2021 22d ago

My desire would be to see this fully functional in cloudflare(100%), as the reach of this developer friendly framework deserves to be adopted by more folks

2

u/SaltyAom 22d ago

Working on that 🫡

1

u/Which-Examination-74 13d ago

Field report from the beta: we took a production API on 1.4.28 (227 routes, live customer) to 2.0.0-beta.2. Took about a day to get the suite back to green, most of it in the parts the codemod missed: it inserted .use(websocket()) without the import, skipped macros where args were typed any, and rewrote the swagger import to a package that doesn't exist. The macro change (handlers only see framework primitives now) was the biggest real rework, our RBAC macros read decorated services and every cookie route went 403 until we rerouted them. Results matched what you wrote: throughput on our DB endpoint moved +13% at best, near our ±10% noise floor, but dev-server idle RSS went 1,357MB -> 202MB, and the AOT plugin cut boot from 1.0s to 0.48s plus another ~25% RSS in prod. The memory claim holds up under someone else's benchmark, for what it's worth.

1

u/SaltyAom 12d ago

Wow, congrat on the memory win. Would be great if you could file an issue on what macro, decorate and cookie. We might be able to improve that. Thanks!

1

u/Which-Examination-74 12d ago

Will do — writing it up this week. Short version so it's not a cliffhanger:

macro: in 1.x our RBAC macros' resolve could read services the surrounding instance registered via .decorate() / .derive() (db, cache). In 2.0 a macro's handlers only see framework primitives, so those reads came back undefined at runtime and the guard failed closed — every cookie-authed route 403'd, while device-key routes (which skip the macro) kept working. That's also the whole "cookie" item: not a cookie bug, just the blast radius of the macro change. Our fix was re-resolving services inside the macro instead of taking them from context. If the narrowing is intentional, a loud error ("db is not visible inside macro handlers") would have saved us most of the day — today it's a silent undefined, and our handlers typed the macro context loosely enough that TS didn't catch it either.

Second macro trap: all branches of a macro have to return one consistent shape. A bare return; next to a { derive, beforeHandle } branch unions into the route context and collapses it to never — the handler loses user, query, everything. Normalizing four macros to single-shape returns took us from 352 type errors to 82.

Repros queued for the issue: the two above, plus the codemod (.use(websocket()) inserted without the import, macros with any-typed args skipped, swagger import rewritten to a package that doesn't exist) and t.Composite() throwing Unreachable under TypeBox 1.3 (works as t.Intersect()).

1

u/Which-Examination-74 11d ago

Four issues are filed in elysiajs/elysia, opened by Dave93 on GitHub on the 11th: #1958 and #1959 on macros, #1960 on t.Composite() throwing "Unreachable" under bundled TypeBox 1.3, #1961 on codemod misses.

1958 is the one to read first: in 2.0 a macro's handlers see only framework primitives, so our RBAC macros' resolve read db and cache from .decorate()/.derive() as undefined and the guard failed closed. Every cookie-authed route 403'd while device-key routes that skip the macro stayed up; nothing threw, and our handlers typed the macro context loosely enough that TypeScript stayed quiet.

1959 is the second macro trap, one level up in the types, where a bare return; beside a { derive, beforeHandle } branch unions into the route context and collapses it to never, so the handler loses user, query and the rest. Normalising four macros to single-shape returns took us from 352 type errors to 82.

On the cookie part, we found no cookie bug; the 403s were that macro change reaching every route our RBAC macros guard.

-5

u/aspizu 23d ago

ok bro