143 comments

[ 2.9 ms ] story [ 201 ms ] thread
Create your own Google sheets like Spreadsheet UI in your application using RowsnColumns Spreadsheet 2.

Declaratively render cells, embed external content, use custom formulas, collaborate with other users all using composable ReactJS UI components.

https://www.rowsncolumns.app/

Curious: since you are rendering everything via canvas, how do you do accessibility?
For screen readers, we are planning to add table element with plain text content, with aria regions.

We offer support for keyboard shortcuts and navigation, and our platform is natively compatible with both light and dark modes.

We also provide the option for developers to customise themes, ensuring optimal accessibility for users with low/tunnel vision.

Is it able to handle tables with 1,000,000+ rows?
I think the question can be will a user wants to see 1M rows at a time. Probably no.

Spreadsheet uses virtualisation to display data, ie only data viewable in a Row x Column viewport is displayed. This improves rendering performance.

Data performance can be improved by 1. Lazy loading data or Infinite scrolling. We have a built-in async hook that does this. 2. Only save pointers to data that is being displayed. So if you have 1M rows, on the JavaScript side, you only load 100 rows in memory and when user scrolls, you can replace this rows with new data. This will make the browser happy. 3. Streaming data from the server similar to google sheets.

But to answer your question, we have a Max row limit of 1_048_576 and max column limit of 16_384

I'm checking it out on my phone and scrolling through the interface is pretty choppy, but rather fluid in a Google sheet. Maybe you might be able to further tweak the virtual row rendering?

Props for the fact that when I scroll a bit faster things don't disappear, which I've seen before in SPAs with infinite scroll.

Feels pretty smooth on my iPhone 13.
Could you share which phone you were using? We use virtual rendering at both row and column level.
I'm on a Fairphone 4 with Firefox, but I guess it would be the same on any midrange phone.
Got it. I will try to do some performance testing on midrange phones and mobile firefox. Thanks
The beauty of excel is you can load Million rows and do computations on them.
Excel is probably the wrong tool for that job. At the scale of a million rows or more, this is probably better done by a real database and programming language.
Oh you’re one of those users.

Prepares LART.

I don't understand your comment. It's not far fetched to have millions of rows to handle. I myself have about 12 million rows (notes mainly), although I don't load everything at the same time, so maybe you're referring to that aspect?
It's pushing the boundaries of a spreadsheet's practical usability to be honest. I would not use it for more than a few hundred at most. In fact I just checked my largest sheet is 292 rows. Anything larger goes in anything else! Usually I use SQLite for local storage data like that now.

A funny problem I had a few years back was a company with users keeping 200 meg+ Excels sheet on their desktops. It took them forever to log off every day because the profile was copied back to the server.

How to you get immediate feedback while doing edits/calculations and also collaborate after you stash your data in anything else?
Oh yes, I’m one of those users (and who are “those”? Lizard people?). At least once a week I need to operate datasets that have hundreds of thousands of rows, and while accessing them is not a problem, batch computations can be tricky.
Actually, this is an important comment. Building a spreadsheet with web technology is not that difficult. However, building one with more than just the most basic features, which performs well, once the data grows, is a surprisingly hard task.

To give an example of what makes it so difficult: Some browsers (e.g. Chrome) seem to have special optimizations for rendering tables. So performance-wise it makes a difference if you use table-tr-td-tags or div-tags within your DOM.

Which approach is more optimized in Chrome?
A few weeks ago I found a StackExchange thread where someone had benchmarked the two approaches and found, that table tags were somehow optimized. However, this was tested with identical content and with a table for which every cell had to be rendered. In other scenarios, the performance might be different, but for spreadsheets, this should be applicable. Sadly I can't find the link at the moment (was on a different PC).
It crashed:

    139-d48f98f3a9d41491.js:1 TypeError: Cannot read properties of undefined (reading 'rowCount')
    at nI (561-5e048c82ab8ff4d8.js:5:68277)
    at e (452-22edc4adb41de58f.js:1:1090692)
    at rs (2443530c-0641256dae818679.js:9:38883)
    at lg (2443530c-0641256dae818679.js:9:54218)
Ah. Could you share more on how you got this error, Maybe i should setup sentry.io for the demo.
I got the following:

Application error: a client-side exception has occurred (see the browser console for more information).

And from console:

    139-d48f98f3a9d41491.js:1 TypeError: Cannot destructure property 'sheetId' of 
    '.for' as it is undefined.
        at 561-5e048c82ab8ff4d8.js:5:60688
        at Object.rQ [as useMemo] (2443530c-0641256dae818679.js:9:43805)
        at t.useMemo (139-d48f98f3a9d41491.js:17:7340)
        at nv (561-5e048c82ab8ff4d8.js:5:60642)
        at nI (561-5e048c82ab8ff4d8.js:5:68802)
        at e (452-22edc4adb41de58f.js:1:1090692)
        at rs (2443530c-0641256dae818679.js:9:38883)
    at lg (2443530c-0641256dae818679.js:9:54218)
    at iv (2443530c-0641256dae818679.js:9:112640)
    at oR (2443530c-0641256dae818679.js:9:90032)
Yes, this was also thrown in collaboration mode when user deleted an active sheet of another user. Will need to figure out how to handle this case :(

Thanks for the report :)

Found the issue. In collaboration mode, when user deletes a sheet another user was on, this error is thrown. Will work on a fix. Thanks for the report.
This looks great! We've looked at a lot of these for our database GUI. I really love how fleshed out this is, and the multiplayer aspect of it!
Thank you. Collaboration is always a hard-one which requires both UI and database sync.
Is this related to the react-spreadsheet[1] project? Where does the "React Spreadsheet 2" from the title come from? It's not clear if this is an update to the project, a fork of an existing project, or something brand new.

[1] - https://www.npmjs.com/package/react-spreadsheet

Hi, Its not related to that project. Its an update to an already existing project under RownsColumns, hence the name.
So did you just steal the name of another component?
No. The component is named "Spreadsheet 2". It's based on React framework. Hence the title of this article "React Spreadsheet 2".
The Twitter link in the footer points to an unrelated account with the "rowsncolumns" handle
Oops. Fixed, thats the handle i wanted, but it was taken :)
Is there some capable fully open source data grid providing spreadsheet functionality?

Commercial / open-core are a no-go for me, since my goal is to integrate it into an open source project.

Older (MIT) versions of Handsontable
(comment deleted)
Performance for something like this is critical. How do you test or plan on testing performance to prevent regressions? I’ve yet to crack this nut in a way that makes me happy.
Yes it is. The Spreadsheet is powered by ReactJS and Konva.

React and Konva provides a Profiler and Devtools to measure performance and to prevent any un-necessary re-renders.

We also measure the Canvas FPS to make sure rendering is at max 60fps. The bottleneck we have identified is with scrolling large amounts of text, especially in large 42 inch 4K monitors, where FPS limits to 55-60fps. We do have some workaround planned for large monitors, by splitting the canvas into 4 layers.

In terms of regression, we use Cypress for most e2e testing, but the test cases are small as of now.

You mentioned physical size of monitors. Does it affect performance in your tests? I would be very, very surprised if performance on 27" 4k monitor was any different than on 42" 4k monitor. Maybe I'm not aware of some quirk?
I have tested on 32" 4K and 27" 4K and there was no performance issues.

Slight degradation on Dell 42" 4K, could be because of the ppi or the pixel ratio, which might be causing canvas/row/cell/ dimensions to be not rounded to whole numbers (this can affect perf).

Interesting. Can you elaborate how you measure performance? What's perfoemance? Framer ate, cpu/gpu usage, mem, scroll speed?
There are quite a few methods to measure performance

We start of with the FPS monitoring tool which measure the frame rate, memory consumption and GPU sange

We switch to devtools->Performance analysis to measure function call times, layout thrashes and shifts, RAF bottleneck, memory consumption and CPU time.

We also use React devtools to measure re-rendering.

Scrolling is wrapped in Request animation frame loop, hence its being controlled by the browsers frame rate.

It's usually the scaling. If you're on 27" at 4k, you probably have some scaling enabled, anywhere from 1.25x to 2x, so less stuff fits on the screen. Since less stuff fits on the screen, less stuff gets rendered and performance should be better.

At 42" 4k, there's probably no scaling, so more stuff fits on the screen.

[flagged]
(comment deleted)
Thanks. Possibly related to collaboration. I need to handle a scenario where user deletes another user's active sheet.
i only got this with my adblocker turned on fyi, ublock origin
Seconding this Edit: Happened again. Might not be related.
Please try again. We don't persist data to a database in this demo, hence some of these errors. Pushed a temporary fix
"Application error: a client-side exception has occurred (see the browser console for more information)."

Shame.

same

Application error: a client-side exception has occurred (see the browser console for more information).

Sorry about that. The demo does not persist data on the server, hence sheet deletions can throw errors.
(comment deleted)
The demo is neat. How did you do the backend? As far as I see your offering is only related to the UI components. What databases and backends are you seeing users have success with?
The demo does not use a back-end service.

We are agnostic to back-end frameworks. Some users have used Prisma + Graphql, NoSQL databases etc.

The Sheet data structure on the UI can be flexible too. It can come from streaming data source, lazily loaded on-demand or all stored in browser memory

Admittedly, I haven't clicked on the link, but you appear to have avoided their question altogether. You offer product demos. Those demos source data from something, be it a JSON file, REST API, etc. Where is the demo data sourced from?
The demo data is sourced partially from US Covid database.
looks great, nice to see real time collaboration built in!
Saw the collaboration mode and immediately feared it would devolve into people throwing around slurs as many unmoderated online experiences often do.

Pleasantly surprised to see conspiracies about Tupac and 'vue gang' take over the sheet instead :)

(comment deleted)
Scrolling the sheet on my pixel 4a is very laggy. Is this server latency or client side lag?
I will do some testing on Pixel phones soon. This should be a client-side UI lag. No server is used for the demo. Thanks for the feedback
I tried again later and it was smooth. I'm using Brave browser on mobile btw.
The coop demo on the homescreen is a dubious idea
As long as the content resets periodically it's probably fine. Right now it's on the front page but in the near future there will probably be only one person on it at a time, who can send it to a coworker and test out the functionality live.
Nothing persists. All the diffs are sent over using Supabase and received by all other clients. The diffs are then applied to create the new state.
(comment deleted)
Anyone else getting this error?

  duplicate capture group name in regular expression
I find that if I refrain from editing the contents of cells, then this crash doesn't occur, and I can see lots of people modify stuff in real-time. I can play with everything but the contents of a cell, otherwise I get a crash.

Overall cool demo

Did you try to enter a date? Any sample text, so that i can try to pinpoint this issue?
Using Chrome 119, I see

  SyntaxError: Invalid regular expression: /^(?<year>\d{4})(\-)(?<month>\d{1,2})(\-)(?<year>\d{1,2})T(?<hour>\d{1,2})\:(?<minute>\d{1,2})\:(?<second>\d{1,2})(Z?)$/i: Duplicate capture group name
This happens whenever I insert text to any cell. I just tried inserting "TEST" to a cell on the first sheet, then pushed the Enter key. It also happens when I use arrow keys to move away from a cell I am editing.
Thanks for the feedback. I will look into this.

Does the error go away if you just refresh the demo?

Yeah, refreshing the page makes everything work again. I can see changes to the spreadsheet in real-time and I am capable of resizing cells, changing fonts, etc. The only problem is with editing the contents of a cell.
Ah. Yes i figured out the issue. Could you share your current location? Are you in the US or Japan? We create a date pattern matching expression based on your current locale.
Yeah, I am currently in the US, using a MacBook with Japanese locale set.
Awesome. I have fixed this issue for you.
Cool, real-time debugging and deploying a fix in minutes. We've come a long way since the days of shrinkwrapped spreadsheet software sold in a store.
Is there a way to try this before I buy it?

I am building something that would probably benefit from this, but with that price tag (solo indy dev) that's going to be a big ask! might be worth it, just no way of knowing without trying it first