You asked for more frequent releases. Here we go!
In this release cycle we added the long awaited dark mode. It touches every bit of the UI, and a lot of design, brainstorming and time went into it. It is still fresh, so let us know how we can improve it.
Merged cells are in town! They are everywhere in spreadsheets, so they were a big missing piece.
We have links now. As usual we designed the feature carefully, tested it and implemented every detail.
Following in the footsteps of Ephraim Kunz we massively improved how we import xlsx workbooks.
A lot of work was put into the main evaluation algorithm. This is a tough nut to crack. We are still evaluating all formulas all the time, and we still have a recursive evaluator. But we solved two long-standing issues: we never overflow the stack, even with formula chains millions of cells deep, and we are correct in every scenario. We will talk about this in the future.
We changed the internal representation of the data to allow for a more compact representation of larger workbooks.
Some love was poured into our side project (for now) TironCalc. You can run and work with large spreadsheets in your terminal.
Finally, we closed many old issues and PRs but my personal favourite was spreadsheets are all you need. IronCalc can now run, in the browser, a 1.4GB Excel workbook containing the whole GPT-2 inference model. That is a milestone I didn't want to go unnoticed, so we created Hamilton, a fully serverless version of our demo app. You can drop gigantic xlsx files in there. Thanks to the code of Brian Hung, files are imported in your browser with full privacy. Go ahead and give it a crack.
Thirteen people opened their first pull request during this time (more than ever!). Their work can be found everywhere in this release: date and time parsing, INDIRECT with R1C1 references, rounding compatibility, Python bindings… Community help keeps making IronCalc better every week. Contributors often wait a while until we get around to reviewing their PRs. IronCalc is still a two-person endeavour, and we read every line of code, test every new feature and question every decision.
Your help and patience are highly appreciated. Thank you all!
But the community is not limited to the IronCalc repository. We have Ruby bindings thanks to Jaap van der Plas. There are folks experimenting with new desktop apps, including IronCalc in their offerings, both open source and commercial.

Engine & Performance
This is the part of the release you will not see, but you will definitely feel. Large workbooks were the main focus:
- A new streaming parser for loading workbooks
- The engine now only evaluates cells with formulas
- Less memory per cell is needed, and a nicer, more compact shape for sheet data
- Memory improvements while loading workbooks
- Shared strings are indexed while sheets load
- by @philip-pentatonic in #1496
- Several fixes to the general evaluation algorithm #1420
- The app now uses IndexedDB instead of LocalStorage #1451
- Faster builds: we no longer rebuild everything when it is not needed
Dark Mode
This has been a common request for some time, and now it's here. IronCalc now adapts to your OS preference automatically (although you can of course change it whenever you want).
Links
Cells can now hold links. Imported workbooks will keep them, or you can just add them directly in IronCalc. It's a small feature, yeah, but a big quality-of-life improvement, especially for anyone using IronCalc to keep track of lists of things that live somewhere else on the internet.
A new function (ENCODEURL by @wms2537 in #1419) was also added, so building URLs from cell values is now easy.
Merged Cells
Another long-standing request. You can now merge cells in IronCalc, with all the usual variants:
- Merge, merge across, merge and centre and merge down
- Unmerge to split them back
- Autofill works as well!
Formula Support & Correctness
Arrays and Implicit Intersection
v0.8 brought dynamic arrays. v0.9 makes sure more of the engine plays along with them:
- Implicit intersection fixes
- Arithmetic errors now broadcast properly across arrays, and the power operator handles arrays
- Several text functions now support arrays
- ROW and COLUMN can deal with ranges
- ROWS and COLUMNS count the rows and columns of an array argument
- TYPE returns 64 for arrays
- by @svettypoo in #1431
- Fixed several issues with expressions like
--A1:B4, and minor issues with MAX and MIN
Dates and Times
Dates and times are where spreadsheets quietly go wrong, so we spent a lot of effort matching Excel here:
- DATEVALUE and TIMEVALUE ignore spaces around separators, like Excel
- by @theluckystrike in #1485
- DATEVALUE rolls the date over when the time part reaches 24 hours
- by @theluckystrike in #1486
- TIMEVALUE accepts fractional seconds
- MINUTE and SECOND round the time to the nearest millisecond
- by @svettypoo in #1432
- EOMONTH returns
#NUM!on date overflow instead of panicking - WEEKDAY evaluates the date argument before
return_type - Date and time tokens in number formats are now case-insensitive
Other Fixes
- ROUND, ROUNDUP, ROUNDDOWN and TRUNC round to 15 significant digits, as Excel does
- BINOM.INV no longer panics; it now searches the CDF directly
- INDIRECT reads R1C1 references
- by @svettypoo in #1444, with further fixes in #1467
- Added ECMA.CEILING, behaving like Excel's CEILING
- by @svettypoo in #1447
- Sheet names containing any non-identifier character are now quoted
- Named ranges keep their scope when a sheet is renamed #1511
- Numbers are checked for
NaNand infinity before a parse is accepted
xlsx Import & Export
- xlsx export now works on wasm32
- by @jleclanche in #1406
- Quotes in conditional-format text rules are escaped for every operator
- by @philip-pentatonic in #1491
- Theme colour tints are written with full precision
- by @philip-pentatonic in #1507
- Rows without cells are written when they have a custom height or are hidden
- by @philip-pentatonic in #1506
<col>elements without awidthattribute fall back to the sheet default- Removed unneeded dependencies from the xlsx package
App & UX
New in the App
- Dark mode, links and merged cells (see above)
- Menus taller than the window now scroll
- by @MFornander in #1536
- Multiple refinements to workbook sharing, including clearer copy about shared links and clearing the shared URL when switching to a local workbook
- Templates updated to showcase v0.9
Autofill
- Double-click autofill no longer stops early when the target range has values
- Autofill now works with merged cells
Widget, Packages & Bindings
- xlsx import and export are now published as a second wasm package
- by @BrianHung in #1363
- Added type checks to the JavaScript bindings. Heads up:
from_typeshas been renamed tofromBytes#1357 - Only
wasm32-unknown-unknownis treated as a browser target- by @devonanderson in #1526
- Python: added
get_cell_valueand other cell readers toUserModel - Updated Python bindings
Testing & Quality
@elsaminsut went through almost every date and time function and many statistical and trigonometric ones, extending their tests and finding bugs along the way. This release includes improved testing for functions like DATE, YEAR, TIMEVALUE, NETWORKDAYS and many more.
What's next?
A lot of things are already in the making. Charts, tables, Desktop App, collaboration, data validation, custom functions... We have way too many ideas and planned features for the next releases.
And of course, performance will keep being a focus in the coming months. If you have a large workbook that IronCalc struggles with, we would love to hear about it!
New Contributors (v0.9)
We got lots of help again. Thank you for your patience with our reviews, and welcome aboard!
- @tommy230
- @jleclanche
- @Bobstin
- @wms2537
- @Yudhyy
- @getdom
- @svettypoo
- @su79eu7k
- @Yi-111-a
- @theluckystrike
- @philip-pentatonic
- @devonanderson
- @MFornander
For the full list of changes, take a look at the v0.9.0 release on GitHub.