Svelte 5 is not JavaScript
hodlbod.npub.pro
hodlbod.npub.pro
But, most frontend people don't do testing at all. Typescript is the tool people use to guarantee correctness, and for good reason. But, svelte people have always cast a narrow eye towards typescript and for good reasons as well. So, here we are.
I personally prefer writing testable frontend code, and Svelte 5 is revolutionary in that way. It is as good as unit testing, but reactive in the browser.
Having said all this, the blog post rings true. Adding proxies feels very uncomfortable. React and Vue lost me when they started adding abstractions on top of abstractions and proxies were the gateway drugs.
> ...when I could create a reactive external component that I can import into a .svelte template...That means you can write vitest tests against it, but get the benefits of reactivity. That is truly powerful and, AFAIK, unique in the frontend world.
Isn't this the same as Vue composables?Composable: https://github.com/CharlieDigital/vue3-state-definemodel/blo...
Vue Component: https://github.com/CharlieDigital/vue3-state-definemodel/blo...
BTW, I agree it's a very good pattern in general; especially good if you end up reusing logic with different templates/UI.
I got disillusioned around Vue 2. When they had proxies in front of class attributes that looked like functions, it really made it hard to instrument inside of tests. Maybe this is fixed now. But, it left a bad taste in my mouth.
Here's an example of a Vue composable for the clipboard: https://github.com/vueuse/vueuse/blob/main/packages/core/use...
Here is an example of how it's used: https://github.com/vueuse/vueuse/blob/main/packages/core/use...
And the unit tests: https://github.com/vueuse/vueuse/blob/main/packages/core/use...
Another one from the same lib: https://github.com/vueuse/vueuse/blob/main/packages/core/use...
Unit test: https://github.com/vueuse/vueuse/blob/main/packages/core/use...
I'm pretty certain that Svelte took inspiration from Vue composables and I'd also guess that the community will have a bit of friction before people start to get its use cases (same as it was with Vue when it was introduced).
A good example in Vue is the top example in this page: https://test-utils.vuejs.org/guide/advanced/reusability-comp... The other examples show some other things you can do if you want, although I'd typically recommend against it - keep your signal-related code free of component/lifecycle-related logic, and it will almost always be much easier to test.
(As an aside, I'd add Angular to the list of frameworks that are easy to test, although the framework feels like it goes out of its way to convince you of the opposite. Services are just classes that maintain reactive data - originally via RxJS/Observables, although now signals are also supported - and if you keep them like that, they're fairly easy to test. Unfortunately, Angular's decorators/DI/module system is very pervasive, and at least when I was last using it, meant that even theoretically simple tests still needed lots of boilerplate. But theoretically, it belongs in the same category as the frameworks above.)
> ...the magic ingredient in all these frameworks is signals, which allow you to have reactive data without having to have a UI framework to provide lifecycle events
This is something that I think a lot of devs don't fully appreciate. A recent writeup on the inverted reactivity model of React: https://chrlschn.dev/blog/2025/01/the-inverted-reactivity-mo...And short video walkthrough: https://youtu.be/7OhyP8H7KW0
I'm not a Svelte dev, so I don't really follow the distinction you're drawing. What is it that supposedly makes Svelte more testable?
When I look at this example it does not look like the code I would be using inside my webapp. I have a rule of thumb: my test code should look the same as the code when it is inside my app.
https://testing-library.com/docs/react-testing-library/examp...
My Svelte 5 runes test code uses the code in exactly the same way that I use it inside my .svelte templates. That's very different in my opinion.
Personally, I think it's a PITA since it's pretty rare that copy (such as text labels) ever remains stable for very long, or are sufficiently unique on the page, so I do the "strongly discouraged" route of using data-testid attributes for everything (which also has the side effect of making people who write e2e tests happy, but I digress).
With all of that said, I find myself rather appreciating the approach. I don't need tests to mirror the implementation, only the interface.
In the Full Example linked, the only code that it makes sense to talk about being in the app itself is the code to render the component, and that does look precisely the same.
The rest is the testing logic - inspecting the state of the DOM post-render, interacting with components by simulating events, and so on. I don't see how this could correspond to anything in the app proper.
That said it's very very easy to write similar looking code using react testing library as long as you're good about separating business logic into a hook. Where it gets dicy & hard to test is when components have complex state/effects co-mingling with render logic.
Business logic is very easily testable as a hook, something like:
``` it('toggles switch state', () => { const {current} = renderHook(() => useSwitchState);
expect(current.checked).toBe(false);
current.toggle();
expect(current.state).toBe(nextState);
}
```Render logic is a bit different because React Testing Library's philosophy is to test as a user would interact with the UI, so that looks more like:
``` it('switches state on button click', () => { render(<Switch onToggle={mockOnToggle} checked={false} />);
getByRole('switch').click();
expect(mockOnToggle).toHaveBeenCalled();
});
```In the js world you're shooting yourself in the foot by choosing a framework that is as locked in as svelte (no vdom,domain-specific-language and their design philosophy), had to find this out the hard way.
I still respect svelte for it's engineering capability, but it's a 100% commitment with no off-road options ever, but if you need a framework for js and don't like react or angular then vue would be my choice.
Or is this about something else?
Also, it's a things metaframeworks enable (Like Astro)
I don’t even think it would be possible to "move to a new framework" without starting from near scratch.
Out of curiosity, could you elaborate on this a little?
Here's a discussion on it, with the first post from Rich Harris himself with some reasoning: https://news.ycombinator.com/item?id=35891259
I am confused about this because on the one hand, you seem to be hinting at my favorite, under-hyped aspect of testing, which is its use (via TDD) as a controlled-state print/debugger, but on the other you seem to be eliding the most popular--albeit, in my view, less important aspect (insofar as one aims for "working software over comprehensive documentation"[0])--the preservation of behavior across commits and into the future.
What am I missing?
Edit: re "reactive in the browser," that's how I run @benchristel/taste[1]
Right now I am working on a legacy project with ~10 years of work into it, about 15% of the code in there I don't even know how to trigger in the application (lots of weird specific circumstances that require special types of accounts to trigger). I just had to make a small change to hundreds of files and it was hell to manually test it everywhere.
IMO almost all components should be able to be renderable in isolation and mocked data. Type systems help with this problem because they remove a whole layer of tests required, but it is not enough.
There are two major ways I think it's reasonable to do frontend/web:
1. Static HTML or server rednered templates with maybe HTMX .
2. Compile-to-JavaScript languages/platforms. At a minimum TypeScript but given that I think HTML and CSS are actually pretty good (for many things), JSX, React, Tailwind, etc, are right out, and Svelte 5 along with a few other frameworks actually improve things over vanilla TypeScript in my opinion.
So much so that Svelte 5 is the clear winner in category 2 for me.
It has nice HTML templating, easy and sane state propagation, and features that make it easy to write modular code. It works great with CSS and you can often build simple throwaway apps and tools in one or two files, as well as bigger, more serious applications. It's less magical and surprising that Svelte 4, and honestly a joy to use. Luckily I don't care about IndexedDB.
I have no clue why anyone would choose to write a single line of JavaScript in this day and age, but each to their own.
I would opt for better debugger tooling specifically for Svelte than strip away the abstractions. Its the lack of a runtime managing a virtual DOM that makes it unique and performant, and frameworks like React also essentially have their own compilation step that obfuscates code. Source maps won't help much by itself; the React debugger is where you have a better view on your components and how things are wired up.
TypeScript is a better scripting language than JavaScript, Svelte is a better language/model/platform than HTML+TypeScript.
React may be your cup of tea but I’d rather write Svelte templates every day! Not to mention per-component styles.
Sure, a component inspector devtool would be neat, though. Nobody’s going to complain about better tooling :)
You should already have a clue, you have to write a lot of JavaScript in order to get Svelte doing what you'd expect outside of very simple components. See these actions as an example, and check out the JS file! https://svelte.dev/tutorial/svelte/actions
Svelte makes more sense if you enjoy the JavaScriptisms. In which it provides enough "magic" for most things, but still lets you enjoy JavaScript.
What initially drew me to SvelteKit was its simplicity. After setting up the project, I could work on one HTML/JS/CSS file at a time, leveraging the benefits of a modern framework without the accompanying complexity. This approach reminded me of the early days of web development, where dropping HTML files into an Apache server was all it took to get things running.
However, it's disheartening to see Svelte shifting away from that straightforward paradigm. From the outset, Rich Harris positioned Svelte's ease of use and simplicity as its key selling points. The current version of SvelteKit isn't bad per se, but I found myself preferring the earlier iterations. Back then, I didn't have to deal with constructs like `+page` for routing. I could place Svelte files wherever I wanted, and they would render seamlessly, all while enjoying the advantages of a modern framework.
This change adds layers of complexity that weren't necessary before, potentially moving away from what made Svelte appealing in the first place. I picked it up because I already knew what I needed to know.
Astro + Svelte seems nice enough if you need it but for most of what I do, plain Svelte 5 is great.
Sadly the Ember team made some strange decisions in the beginning and it wasn't easily grokable compared to regular JavaScript (most of that has been fixed now, though).
This is all to say that whether or not it's JavaScript doesn't really matter, compared to the stability of the API.
My personal problem with JavaScript is that things keep changing too much.
And any book older than that is useless due to class syntax or predating hooks. Just 3 years to turn a resource into a door stop.
In that time, the knockout parts have kept going strong. The react parts have seen three different paradigms ( React classes, Functional react with redux, React Hooks ) and still hasn't fully settled down given there's also churn in the CSS-in-JS space.
The very occassional time something in the remaining knockout parts need fixing, it's just a harsh reminder that it worked fine.
I'm fairly sure the react portion is still not even on the very latest version of react because some other dependencies are stuck on older versions and they themselves have breaking "API changes" (i.e. complete rewrites with no semblance to the original ).
As someone here also said, maintainers in the JS/TS ecosystem appear to have no respect for their users.
It might sound entitled, but sometimes not completely rewriting your framework's API to a completely incompatible one is a better choice. Even if that means putting up with a slightly worse API than you'd like.
I guess everyone moves so fast that there's a fear that sticking on the old API would just lead to dying off at the hands of a new upstart with a smoother API.
But the alternative is a constant abandonment of projects. If a major version change requires a complete re-write then really the new version is a new project entirely that's re-using the namespace and maintainership.
But perhaps emberJS fell away precisely because it didn't rewrite itself to stay "modern". Maybe this is a "worse is better" situation where the world optimises for the wrong things.
"Has had a mostly stable API for a decade" just isn't something people select for. If it were, then things like ASP.NET would be far more popular.
Meanwhile they've deprecated parts of the class components.
- https://github.com/krausest/js-framework-benchmark/pull/1835... - https://github.com/NullVoxPopuli/markdown-table-viewer - https://github.com/NullVoxPopuli/package-majors (older, needs update, which i can do pretty quickly if i remember to do it)
JavaScript itself barely changes - it's the flavor-of-the-month frontend frameworks that do. What language feature is commonly used now that wasn't 5 years ago? Some nicer builtin Array methods I guess?
There's a lot of dislike on here for Typescript as a backend language. But the difference with the frontend world with its dozen everchanging frameworks is striking. On the backend side, most projects don't even use a framework, and for those that do basically all of them use the same one (NestJS). And the rate of breaking changes on that has been much lower than something like React.
Of course, many will say that this lack of industry-wide adopted framework in itself is what they dislike about it. But it's hard to settle on that golden mean inbetween both extremes when it's the most popular language in the world (in terms of "Yearly new LOC going into production"). Python makes for a good contrast, with a dozen popularish backend frameworks. Not sure if that's really a better situation to be in, there's pros and cons.
The javascript language itself hasn't really had a breaking change of note that I can remember in the last 15 years? It's just expanded its API from years and years of browser implementations trying stuff and trying to get to an actual standard. HTML5/ES6/CSS3 brought a new kind of baseline sanity to the whole thing. That's not to say it's a perfect language without quirks, but to say it keeps changing is just not even accurate at all.
python has version evolution, C++ has version evolution, they kinda all do...
This isn't true.
ComponentWillMount and related methods were deprecated and then removed.
Yes, they allowed an escape hatch of UNSAFE_ComponentWillMount etc, but that still requires work to make it compatible, so it definitely doesn't "[work] perfectly well".
On the app development side, we dealt with 3 major overhauls of PrimeNG's style system before we decided to invest in a custom library just to eliminate the risk of future upgrades. It took us 6 months to migrate our Angular 9 app to 18 because of the PrimeNG dependency. Granted, it's a massive application and they didn't maintain it properly, but I'd hardly call Angular stable regardless.
And then you have the Vue composition API, which was a major shift from Vue 2.
This isn't to say that React has been perfect. Depending on your stack, there are certainly a fair degree of breaking changes (looking at you, Next.js and react router). But that is far from abnormal in the JS world.
I take it you didn’t have to deal with porting an AngularJS app to some other framework, like Angular 2.
At my company I mentioned using it in passing to our cto as we were discussing a project to move our core web app from angular to react, and he laughed saying "maybe if this was 10 years ago!".
Sorry there was hostility when you were around. We try hard to keep hostility out and keep everyone civil now a days
Yeah.
Last year I realized in my 10 or so years using Node I've changed my stack so many times (Express, Hapi, Fastify, Hono, Sequelize, Objection, Prisma, Drizzle, Mongo, Fauna, Postgres, Firebase, etc etc). So much time wasted.
Surprisingly, on the frontend I've found stability with Svelte. I've been using for 4-5 years now and still very happy with. I also love runes.
I've been a fan of Svelte since version 2 or 3 because it was the closest I could get to writing vanilla HTML/CSS/JS, whilst also enjoying the benefits of a framework (and then using Sass and TypeScript). Fantastic.
Svelte 5 made me feel uneasy because runes are weird. After upgrading a project with it and working on another project, it's not so bad. I like that Svelte 5 disallows you from mixing the old and new ways of handling state and the error messages are mostly informative.
I see people in these comments talking about htmx and vanilla JS being objectively better and...no? For what YOU do, sure. Personally, Svelte is still a lot simpler to grok than React and for the people that care about benchmarks, Svelte is just as fast as SolidJS (I feel like the React crowd could pretty easily switch to Solid, the syntax feels similar).
That should shed more light on my problem, which is not just due to proxies, but is also a result of props being getters under the hood.
[0] https://jcuenod.github.io/bibletech/2025/02/16/beyond-typesc...
A couple of things that I found really annoying: all pages being named `+page.server.ts` or `+page.svelte` or a variation of that makes it hard to easily search for code. The tooling for Svelte is also separate from `tsc` and ESLint, making it tricker to both integrate into CI and use in dev.
And then there's just weird incompatibility stuff with the previous version. For instance, most Svelte packages still use stores, like SuperForms, so you have to contend with two versions of the world, making writing code really confusing at times. Plus, Svelte HMR is still kinda early AFAICT, so it will clobber your state when a Svelte module reloads.
I _really_ want to like Svelte. It's significantly faster to render and I like the ideas behind it. But React's productivity is unmatched.
I'm React developer since 2015 and working on side with svelte+sveltekit for the last 3 years. For me it's exactly the opposite. React was huge upgrade from Angular 1 and jQuery development before, but everything goes so much more quickly together with Svelte. I understand that there is no one-size-fits-all for UI frameworks, and we have different thought-processes for lack of a better word, but saying React's productivity is unmatched, is very much untrue.
For deep reactivity, we have add-on packages for signals, and we're aiming towards integration with the upcoming Signals TC39 proposal: https://lit.dev/blog/2024-10-08-signals/
Lit's used by pretty major apps like Photoshop, Reddit, Home Assistant, and The Internet Archive.
I really wanted that framework to take off.
But that community is straight toxic... I have not seen a more toxic community than the React Router community. It's one of the reasons I stopped using Remix. React Router 7 is actually pretty cool; I recently built a prototype on it and was surprised by how well it worked. But I know I'll eventually need some kind of support and feedback, and I can't imagine engaging with those devs/that community again...
The key trick is that its "observables" (similar to Solid Stores or Svelte runes) aren't mixed with the actual data, and instead are sort of pointers to the data. This makes it very clear when you're passing reactive observables around, and when you just have vanilla data. There's never confusion about whether a particular property access is properly tracked or not. There's never that feeling that it "is not JavaScript".
It works well with React but is fundamentally framework-independent. We moved to it after trying SolidJS (which Svelte 5 is strongly influenced by) and we haven't looked back. IMO it deserves a lot more mindshare than it currently has.
JS frameworks for some reason or other are a madness.
Best thing I did in many years for that project.
I _like_ building things with React.
If you have a nice codebase with good separation of concerns (that everybody adheres to) and reasonable library choices, you'll be happy regardless of what framework you're using.
I prefer solid
const state = new Proxy(
{},
{
set(target, property, value) {
target[property] = value;
renderUpdate();
return true;
},
}
);
I'm only 1/4(.0000000004) serious here. That said, I've been doing this for almost 30 years, I was a kid when I picked up Netscape, I have gone through every mainstream and many niche libraries/languages replacing libraries. Now, in my late 30s I finally can grow a moustache (a big achievement in my family gene pool) but the analysis paralysis is still making me anxious every time I pick up a new project.- preact w. signals or Svelte are still my libraries of choice if I need to spike something, but that's partially because of signals and vite. The development experience is good, there isn't much magic you need to deal with on a daily basis.
- Web Components are great in many ways, but they don't solve the problems I usually have with bigger projects (scaling state, orchestration for the lack of a better phrase). Lit makes it a bit better though.
- JSX is actually not that bad, as long as you treat it as a DSL around functional composition. Native JSX + signals would probably make most of my node_modules redundant.
(please don't overthink this, I didn't)
Agree that JSX is great (but styles like in Svelte also).
Oh yeah, 100%. One of the reasons I like Svelte are colocated CSS modules.
> seems like frameworks are somewhat converging now on this app router concept.
That for sure, and signals in one way or another. It took us 10+ years, Solid.js then preact to bring back a pattern from 2010s (IIRC) implemented in Knockout.js.
People are talking about declarative signals in HTML. I don't have a formed opinion about them yet.
By that I mean saying everything has to be a JS framework or everything has to be server-delivered-HTML.
For very dynamic & interactive things maybe it makes sense to write it just in JS without a framework?
For full pages for data-powered applications (that heavily benefit from types & Typescript), maybe it makes sense to use something like Golang on the server.
And then you can embed those interactive dynamic islands inside the data-intensive application, with a thin layer of communication between the two.
Just my 2c - I've found that pattern to be super compelling
I know hating on frontend dev is trendy, and I guess blazor is the logical end to that aversion to actually using frontend tools, but if anything it's the perfect example to show how much worse web dev would be without JavaScript frameworks. There's a reason it's only used for internal tools.
I'd take any react+JavaScript "bloated" websites over this. Especially on mobile. https://bootstrap5demo.blazorise.com/
I appreciate Svelte's new architecture, it's going to help people make smaller, faster apps, even it requires you to learn about how it's reactive system works.
Was a huge React enthusiast, even wrote a book on it.
But with version 5, Svelte got really interesting. Runes really feel like a breath of fresh air.
Which means, that anywhere I render those components I have to suffix the file as .svelte.ts Or switch to svelte/store but it's quite dumb to wrap everything as a Writable<T>
I still like Svelte regardless, but I just thought "why" as over-abstraction wasn't the original tenets of Svelte
As much as I love Svelte this worries me. Vercel is pretty invested into React and Next and who knows how long they'll be funding the project.
The only issue we have is JS UI libraries we depend on who have a funny understanding of backwards compatibility.
Meanwhile, the abstractions ARE leaky, and I NEED to and SHOULD understand the underlying UNIX filesystem because it IS different from the Windows filesystem. Should know the inner workings of my PostgreSQL RDBMS rather than relying only on hibernate. And so on.
Last but not least, I just realised that it is impossible to write code in an unknown-to-me framework using LLM, because sooner or later I will need to fix the problems that arise exactly by going deeper into the inner workings.
I work on frontend right now, but I've worked on backend earlier, as well as gamedev and desktop applications. And it was always like that in every area: when your major dependency has a major version upgrade, you will have to spend effort on migrating your code to support it.
Security support lifetimes make sense for a widely used language or runtime, but not really a frontend web framework on the most backwards compatible language you can have.
Those aren't the things most developers complain about. Most front end developers spend their energy on concerns of code style, tools, build steps, framework madness, state management, and more. Those are fashion concerns. A decent programmer can solve for most of those themselves without external tooling in a fraction of the time and code size, but not everybody that does this work is confident writing original code.
The paradox works like this: If you were capable of writing your own software the triviality of state management becomes self evident. If you are not capable of writing your own software, such as full eternal reliance on some tool set or framework, then the answer doesn't matter.
That’s because most SPAs are duplicating backend logic.
If we kill REST, a lot of the complexity around frontends would be reduced significantly. You don't even need GraphQL or RPC protocols to do that.
I didn't say that it was specifically. REST is still a convention that is usually tied to and influenced by HTTP and its methods. It doesn't necessarily have to be that way exactly, but that's how many web applications are typically written.
> There’s no need to “kill” it.
We don't necessarily need it around either.
> If you’re sure you need another set of verbs and nouns, use http as a tunnel.
That is somewhat along the lines of what I'm suggesting. REST is not necessarily better than an API that just takes POST requests in a way that serves the application's needs directly rather than some abstract standard that homogenizes data in ways that require extra work to be done. For some odd reason, many frontend-oriented developers look at me like I've got bugs crawling out of my ears when I say this, yet the idea of allowing the server to do the bulk of the work is both old and resurging in popularity (e.g. Hotwire, LiveView, HTMX).
However, I think frontend is often quite underrated in its essential complexity. I don't share the opinion that state management is a fashion, it's often tightly intertwined with the UX requirements, which can be varied and have all kinds of difficult essential complexity of their own (often complexity that is under-specified, and up to the programmer to discover).
The lack of experience of many frontend devs, combined with the limitations of dynamically typed Javascript, is a recipe for a lot of very gnarly code. Maybe it would be fair to say that this is self-inflicted, but I am sympathetic. It's quite a difficult problem.
When I think of 'total own-goal', completely pointless self-inflicted hell, I think of Python package management.
Do you know why there are new frameworks, new versions every time? Because web is a moving target. New js/css/html5 features are released every day and the libraries have to update to adopt them.
Back in the day you do not have css variables, so you have either use sass and do all the math inside the preprocessing process, or crazier, using those shitty css-in-js libraries to calculate css properties on the fly. Nowadays you can pass around the variables and it can cover almost all the case. In able to pass the css property to the component, you need to improve your framework.
Another example is html5 history API, back in the old days people implemented link components in SPA with buttons (hilarious but it happened), only after History API is introduced there raised the need to manipulate the history properly, thus another rewrite issued.
before that, ES5 introduced `class`, proving yet another way to write js code, which in some situation make cleaner code than the plain old js functions.
everything in the web is moving, new nice things are introduced every month, if you want to create a modern and performant web application, you need to keep up with the new fancy things, frameworks are no exception for that.
[1]: https://docs.sqlalchemy.org/en/20/changelog/migration_20.htm...
> They seem to have no respect for peoples time or any consideration for longtermism or even just the common decency of backwards compatibility
You mean Svelte 5, the backwards compatible framework that makes all of its new features an optional opt-in? That one?
> What are we at now, React 19?
Allow me to introduce you to the concept of semantic versioning, otherwise known as “a versioning system that has defined meaning”. Any breaking change means a new major version, which is why the numbers increment at a rate that is apparently terrifying. These breaking changes are often absolutely tiny and trivial to adapt to.
I don’t even like React but the upgrade path between major versions is rarely a big deal. You’re taking a non-semantic versioning mindset (new version number? Guess I have to rewrite everything!!) and applying it in a scenario where it doesn’t fit.
There's much bigger topics afoot in the world that also make me think humanity desperately needs better tools to defend & equip ourselves with broadscale collaborative efforts to shut down & reject-by-default negative-valence posts.
The hater-squad has the easiest job on the planet attracting some fellow people who also want to resist learning, change, or who want to feel more secure in their current position. The Dark Side is strong.
Inevitably we will see it in every front-end related thread until the end of time.
This is absolutely untrue. There's a huge gap in how easy it is to upgrade some stacks vs. others.
Updating dependencies in a language with strong, static types and/or an expressive type system is incredibly easy, for example:
Step 1: update dependencies
Step 2: fix compiler errors
Upgrading major versions of .NET, for example, sometimes requires no work at all.
This is not true in JavaScript, Python, and some other languages where you're only going to discover issues during runtime.
TypeScript makes things a lot better, but you're relying on the authors of your dependencies either using TypeScript or keeping types up to date.
I love types and advocate their use whenever possible. They help a lot but they are a spectrum. Thanks to static analysis tools like TypeScript or even eslint you can get a bit towards automated checks on front end code. Also even compiled languages can miss some things, different languages have type systems that give you different kinds of guarantees. For example, Java has NPEs that can't be caught at compile time.
This I can agree with.
> Updating dependencies in a language with strong, static types and/or an expressive type system is incredibly easy
Java would typically be regarded a pretty close to .NET in regards to its type system, yet I've seen plenty of issues with updating dependencies, whenever you have any sort of dynamic class loading or reflection going on: be it Lombok or MapStruct not liking a specific version of Java, or Spring Boot or one of its many integrations throwing errors during startup after a successful compile, sometimes even disliking specific annotations that worked previously.
A decent type system will help you make sure that the code compiles, sure (and I'm thankful for that), but with some styles of writing code and handling, for example, dependency injection, all bets are off. The same goes for any dependencies that make liberal use of those features. I'd have to dig around for specific examples, but I know for a fact that there are plenty of projects that are stuck on old versions of Spring for that very reason.
Or the fact that there are plenty of pre-.NET Core projects out there that won't be upgraded to anything new anytime soon for similar reasons.
In my experience, updates suck across the board, the only variable is how much. And that applies to everything not just dependencies in code (and runtimes): I've also had seemingly innocuous Debian updates break GRUB and prevent the OS from booting, or even upgrades making exim4 start up for some reason and taking up the port that my mail server needed, preventing it from starting.
Next time I'll tell you how people used to update their code to use Python 3! Shocky-shocky.
To give you a simple example.
"What's the best web framework these days for fullstack JS work?"
Ok, Hono, found that. Installed it, great, it even runs well with Bun. Holy shit, it seems like JS is catching up! But now how do I talk to my database? Hono has no such thing, you're on your own.
Ok, let's use Prisma but setting that up there is no one-true-way, it's all blog posts and praying you followed the right one. Also Prisma seems to now work with joins?
Migrations? You set that up manually.
Deploying is another story.
Very painful.
---
Compare to Laravel, Rails or Phoenix. All these things baked in, one blessed paved road to tackle the common things 99.9% of web apps need. We are blessed to have all this great work for free, right at our fingertips. People donated a lot of time and love into building them. I hope javascript one day reaches that level.
It's still cowboyitis out there.
Weird that you went with some framework I've never heard of, and that definitely does not come up when I google for best fullstack JS framework.
> Ok, let's use Prisma but setting that up there is no one-true-way
Maybe the docs? https://www.prisma.io/docs/getting-started
> Deploying is another story.
I mean deployment always brings some complexity, but for the majority of JS frameworks you can get started by building it, throwing it in a docker container, and hosting that somewhere. I don't see what's difficult about that
I've been sitting here as a react developer, quite stagnent in my toolset, using the same React I've been writing since 2015. The 'newest' technology I picked up was Typescript back in 2019.
For what it's worth, between 2011 and 2016, React shipped versions 0.0.1 to 0.14.0. Then in 2016 they said "fuck it, we're stable now" and jumped immediately to 15.0.0 (they considered 0.14.0 to be mostly equal to 14.0.0).
Then they did 16 in 2017, 17 in 2020, 18 in 2022, and 19 finally in Dec 2024. I don't think 4 major versions in ~9 years is a world breaking amount of churn. I have my problems with the team's development of React, but I think they have a pretty sensible view of breaking changes and limiting churn.
Also StimulusJS and htmx are good for simple cases as long as you don't need a global state IMHO.
The take about AI is also interesting, I didn't think about that before. If AI is now able to generate a lot of code, maybe being able to quickly understand that code is more important than that code being clever.
Whatever version of svelte you use will be dead and abandoned soon, so if you have any hope for a long-lived project, you're jumping on the update treadmill, where the value proposition is 100% backwards...
If your project fails, then great, no problem!
If it succeeds you'll have to spend a proportion of your time upgrading.
Worst case scenario is your project succeeds and grows. The time you spend upgrading grows in proportion with how much you use it. And in complex projects you tend to get these spikes of exponential upgrade work, which outright blocks your progress.
No thanks.
(Of course, this isn't restricted to svelte. React and all the crap you have to use with it are even worse.)
If you like template like syntax and single file components the. Vue provides the same benefits, with a bigger ecosystem and better team behind it (non vercel backed, that’s a big advantage).
If you prefer JSX, performance, simplicity and integration with vanilla js then why not use Solid instead?
I’ve used svelte for a medium size project and ended up regretting it. (For the above reasons).
Svelte 4 felt awesome because it felt like I was just writing an HTML file, sure there was some magic ($:) but for the most part things were simple, easy to understand, and it all just worked. Runes totally changed that, maybe for the better because of all of the things previously cited, but not for my personal experience. I'll stop there because I'm 100% covering already-treaded ground.
I'm "joining the dark side" by trying the HTMX & Golang combo, just to see if I can hack together an on-par DX (which is going to be a herculean task, I know).
> Don't choose tools that alienate you from your work. Choose tools that leverage the wisdom you've already accumulated, and which help you to cultivate a deeper understanding of the discipline.
We're now using Solid for another project, and so far we're very happy with it.
The one thing that has really caught our eye - and I feel is the real breakthrough these days - is the new generation of SSR/RPC-style frameworks like Solid Start, SvelteKit (I'm assuming?), TanStack Start, and of course Next.js and React Server Components (oh and React Router 7 née Remmix ¯\_(ツ)_/¯). Being able to code in 'server module space' and have data available in advance of the render cycle, without having to write a separate API layer - is great. For example, we can - if we chose to, write a Next.js application as an all dynamic app (no statically generated or cached pages) and treat it pretty much as we would a PHP application that renders a template on initial renders. The only remaining hill to climb is the performance of the initial render in SSR as this is catastrophically slow in React (we implement short TTL Level 1 caches in Nginx so that we can survive scaling a response to any 'popular' dynamic pages in our applications). I've heard (but not tested) that Solid's SSR life cycle is better in this respect. We can do the same in Astro 'server' mode. We've not yet looked at SvelteKit.
As for the rest, I agree that this quote nails it: "Don't choose tools that alienate you from your work. Choose tools that leverage the wisdom you've already accumulated and help you to cultivate a deeper understanding of the discipline.". For us this translates into CSS and CSS Modules as our style system, as we watched - mortified, as an entire CSS-in-JS ecosystem (ala Styled components, Motion.js) was basically told to get stuffed when the shift to SSR/RPC and streamed responses occurred. We narrowly dodged that bullet. It also means casting a very cautious eye over Tailwind CSS (ignoring how it can be abused, and arguably encourages duplication and bad practices in component reuse), as the recent Tailwind 4 release demonstrated by the manner in which guidance on migration was published for first-party plugins like Typography.
I love the web - despite the complexity. And I agreed whole hardheartedly with statements from people like Rich Harris when he says the web is ours to nurture and protect [paraphrased].
“Svelte is not JavaScript” is spot on.
The `Proxy`-based state management API is a perfect example of this. The intention was to make working with mutable state like arrays feel better, but it creates this layer of added complexity under the hood with non-trivial performance and functionality implications (like the IndexedDB sync issue the author ran into).
Compared to the `let x = 1` paradigm from before, we now have three different Runes for state (`$state`, `$state.raw`, and `$state.snapshot`) which you need to choose and understand the differences between. The added nuance to the way `$effect` works which is detailed in the post is in the same vein.
Another issue is that stores are pretty much deprecated. I love stores because of their simplicity all the way through; you could click "go to source definition" on a `writable()` call in your text editor and read through the simple implementation in the Svelte source code. [1] You could confidently create custom stores that integrated seamlessly into Svelte's reactivity system all using plain JS; you just had to match the expected API.
With hooks, that transparency is greatly reduced and all of the magic happens invisibly under the hood in the compiler. In `.svelte` files this was totally fine since it was operating within the Svelte model. But now, any random assignment to `self.foo` in a class might actually be to a reactive `$state` rune which could cause UI components to re-render elsewhere.
Besides that, there are bugs when using both stores and Runes (some of which I've reported on Github [2]). Stores and Runes have slightly different reactivity models which aren't quite compatible. The response was basically a wontfix, so the expectation is that if you upgrade you go all the way.
----
I will say that I'm still a fan of Svelte and will probably keep using it as my favored UI framework despite my feelings about Svelte 5. And from other discussions I've seen on places like the Svelte subreddit, it seems that there are big parts of the community which are very happy about these changes.
Maybe what some people are saying is true and that this added complexity is needed as a framework like Svelte matures in order for it to find adoption with larger teams and organizations.
[1] https://github.com/sveltejs/svelte/blob/98734433376e99909fb6...
The Svelte API shouldn't have changed, IMO. If you want what Runes do, then why not use React? Svelte will probably look like React in a few years, and maybe even like Backbone after that.
rxjs/reactive like, stores subscriptions, ah that's nice.
But i was disappointed about svelte v5, because it changed paradigm. runes force you to change your mind and it is no more rxjs, it is class-based enterprise angular-js. New version added a lot of new things, but they are not described well.
I also hate some things like your class fields that have state are undefined by design and you need to do cast or null-check every time. Also your getter can't return derived, it should be class field, meh.
Ah, also I HATE how they force SvelteKit. Guys, hello, I need just plain svelte, why do your starter template creates for me non-ssr sveltekit project? Do you really think that I'll choose this new sapper?
====
But, svelte is the only non-runtime framework that is trending and has big community. Hope Rich will do better new versions :)
Jesus Christ, I didn't know how bad Javascript devs had it. I'm so sorry.
var foo = "something"
foo = "something else" -> ui updates
to:
$state('hello')
Runes and other nonsense immediately made me turn off Svelte.
Even Vue sort of moved away and started looking like React.
I think there is an opportunity now for another new framework which goes back to simplicity which Vue and Svelte tried to do.
Mithril really was as close to perfection as one can get.
Anyway, if you don't want it like that you can continue to use the old system.
Svelte 4 is simple in a single component. Svelte 5 needs a bit more boilerplate.
Svelte 4 was always very confusing in multi component/files workflows, especially when working with .ts/.js files. Svelte 5 is way better in this regard.
I'd pay the "slightly more boilerplate" price every day.
Did it? Vue has composables that look kinda like react hooks syntaxically, but aren't the same thing at all, they are just better scoped mixins.
Without svelte 4 compatibility, you can just replace `$state` with `$`, `$derived` with `$$` or even some simpler mechanisms. Heck, I have vague intuition that we can reuse the `$: ` statements someway too, and still keep the new deep reactivity feature.
Might be svelte 6 will give us the proper answer. Or some newer fancy framework will take the hint and do it sooner.
The way the compatibility works is by seemingly identifying the file and either treating it in legacy mode or runes mode. I don't think what you are suggesting would have blocked them from doing what they are doing now.
At the very least the conversion between the versions will be very messy and error prones, especially using the migration tools.
Not to mention the designs of runes was still unstable back then. Heck even now it is still very awkward to use runes with sveltekit. You need $state and $effect everywhere for the page data.
Every single industrial scale project I saw was inevitably breaking apart on seams.
My components do as little as possible other than render html and bind the occasional event handler to a store function. With this in place, development scales much more easily than layers of hooks.