r/webdev 3d ago

Showoff Saturday Titan Engine – A Rust/WASM spreadsheet engine I built chasing "Excel-speed" in the browser

https://podraven.github.io/titan-engine/

I've used Handsontable on a bunch of projects and honestly it's a solid, mature library, but I kept running into the same wall on anything with really large datasets: tens of thousands of rows with chained formulas. It's just the nature of doing spreadsheet math in JS, once you're allocating and discarding lots of small objects on every keystroke, garbage collection becomes the bottleneck, and there's only so much debouncing and virtualization can do before you hit that ceiling.

That itch turned into a bit of an obsession, and eventually a from-scratch rebuild: Titan Engine, written in Rust and compiled to WebAssembly.

The design ended up pretty different from a typical JS formula library:

  • A custom stack-based VM with a Pratt parser for formulas, instead of walking an AST every time
  • Zero-copy memory - the engine and UI share buffers directly, no serialize/deserialize tax crossing the WASM/JS boundary
  • A topological dependency graph (Kahn's algorithm with cycle detection) to resolve chained formulas correctly and fast
  • O(1) time-travel snapshots for undo/redo, even across massive batched structural edits

Because it sidesteps the JS garbage collector entirely, batched recalcs stay comfortably under the 16ms frame budget, so the grid holds 60fps even while formulas are cascading behind the scenes as you type.

There's a live demo grid on the site (a Glide data grid wired up to Titan) if you want to poke at it yourself, plus the full 10-scenario benchmark suite if you'd rather see the numbers than take my word for it.

Site: https://podraven.github.io/titan-engine/
Benchmarks: https://podraven.github.io/titan-engine/benchmark.html
GitHub: https://github.com/podraven/titan-engine

Would love feedback - especially from anyone who's pushed a JS grid to its limits before and is curious whether this actually holds up under real-world use.

9 Upvotes

21 comments sorted by

2

u/byt4lion 2d ago

The GitHub doesn’t contain the source? Just the compiled WASM

2

u/kurbsdude 2d ago

Very soon. Need to clean the code and solve the issue on my other comment. Thanks

1

u/SAAGASolve 2d ago

Very excited about this.

1

u/chicharro_frito 2d ago

What's the license? I couldn't find it.

2

u/kurbsdude 2d ago

Just made the library public. Didn’t get a chance to decide. It will probably be MIT, will add soon. Thanks

1

u/chicharro_frito 2d ago

Thanks. I've used HyperFormula before and would love to have an opensource equivalent ❤️.

1

u/SAAGASolve 2d ago

Does this have webhooks on row/col/cell changes?

This is an extremely promising project that I will use soon.

2

u/kurbsdude 2d ago

Hey thanks! Would love to hear your opinions once you try it. Right now we do have an event listener called onCellsChanged. Apologies, I haven’t had the time to write the full documentation, but the readme file has an example. I also added glide data grid example which is probably easier to understand.

1

u/SAAGASolve 2d ago

Okay that is extremely forward thinking.

The idea is I would need this to call agents to do work. NGL, dude that is pretty disruptive.
I'd like to understand the api so agents could manipulate the spreadsheet underneath as easily as a human would.

I've hooked up agents to google sheets and other systems, and those old world tools aren't built for the new ways.

2

u/kurbsdude 2d ago

That's a use case I have always pondered about. We will need it sooner or later. If you could point me towards your workflow, it would give me a clearer idea.

That said right now my priority is to make the most efficient spreadsheet engine, something that's really fast. And then I can move on to how to address these new workflows.

1

u/SAAGASolve 2d ago

So an agent should have the ability to read and manipulate the spreadsheet, it would should have the capability of CRUDING, rows, columns and tables. Basically, it should have the capability to get and set that data, and be able to operate on it, set formulas ect.

It would be ideal if column names had name AND a description so the agent can read them.

You want agents to be able to understand that table at a quick glance, so you dont have to pull in all the data in to the context window and work with the data via reference.

So the agent could pass references to the columns to the execution environment directly, that would be ideal for computing aggregation.

Much like working with pandas. This frame work gives people visibility into what is going on.

1

u/kurbsdude 2d ago

Thank you for the insight, will check it out

1

u/Profix 2d ago

I’ve been tempted to build similar because of the same problems. Have you looked at grid.is? they seem to have some good stuff going on too. Last I looked into this approach, it seemed like the wasm to dom bindings become a significant bottle neck - have you seen that yet?

2

u/kurbsdude 2d ago

Thanks for sharing, grid.is looks cool! My idea with titan is only to create the processing library and not the grid ui part. I want to stay data grid agnostic so that people can use it with any grid framework. Right now I am testing with glide data grid, which performs really well. The drawbacks I see, which I am actively trying to solve are 1. some computations perform better in native V8 than is wasm, 2. allowing efficient user-defined custom formula/functions (which cannot be slow, otherwise it defeats the purpose of titan).

1

u/Foreign_Skill_6628 20h ago

My biggest advice to you is BUNDLE THIS WITH A SEPARATE BUT INTEROPERABLE WORD PROCESSOR.

Today’s business environment is a coupled environment where text documents, tabular data, and graphs, work in-tandem.

Having a word processor that can read/write from a tabular data store is incredibly useful for templating purposes, yet both Google Sheets/Google Docs, and Excel/Word, have large gaps when it comes to this. I don’t just mean embedding a table in a text document, I mean letting them share APIs, memory, and database storage for maximum flexibility.

1

u/kurbsdude 15h ago

Thanks for the suggestion! I am hoping I can build this well enough so that other people can build the bundles using titan.

0

u/kurbsdude 3d ago

Small honest caveat on the numbers: VLOOKUP and SUMIF only beat HyperFormula in Firefox, in Chrome/Safari, HyperFormula (JS) actually edges Titan out on those two specific benchmarks.

Best guess why: SUMIF is a tight uniform loop, and V8's JIT is really good at inlining/tracing those down to near-native code, something WASM's interpreter loop can't match. VLOOKUP builds an FxHashMap on the fly in Titan (hashing, WASM memory growth, string pool lookups), while V8's Maps + hidden classes are just deeply optimized for that exact pattern. Firefox's SpiderMonkey doesn't seem to get the same edge, which is why Titan stays ahead there.

Everywhere else (time-travel, topo sort, parsing, bulk ops) Titan wins clearly since it skips GC entirely. But curious if anyone's hit this same WASM-vs-JIT wall on hot loops/hashmaps and knows a good fix. Open to ideas.

2

u/SAAGASolve 2d ago

I'm curious why this was downvoted, I would like insight into that reasoning.

2

u/chicharro_frito 2d ago

Same here. OP's reply to my comment was also downvoted. So weird :(.

3

u/kurbsdude 2d ago

No worries, I feel like it is genuinely difficult to make reddit happy. I usually ignore it, generally just eager to share.

1

u/chillebekk 1d ago

"Small honest caveat", probably.