How to open a 300,000 row Excel file in the browser with React? office-engine loads it without backend ✅ yoDEV Tested

Yes: office-engine, a React library with MIT license, opens a 300,000-row XLSX in the browser without a backend and displays the first rows in about 300 ms. We tested it with a 23 MB file: it also edits, saves back to XLSX, and opens DOCX and PPTX with the same component.

:white_check_mark: yoDEV Tested · November 3, 2026
We tested office-engine 0.3.0 within a React app built with Vite, in Chromium 153 in headless mode, on Linux in the cloud with 2 vCPU. We used our own XLSX of 300,000 rows by 12 columns. The results we report as ours come from that test.

At the time of publishing this note (November 3, 2026), the most recent version on npm is 0.3.0. The package was created on November 2 and published eight versions in its first 28 hours, so expect the API and feature list to keep changing.

What is office-engine?

office-engine (@p10node/office-engine on npm) is a document engine that runs on the client side for the three Office Open XML formats: Word (DOCX), Excel (XLSX), and PowerPoint (PPTX). It’s distributed as a React component, as a hook, as a framework-agnostic mount() function, as a web component, and as a single self-contained script. Its author presented it on Hacker News as Show HN (item 50348361) with the headline “Open a 300k-row XLSX in the browser in ~300ms, no server”.

What’s interesting is not that it opens Office files, because many tools do that. What’s interesting is that it does it without uploading the file to any server and without freezing the tab while processing it.

Why does a very heavy Excel file freeze the browser?

An XLSX file is a ZIP of XML documents, and the sheet of a large workbook can occupy tens of megabytes of XML. If you read the entire file, decompress it, and process all that XML on the main thread, the page stops responding until it finishes; and then you try to put 3.6 million cells into the DOM.

office-engine tackles each of those steps:

  • Lazy ZIP reading. It reads file entries as it needs them, instead of decompressing everything at the beginning.
  • HTTP Range requests. When the source is a URL, it downloads only the byte ranges it needs. If the server doesn’t support Range, it falls back to downloading the entire file.
  • Streaming XML parser in a Web Worker. Processing happens off the main thread, so the interface keeps responding while the sheet loads.
  • Virtualized views. Only the visible pages, cells, or slides are rendered.
  • Fast saving. When saving, only the parts you edited are regenerated; the rest keeps its original bytes.

How to install office-engine in a React project?

With a single command, and with React 18 or higher as a peer dependency:

bun add @p10node/office-engine   # peer: react >= 18, react-dom >= 18

CSS is injected automatically. The only layout requirement is that the container has a defined height.

How to open an XLSX file in the browser with React?

Import DocViewer and pass it the file. src accepts a File, a Blob, an ArrayBuffer, or a Uint8Array:

import { DocViewer } from '@p10node/office-engine'

<DocViewer src={file} style={{ height: 600 }} />

If you pass it a URL, the component loads the file with Range requests:

<DocViewer src="https://cdn.example.com/report.xlsx" />

That way with URL is what matters for really large files: the browser doesn’t have to download the entire workbook before showing the first rows.

An Excel viewer in five minutes

The fastest way to see it work is a file selector that delivers the chosen File directly to DocViewer. The file never leaves the user’s machine:

import { useState } from 'react'
import { DocViewer } from '@p10node/office-engine'

export default function App() {
  const [file, setFile] = useState<File | null>(null)
  return (
    <>
      <input type="file" accept=".xlsx,.docx,.pptx"
        onChange={e => setFile(e.target.files?.[0] ?? null)} />
      {file && <DocViewer src={file} style={{ height: 600 }} />}
    </>
  )
}

Pick a large workbook and you’ll see the first rows appear before it finishes loading the rest. That’s how we set up our test app.

How fast does it open a 300,000-row Excel?

In our test, the first rows appeared on screen between 286 and 379 ms, across six runs. That matches the roughly 330 ms reported by the author. Full loading was slower than his: between 4.3 and 8.4 seconds, versus about 2 seconds in his measurement.

Test (23 MB XLSX, 300,000 rows × 12 columns) First rows Full load
From a URL (Range requests), 3 runs 301–379 ms 4.3–8.4 s
From a File object, 3 runs 286–306 ms 4.3–5.1 s
Author’s measurement (Apple M-series) ~330 ms ~2 s

The difference in full loading is reasonable: the author measured on Apple silicon and we measured on a Linux cloud machine with 2 vCPU. What matters is that the sheet is usable while it loads: at 1 second there were already 10,321 rows available and at 3 seconds, 84,626.

We also measured whether the tab froze. During a full load, the main thread had at most two long tasks, the longest being 231 ms. That’s the point of using a Web Worker.

And we checked how much it downloads before showing anything. From a URL, before the first rows it downloaded about 0.57 MB: the ZIP index, which is at the end of the file, and the first 256 KB. It then transmitted the sheet in a single range. To complete the load it does download the entire file; what it avoids is waiting to have everything before starting to display it.

The author’s other two numbers, a 20,000-paragraph DOCX (2,073 pages in about 2 seconds) and a 305-slide PPTX, we didn’t reproduce.

Can you edit an Excel online and save it as XLSX?

Yes, and without a server. Add editable and an onSave handler, which receives the edited file as a Blob along with its name:

<DocViewer src={file} editable onSave={(blob, name) => upload(blob, name)} />

upload is your own function: send the Blob to your API or trigger a download. The editor has a Google Docs-style toolbar. In XLSX you can edit cells, formulas, formats, borders, rows, columns, and sheets; the formula engine implements 134 functions. In DOCX, text, styles, lists, images, and tables. In PPTX, text, shapes, images, slides, and a presentation mode.

We tested it on the same 300,000-row file: we edited a cell, saved with Ctrl+S, and onSave received the file about 5 seconds later. We opened the result with openpyxl, an independent Python library:

  • The edit was saved.
  • The 300,000 rows were still complete.
  • The formulas on the second sheet (SUM and AVERAGE over the 300,000 rows) were still formulas.
  • When we compared the ZIP parts with the original, only the edited sheet had changed. Styles, workbook, the other sheet, and metadata were identical byte for byte. The promise of “only the parts you edit are regenerated” holds true.

The engine also calculated those formulas in the browser: the average of 300,000 prices came out to 499.450, the same value we got with Python.

The File menu also creates new documents, opens CSV, text, Markdown and HTML, imports CSV, exports to PDF, HTML, text or CSV, and prints. We didn’t test that.

office-engine or SheetJS?

They solve different problems. SheetJS is a library for processing spreadsheet data: it reads and writes Excel formats, but it doesn’t draw an interface. Its own documentation combines it with third-party grid components, like React Data Grid, Handsontable, or x-spreadsheet, for the visual part. office-engine is the viewer and editor in a single component: it opens the document with its formatting, lets you edit it, and saves it in the original format.

If what you need is to read Excel data in JavaScript to process it, SheetJS is still the tool. If you need the user to see and edit the document within your application, office-engine saves you assembling the grid. We didn’t compare the performance of both.

Does it work without React?

Yes. The dist/ folder includes office-engine.embed.js, which bundles React and the worker, and exposes an <office-viewer> web component:

<script src="office-engine.embed.js"></script>
<office-viewer src="/files/report.docx" style="height:600px"></office-viewer>

There’s also a framework-agnostic mount() function, documented in the API reference. We didn’t test this path. As a weight reference: our test app with React and office-engine ended up in a single JavaScript file of 947 KB, 318 KB with gzip.

Does real-time collaboration need a server?

Yes, and it’s the only point where “no backend” stops being true. Viewing and editing work entirely in the browser. Live multi-user editing (shared changes, avatars, collaborators’ cursors, and offline changes that sync when reconnecting) needs a hub that orders batches of changes, saves the operation log, and broadcasts each user’s presence.

The project includes a reference hub, CollabHub, that runs with Bun and listens on port 8787. It stores rooms in a local directory (DATA) or in an S3 bucket (S3_BUCKET). You can connect it to any WebSocket server or implement the Transport interface for your own backend. It doesn’t use Yjs: it uses its own schema where each client applies its changes instantly and, if the hub ordered another collaborator’s batch first, it undoes its own changes and reapplies them.

On the client it’s just another DocViewer prop:

<DocViewer
  src={`https://hub.example.com/rooms/${id}/file?seq=${snapshot}`}
  editable
  collab={{ transport: 'wss://hub.example.com/collab', room: id, base: snapshot, user: { name: 'Ann' } }}
/>

base must match the sequence number of the file from src; if you omit it, the client reapplies the entire room history. The README shows a demo with three users, but we didn’t test the hub and, at the time of publishing, no one outside the project had reported running it.

What doesn’t office-engine support?

The project documents its limitations in a feature table. As of November 3, 2026:

  • No support: old binary formats (.xls, .doc, .ppt) and encrypted files.
  • XLSX: it doesn’t yet display charts, conditional formatting, or images. Formulas don’t support defined names, structured table references, or 3D references. You can’t edit charts, pivot tables, conditional formatting, data validation, or filters, and when you insert or delete rows, conditional formatting and data validation don’t shift.
  • DOCX: missing are footnote bodies, charts, precise floating object positioning, and paragraphs split across pages. Headers, footers, text boxes, nested tables, and multi-paragraph fields like a table of contents are read-only.
  • PPTX: charts appear as placeholders; SmartArt, animations, transitions, and video playback are missing. You can’t edit text inside tables or insert tables, you can’t rotate shapes with the mouse, and you can’t undo adding, deleting, or moving slides.
  • Browser compatibility: the documentation doesn’t publish a list. The engine depends on the native DecompressionStream API and Web Workers. We only tested Chromium.

Is it ready for production?

Treat it as a very young project. It has a single identifiable maintainer, who publishes to npm as pierreneter; the repository has no tagged releases on GitHub, and in roughly a day eight versions came out on npm. It has MIT license and installs today, so it’s easy to test it behind a feature flag.

Where it fits best now is in an internal tool or admin panel where users need to preview large spreadsheets and you’d prefer not to set up a conversion service. Pin the exact version and check the feature table before depending on charts or conditional formatting.

Our verdict: in what we tested, it does what it promises. The first rows arrive in the announced time, the tab doesn’t freeze, and the saved file comes out clean. Full loading depends a lot on hardware, and real-time collaboration is another project, with its own server.


And you? What’s the largest Excel file you’ve had to display inside a web application?

How do you display Office files in your application today?
  • I convert them on the server (to PDF or HTML)
  • SheetJS plus a grid component
  • I send them to an external viewer (Google or Microsoft)
  • I prefer another option (tell us which)
0 votantes

Comment below or, if this article reached you by email, reply directly to the email: your reply will be published here.

Related: MarkItDown: Microsoft’s Tool That Converts Any Document into Context for Your AI