You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It's working fine in Svelte 4. I'm currently trying out the library in Svelte 5 and found my use case doesn't work.
I got an empty table with the same code. I suspect it cannot keep track of the initial element binding of the scroll element, because it works if I manually make a mounted state and call $virtualizer._willUpdate().
I've made a minimal reproduction repo.
Please note that we have to manually run npm i --force && npm run dev before #863 is merged.
With the hack from L19-L27, it seems to work. However, when I commented out it, I got an empty table.
I suspect it cannot keep track of the initial element binding of the scroll element?
Expected behavior
I hope we can get rid of the manual mounting/element binding check and call of $virtualizer._willUpdate().
How often does this bug happen?
None
Screenshots or Videos
No response
Platform
macOS, Arc browser Version 1.65.0 (54911)
Chromium Engine Version 130.0.6723.59
tanstack-virtual version
3.10.8
TypeScript version
No response
Additional context
No response
Terms & Code of Conduct
I agree to follow this project's Code of Conduct
I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.
It's literally just a clone of the index.ts from @tanstack/virtual-solid using svelte runes. Note: in svelte the file should be called index.svelte.ts for this to work.
Reacted by Luis Fontes, Daniel, Fedor Nezhivoi, enchart, Coinhexa, 파링, aaronjbecker, Ricardo Christmann, Arne Wiese, Tomasz Kasperczyk and 2 more
Reacted by aaronjbecker, Arne Wiese and Sikandar Bhide
Svelte 5 was released some time ago, do you think we can get an update to support it? Do you have any internal discussions in the team regarding this? Would be highly appreciated!
Reacted by Coinhexa, Fredrik Stock (Eltele as), Jerric Lyns John, Arne Wiese, Sean Knowles, Sikandar Bhide, Peter, enchart, Baratyants Karen and karosmiy
@jithujoshyjy tried your method, the list items seem very jumpy when you click on them. Also the scrollbar keeps going to 0 every time you click show more
@slidenerd I have the same issue, in a another situation. I've an action bound to a row, and the response returns the updated item. When updating the underlying array, it jumps to the top of the table. Did you find a workaround to avoid jumpy table?
@phhoef seems that it has something to do with global state I abandoned this virtual list since i was not getting anywhere with it and started using this Warning though, scroll to index doesnt work as reliably as i expected it to but rest is super solid
@slidenerd thanks for your feedback. Do you use the virtual list with tanstack-table or just a normal list? Would you mind sharing a code example how you use it with tanstack table?
For lists I am using virtua.
@phhoef i dont need a table in my application at all so I just need a virtual list. Given the state of this library, I am not using tanstack anything at the moment. As mentioned above, I independently found a virtual list whose scroll to index with smooth behavior is broken. The problem with virtua is that it does not persist scroll positions between routes. Keep in mind with virtua that this is a MAJOR ISSUE
I looked into this again, and now I believe the issue is related to how reactivity works in Svelte 5 with runes.
In the original code, when I added console.log(virtualListElement) inside getScrollElement callback, it always logged null just once. I was expecting it to log again with the actual HTMLElement, but that never happened.
It seems like the reactivity mechanism can't track virtualListElement properly since it's being accessed inside a function.
I eventually came up with a better workaround: I moved the access into the $derived block so it's read ahead of time. With this approach, it works without needing a mount check or manually calling $virtualizer._willUpdate().
Alternatively, using a factory function also works. The key point is to access virtualListElement at the same level as the $derived block so the reactivity system can track it properly.
Activity
jithujoshyjy commentedon Nov 2, 2024
Here's how I made it work in svelte 5, mimicking the existing @tanstack/virtual-solid package:
It's literally just a clone of the
index.tsfrom@tanstack/virtual-solidusing svelte runes.Note: in svelte the file should be called
index.svelte.tsfor this to work.gyzerok commentedon Dec 23, 2024
Hello @tannerlinsley!
Svelte 5 was released some time ago, do you think we can get an update to support it? Do you have any internal discussions in the team regarding this? Would be highly appreciated!
jerriclynsjohn commentedon Jan 30, 2025
@tannerlinsley looking forward to seeing if there is any upgrade plans to Svelte 5
slidenerd commentedon Feb 6, 2025
Anyone knows how to make this sandbox work on svelte 5? that uses @tanstack/svelte-virtual
slidenerd commentedon Feb 7, 2025
@jithujoshyjy tried your method, the list items seem very jumpy when you click on them. Also the scrollbar keeps going to 0 every time you click show more
Code Sandbox Link showing the problem
+layout.sveltephosmium commentedon Feb 19, 2025
Yea, tanstack virtual seems very unusable on svelte 5.
https://tanstack.com/virtual/v3/docs/framework/svelte/examples/dynamic Add
setTimeout(() => count++, 2500)and set svelte reactivity on count, you will notice that the virtualizer always scrolls back to 0.lachlancollins commentedon Mar 7, 2025
Hi @jithujoshyjy , would you be interested in submitting a PR with your work?
phhoef commentedon Mar 11, 2025
@slidenerd I have the same issue, in a another situation. I've an action bound to a row, and the response returns the updated item. When updating the underlying array, it jumps to the top of the table. Did you find a workaround to avoid jumpy table?
slidenerd commentedon Mar 11, 2025
@phhoef seems that it has something to do with global state I abandoned this virtual list since i was not getting anywhere with it and started using this Warning though, scroll to index doesnt work as reliably as i expected it to but rest is super solid
phhoef commentedon Mar 11, 2025
@slidenerd thanks for your feedback. Do you use the virtual list with tanstack-table or just a normal list? Would you mind sharing a code example how you use it with tanstack table?
For lists I am using virtua.
slidenerd commentedon Mar 12, 2025
@phhoef i dont need a table in my application at all so I just need a virtual list. Given the state of this library, I am not using tanstack anything at the moment. As mentioned above, I independently found a virtual list whose scroll to index with smooth behavior is broken. The problem with virtua is that it does not persist scroll positions between routes. Keep in mind with virtua that this is a MAJOR ISSUE
vlausargs commentedon May 6, 2025
any updates on this?
noobmaster19 commentedon Jun 1, 2025
anyone working on this?
rebasecase commentedon Jul 12, 2025
Dead project?
rayrw commentedon Jul 20, 2025
I looked into this again, and now I believe the issue is related to how reactivity works in Svelte 5 with runes.
In the original code, when I added
console.log(virtualListElement)insidegetScrollElementcallback, it always loggednulljust once. I was expecting it to log again with the actual HTMLElement, but that never happened.It seems like the reactivity mechanism can't track
virtualListElementproperly since it's being accessed inside a function.I eventually came up with a better workaround: I moved the access into the
$derivedblock so it's read ahead of time. With this approach, it works without needing a mount check or manually calling$virtualizer._willUpdate().let virtualizer = $derived( createVirtualizer<HTMLElement, HTMLTableRowElement>({ count: numbers.length, - getScrollElement: () => virtualListElement, + getScrollElement: virtualListElement ? () => virtualListElement : () => null, estimateSize: () => 24 }) );Alternatively, using a factory function also works. The key point is to access
virtualListElementat the same level as the$derivedblock so the reactivity system can track it properly.I made a PR to my MRE repo to better demonstrate the workaround. The SvelteLab link should now also work directly:
https://www.sveltelab.dev/github.com/rayrw/svelte5-tanstack-virtual
Hope this helps! :)
harryqt commentedon May 18, 2026
Still no support for Svelte 5
rebasecase commentedon Jun 14, 2026
I gave up. Just get claude to reimplement everything in react. When it is slow just say “make it faster” and it does.
No point to this any more 😩
fix: replace @tanstack/svelte-virtual with plain {#each} in ModGrid