From what I understand, Svelte 4 calculated dependencies at compile time. Whereas Svelte 5 does it automatically at runtime based on which values are accessed in tracking contexts (effect / computed value callbacks). This means objects marked as reactive have to be wrapped in proxies to intercept gets / sets. And plain values have to be transformed to objects at compile time. The deps are also recalculated after every update, so accessing state in conditionals can cause funkiness.
But after working with Svelte 5 daily for a few months, I don't think I like the implicitness. For one, reactivity doesn't show up in type signatures. So I have to remember whats reactive and what's not. Another is that making plain values (string, numbers, etc) reactive is really a trap. The reactivity doesn't cross file boundaries so you have to do weird things like exporting a getter / setter instead of the variable.
I agree with all of that. With reactive systems I prefer just making objects deeply reactive and using them as view models, while limiting the amount of derived / computed values. Both Vue and Mobx work well for this.
I've worked through the same process in SolidJS, which had the dynamic dependency tracking from the beginning.
I agree that not seeing reactivity in the type system can be irritating. In theory, you can wrap reactive elements in `Computed` objects (Angular's signals have this, I believe) so you can follow them a bit better, but the problem is that you can still accidentally end up with implicitly reactive values, so it only works as a kind of opt-in "here be reactivity" signal, and you can't guarantee that just because you can't see a `Computed`, that reactivity has been ruled out.
That said, I find I eventually built up a good intuition for where reactivity would be, usually with the logic that functions were reactive and single values weren't, kind of like thunks in other contexts. For me, at least, it feels much simpler to have this implicit tracking, because then I don't need to define dependencies explicitly, but I can generally see them in my code.