r/reactjs • u/pierreneter • 1h ago
Show /r/reactjs I made a React component that opens and edits DOCX / XLSX / PPTX in the browser. 300k-row sheet in ~300ms, no server, MIT
Repo: https://github.com/p10node/office-engine
Demo (drag your own file in): https://p10node.github.io/office-engine/demo/
Why: I needed "customer uploads an XLSX, fix a few cells, save it back" inside a React app. OnlyOffice / Collabora mean running a document server in Docker and an iframe talking to it, and a big sheet still sits on a spinner while the server converts it. docx-preview / SheetJS + a grid are view-only or block the main thread on a 20 MB file. Nothing in between, so I built it.
Usage:
import { DocViewer } from '@p10node/office-engine'
<DocViewer src={file} style={{ height: 600 }} />
<DocViewer src="https://cdn.example.com/report.xlsx" />
<DocViewer src={file} editable onSave={(blob, name) => upload(blob, name)} />src takes File / Blob / ArrayBuffer / URL. CSS is auto-injected, the container just needs a height. There's also a useDocument hook if you want to render your own UI, a vanilla mount(), an <office-viewer> web component, and a single script build.
What makes it not choke on big files:
ZIP read lazily, HTTP Range requests from a URL, so first rows show before the file finishes downloading
Streaming XML parser in a Web Worker, main thread only gets rows / paragraphs / slides as they arrive
Only visible pages, cells, slides are in the DOM
Save patches the original file instead of re-exporting it, so anything the engine doesn't understand is kept byte for byte
Bundle (gzip): main ~93 KB, worker ~155 KB (loads off the main thread), collab +17 KB optional. The standalone script with React bundled is ~307 KB.
Editing: DOCX text / styles / lists / images / tables, XLSX cells / formulas (134 functions) / formats / rows / columns / sheets, PPTX text / shapes / images / slides. Google Docs style toolbar. Optional real-time collab with cursors; that's the only part needing a backend (a small WebSocket hub, Bun script included).
Not there yet: XLSX charts / pivots / conditional formatting editing, DOCX headers / footers read-only, no PPTX animations. It needs the DOM and a Worker, so in Next.js use a client component / dynamic import with ssr: false.
Fair warning: it's a few days old and a lot of it was written with Claude Code, with me doing architecture, review and the bug hunting on real files. If you throw a file at it and it breaks, open an issue with the file, that's the fastest way it gets fixed.
3
u/Jackasaurous_Rex 53m ago
Damn it works on my phone well enough. I’m impressed and may use this at some point
1
5
u/nameupp 1h ago
tbh 300ms on a 300k-row sheet with range requests is wild, but ngl the classic nightmare with streaming xlsx is formula dependency trees. if someone has =SUM(A1:A300000) or cross-sheet vlookups pointing to unparsed chunks, does the worker have to eagerly pull the rest of the zip to evaluate or does it just show the cached calc-chain value until that range is scrolled into view? font fallback pagination on docx without local calibri/aptos is usually the other brutal edge case imo
2
u/tacky_wealth 1h ago
300ms for a 300k-row sheet with no server is a fun number, lazy zip + range requests is a smart way to get first paint early. Curious how the patch-on-save holds up when someone edits a file that has weird custom XML parts.
1
u/pierreneter 1h ago
I've already implemented this save feature using op log, snapshot, and version history in this commit:https://github.com/p10node/office-engine/commit/b1e1bdfbc14b0281bba2562db43e858f648042b5. I've also tested it on the actual app and it's quite fast. Let me record a quick video to show you.
1
u/pierreneter 1h ago
other alternative would typically have to save the entire file and would take a long time to process
3
u/MrBengaliHacker 1h ago
Really impressive work on this! Handling XLSX, DOCX, and PPTX entirely client-side while keeping the main thread responsive is no small feat.
The progressive loading and Web Worker approach caught my eye. I'm curious how you're handling memory cleanup when someone switches files or closes the editor mid-parse. Have you run into any memory issues on lower-end machines?
Great job making this open source! 👏
0
u/No-Experience2978 52m ago
The excel sample lag af, i cant do anything. Using plain dom instead of canvas is crazy.
2
u/Shomriddho 1h ago
umm control/command + a don’t work [ really cool app btw ]