Sim: office-engine, uma biblioteca React com licença MIT, abre um XLSX de 300.000 linhas no navegador sem backend e mostra as primeiras linhas em cerca de 300 ms. Testamos com um arquivo de 23 MB: também edita, salva de volta em XLSX e abre DOCX e PPTX com o mesmo componente.
yoDEV Tested · 3 de novembro de 2026
Testamos office-engine 0.3.0 dentro de um app React construído com Vite, em Chromium 153 em modo headless, em Linux na nuvem com 2 vCPU. Usamos um XLSX próprio de 300.000 linhas por 12 colunas. Os resultados que reportamos como nossos saem desse teste.
No momento de publicar esta nota (3 de novembro de 2026), a versão mais recente no npm é a 0.3.0. O pacote foi criado em 2 de novembro e publicou oito versões em suas primeiras 28 horas, então espera que a API e a lista de funcionalidades continuem mudando.
O que é office-engine?
office-engine (@p10node/office-engine no npm) é um mecanismo de documentos que funciona do lado do cliente para os três formatos do Office Open XML: Word (DOCX), Excel (XLSX) e PowerPoint (PPTX). É distribuído como componente React, como hook, como função mount() sem framework, como web component e como um único script autocontido. Seu autor o apresentou no Hacker News como Show HN (item 50348361) com o título “Open a 300k-row XLSX in the browser in ~300ms, no server”.
O interessante não é que abra arquivos do Office, porque muitas ferramentas fazem isso. O interessante é que faz isso sem enviar o arquivo para nenhum servidor e sem congelar a aba enquanto processa.
Por que um Excel muito pesado congela o navegador?
Um arquivo XLSX é um ZIP de documentos XML, e a planilha de um livro grande pode ocupar dezenas de megabytes de XML. Se você lê o arquivo completo, descompacta e processa todo esse XML na thread principal, a página para de responder até que termina; e depois você tenta colocar 3,6 milhões de células no DOM.
office-engine ataca cada um desses passos:
- Leitura preguiçosa do ZIP. Lê as entradas do arquivo conforme as necessita, em vez de descompactar tudo no início.
- Requisições HTTP Range. Quando a fonte é uma URL, baixa apenas os intervalos de bytes que precisa. Se o servidor não suporta Range, recorre a baixar o arquivo completo.
- Parser XML em streaming dentro de um Web Worker. O processamento ocorre fora da thread principal, então a interface continua respondendo enquanto carrega a planilha.
- Visualizações virtualizadas. Apenas as páginas, células ou slides visíveis são renderizados.
- Salvamento rápido. Ao salvar, apenas as partes que você editou são regeneradas; o resto mantém seus bytes originais.
Como instalar office-engine em um projeto React?
Com um único comando, e com React 18 ou superior como dependência peer:
bun add @p10node/office-engine # peer: react >= 18, react-dom >= 18
O CSS é injetado automaticamente. O único requisito de design é que o contêiner tenha uma altura definida.
Como abrir um arquivo XLSX no navegador com React?
Importe DocViewer e passe o arquivo para ele. src aceita um File, um Blob, um ArrayBuffer ou um Uint8Array:
import { DocViewer } from '@p10node/office-engine'
<DocViewer src={file} style={{ height: 600 }} />
Se você passar uma URL, o componente carrega o arquivo com requisições Range:
<DocViewer src="https://cdn.example.com/report.xlsx" />
Essa forma com URL é a que importa para arquivos realmente grandes: o navegador não precisa baixar o livro completo antes de mostrar as primeiras linhas.
Um visualizador de Excel em cinco minutos
A forma mais rápida de ver funcionando é um seletor de arquivos que entregue o File escolhido diretamente para DocViewer. O arquivo nunca sai da máquina do usuário:
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 }} />}
</>
)
}
Escolha um livro grande e você verá as primeiras linhas aparecerem antes de terminar de carregar o resto. Assim montamos nosso app de teste.
Quão rápido abre um Excel de 300.000 linhas?
Em nosso teste, as primeiras linhas apareceram na tela entre 286 e 379 ms, em seis execuções. Isso coincide com os cerca de 330 ms que o autor reporta. O carregamento completo foi mais lento que o dele: entre 4,3 e 8,4 segundos, comparado aos cerca de 2 segundos na medição dele.
| Teste (XLSX de 23 MB, 300.000 linhas × 12 colunas) | Primeiras linhas | Carregamento completo |
|---|---|---|
| De uma URL (requisições Range), 3 execuções | 301–379 ms | 4,3–8,4 s |
De um objeto File, 3 execuções |
286–306 ms | 4,3–5,1 s |
| Medição do autor (Apple M-series) | ~330 ms | ~2 s |
A diferença no carregamento completo é razoável: o autor mediu em um equipamento com Apple silicon e nós em uma máquina Linux de 2 vCPU. O importante é que a planilha pode ser usada enquanto carrega: em 1 segundo já havia 10.321 linhas disponíveis e em 3 segundos, 84.626.
Também medimos se a aba congelava. Durante um carregamento completo, a thread principal teve no máximo duas tarefas longas, a mais longa de 231 ms. Esse é o ponto de usar um Web Worker.
E verificamos quanto baixa antes de mostrar algo. De uma URL, antes das primeiras linhas apenas baixou cerca de 0,57 MB: o índice do ZIP, que fica no final do arquivo, e os primeiros 256 KB. Depois transmitiu a planilha em um único intervalo. Para terminar o carregamento, sim, baixa o arquivo completo; o que evita é esperar por tudo para começar a mostrá-lo.
Os outros dois números do autor, um DOCX de 20.000 parágrafos (2.073 páginas em cerca de 2 segundos) e um PPTX de 305 slides, não reproduzimos.
É possível editar um Excel online e salvá-lo como XLSX?
Sim, e sem servidor. Adicione editable e um manipulador onSave, que recebe o arquivo editado como Blob junto com seu nome:
<DocViewer src={file} editable onSave={(blob, name) => upload(blob, name)} />
upload é sua própria função: envia o Blob para sua API ou dispara um download. O editor tem uma barra de ferramentas ao estilo do Google Docs. Em XLSX você pode editar células, fórmulas, formatos, bordas, linhas, colunas e planilhas; o mecanismo de fórmulas implementa 134 funções. Em DOCX, texto, estilos, listas, imagens e tabelas. Em PPTX, texto, formas, imagens, slides e um modo de apresentação.
Testamos no mesmo arquivo de 300.000 linhas: editamos uma célula, salvamos com Ctrl+S e onSave recebeu o arquivo cerca de 5 segundos depois. Abrimos o resultado com openpyxl, uma biblioteca Python independente:
- A edição estava salva.
- As 300.000 linhas continuavam completas.
- As fórmulas da segunda planilha (
SUMeAVERAGEsobre as 300.000 linhas) continuavam sendo fórmulas. - Ao comparar as partes do ZIP com o original, apenas a planilha editada havia mudado. Estilos, livro, a outra planilha e metadados eram idênticos byte a byte. A promessa de “apenas o que você edita é regenerado” se cumpre.
O mecanismo também calculou essas fórmulas no navegador: a média de 300.000 preços deu 499.450, o mesmo valor que obtivemos com Python.
O menu Arquivo, além disso, cria novos documentos, abre CSV, texto, Markdown e HTML, importa CSV, exporta para PDF, HTML, texto ou CSV e imprime. Isso não testamos.
office-engine ou SheetJS?
Resolven problemas diferentes. SheetJS é uma biblioteca para processar dados de planilhas: lê e escreve os formatos do Excel, mas não desenha uma interface. Sua própria documentação a combina com componentes de grid de terceiros, como React Data Grid, Handsontable ou x-spreadsheet, para a parte visual. office-engine é o visualizador e o editor em um único componente: abre o documento com seu formato, permite que você o edite e o salva no formato original.
Se o que você precisa é ler os dados de um Excel em JavaScript para processá-los, SheetJS continua sendo a ferramenta. Se você precisa que o usuário veja e edite o documento dentro de sua aplicação, office-engine poupa você de montar o grid. Não comparamos o desempenho dos dois.
Funciona sem React?
Sim. A pasta dist/ inclui office-engine.embed.js, que empacota React e o worker, e expõe um web component <office-viewer>:
<script src="office-engine.embed.js"></script>
<office-viewer src="/files/report.docx" style="height:600px"></office-viewer>
Também há uma função mount() sem framework, documentada na referência da API. Essa via não testamos. Como referência de peso: nosso app de teste com React e office-engine ficou em um único arquivo JavaScript de 947 KB, 318 KB com gzip.
A colaboração em tempo real precisa de servidor?
Sim, e é o único ponto onde “sem backend” deixa de ser verdade. Ver e editar funcionam completamente no navegador. A edição multiusuário em tempo real (mudanças compartilhadas, avatares, cursores dos colaboradores e mudanças offline que se sincronizam ao reconectar) precisa de um hub que ordene os lotes de mudanças, salve o registro de operações e retransmita a presença de cada usuário.
O projeto inclui um hub de referência, CollabHub, que é executado com Bun e escuta na porta 8787. Salva as salas em um diretório local (DATA) ou em um bucket S3 (S3_BUCKET). Você pode conectá-lo a qualquer servidor WebSocket ou implementar a interface Transport para seu próprio backend. Não usa Yjs: usa um esquema próprio em que cada cliente aplica suas mudanças instantaneamente e, se o hub ordenou antes o lote de outro colaborador, desfaz as dele e as reaplica.
No cliente é apenas uma prop a mais de DocViewer:
<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 deve corresponder ao número de sequência do arquivo em src; se você omitir, o cliente reaaplica todo o histórico da sala. O README mostra uma demo com três usuários, mas não testamos o hub e, no momento de publicar, ninguém fora do projeto tinha reportado tê-lo executado.
O que office-engine não suporta?
O projeto documenta suas limitações em uma tabela de funcionalidades. Em 3 de novembro de 2026:
- Sem suporte: os formatos binários antigos (
.xls,.doc,.ppt) e os arquivos criptografados. - XLSX: ainda não mostra gráficos, formatação condicional ou imagens. As fórmulas não suportam nomes definidos, referências estruturadas a tabelas ou referências 3D. Não é possível editar gráficos, tabelas dinâmicas, formatação condicional, validação de dados ou filtros, e ao inserir ou excluir linhas não há deslocamento de formatação condicional ou validação de dados.
- DOCX: faltam o corpo de notas de rodapé, gráficos, ajuste exato de objetos flutuantes e parágrafos divididos entre páginas. Cabeçalhos, rodapés, caixas de texto, tabelas aninhadas e campos de vários parágrafos, como um índice, são somente leitura.
- PPTX: gráficos aparecem como marcadores; faltam SmartArt, animações, transições e reprodução de vídeo. Não é possível editar texto dentro de tabelas ou inserir tabelas, não é possível girar formas com o mouse e não é possível desfazer adicionar, excluir ou mover slides.
- Compatibilidade de navegadores: a documentação não publica uma lista. O mecanismo depende da API nativa
DecompressionStreame de Web Workers. Testamos apenas Chromium.
Está pronto para produção?
Trate-o como um projeto muito jovem. Tem um único mantenedor identificável, que publica no npm como pierreneter; o repositório não tem releases etiquetadas no GitHub, e em aproximadamente um dia saíram oito versões no npm. Tem licença MIT e se instala hoje, então é fácil testá-lo atrás de um feature flag.
Onde melhor se encaixa agora é em uma ferramenta interna ou um painel de administração onde os usuários precisam pré-visualizar planilhas grandes e você prefere não montar um serviço de conversão. Fixe a versão exata e revise a tabela de funcionalidades antes de depender de gráficos ou formatação condicional.
Nosso veredicto: no que testamos, cumpre o que promete. As primeiras linhas chegam no tempo anunciado, a aba não congela e o arquivo salvo sai limpo. O carregamento completo depende muito do hardware, e a colaboração em tempo real é outro projeto, com seu próprio servidor.
E você? Qual é o arquivo Excel maior que você teve que mostrar dentro de uma aplicação web?
- Converto no servidor (para PDF ou HTML)
- SheetJS mais um componente de grid
- Envio para um visualizador externo (Google ou Microsoft)
- Prefiro outra opção (conte-nos qual)
Comente abaixo ou, se este artigo chegou para você por email, responda diretamente ao email: sua resposta é publicada aqui.
Relacionado: MarkItDown: A Ferramenta da Microsoft que Converte Qualquer Documento em Contexto para sua IA
