Skip to content
ChristopherVRPublic

About

All the logic behind the Office viewers (DOCX, PPTX, OPC, XML, DrawingML shapes): one package, ooxml-core

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

10 stars

Watchers

0 watching

Forks

ooxml

Open, edit, validate and save Word, Excel, PowerPoint and Visio files in TypeScript, in the browser or on a server. One XML model, one library, ready-made editors for every major framework, and no server in the middle.

CI OpenSSF Scorecard OpenSSF Baseline npm license Contributor Covenant

Open OOXML Office  ·  The suite  ·  Quick start  ·  What is here  ·  Development  ·  Roadmap  ·  Discussions  ·  Contributing

PowerPoint
The PowerPoint editor
Demo · Docs · README
Word
The Word editor
Demo · Docs · README
Excel
The Excel editor
Demo · Docs · README
Visio
The Visio viewer
Demo · Docs · README
OpenTeams
The OpenTeams workspace
Demo · Docs · README
OOXML Office
OOXML Office: one workspace for every app
Open the app · About · README

Select a product to open its README.

Why ooxml?

  • Everything runs client-side. Files never leave the user's machine: no Office install, no conversion service, no native binaries. The same library runs in browsers, Node.js, Bun, workers and serverless functions.
  • One model for every format. Word, PowerPoint, Excel and Visio share one XML model, packaging layer, units, colours and geometry. Each format is an area of one package, not a dependency to keep in step.
  • Round-trips without losing what it does not understand. Untouched parts stay byte-for-byte, unknown markup is preserved, and edits that would damage unsupported content are rejected instead of silently dropped.
  • Real editors, not only viewers. Ribbons, grids, a formula engine (480+ functions), undo and redo, find and replace and real-time co-editing over Yjs, as web components with thin bindings for React, Vue, Angular, Svelte, Solid and plain JavaScript.
  • Password-protected and legacy files. Open and save ECMA-376 encrypted packages, and read legacy .doc, .xls and .ppt through the sibling ole2 codecs.
  • AI ready. MCP servers let Claude, Cursor and other agents read and edit documents through the same code the editors use.
  • Honest about its limits. Unsupported features are reported, never hidden, and nothing here claims Office parity or lossless export without evidence.

OOXML Office: the whole suite in one app

OOXML Office is the integrated application built from everything in this repository. It mounts the real Word, Excel, PowerPoint, Visio and OpenTeams editors (the same components the npm packages ship, not demo iframes) in one workspace with tabs, so you can move between a document, a workbook, a deck and a team conversation without losing your place.

The start chooser: open the whole suite, or Word, Excel, PowerPoint, Visio or Teams on its own

The first time you open it, it asks how you want to work:

  • OOXML Office: every app in one workspace, with a shared file library, one tab per open document, an app launcher, search and one assistant pane.
  • One product on its own: Word, Excel, PowerPoint, Visio or Teams, each on its own site with its documentation and framework demos.

What the suite gives you:

  • One local library. Import .docx, .xlsx, .pptx and .vsdx files, or create blank documents, workbooks, presentations and drawings. Files stay in your browser's IndexedDB (or the desktop app's WebView); nothing is uploaded, and Download always gives you the saved bytes.
  • Live tabs. A document opens in one editor tab, and edits survive switching apps. Tabs close, close others and close to the right like a desktop app, saving first.
  • Office files in Teams. Share a document in an OpenTeams channel, reopen it in its editor from the conversation and return to the channel. With a configured Teams server, files go through its storage.
  • Embedded documents. Open the Office packages embedded in a parent document, edit them, and save child and parent together.
  • An assistant across files. Pick files (and optionally the current conversation) and get bounded edit proposals you review, apply and undo. It talks to your own OpenAI-compatible endpoint, and nothing is applied without you.
  • Profiles and appearance. Local profiles with separate libraries, plus Light, Dark and System appearance and accent themes shared by every editor.
  • Install it. The root installs as a PWA, and each product also installs on its own (/apps/word/, /apps/excel/, /apps/powerpoint/, /apps/visio/, /apps/teams/), sharing one profile and library on the same origin. A desktop build (Tauri) wraps the same bundle and adds a native folder picker.

Its boundaries are written down: profiles are local conveniences, not sign-in; there is no cloud drive or Microsoft 365 integration; and document co-authoring is not wired to suite files yet. The full list is in suite integration. The source is the private apps/office-suite package; run it locally with bun run build:suite && bun run preview:suite.

The products

Each product name opens its README, with install steps and a snippet for every framework.

Product Live demo Install What you get
PowerPoint Demo npm i pptx-react-viewer React, Vue, Angular, Svelte and vanilla bindings, with editing, presenting and collaboration
Word Demo npm i docx-react-viewer <docx-editor>; React, Vue, Angular, Svelte, Solid and vanilla bindings
Excel Demo npm i @christophervr/xlsx-react-viewer <xlsx-editor>; the same six bindings
Visio Demo npm i visio-react-viewer A local-first viewer; the same six bindings
OpenTeams Demo npm i openteams-react-viewer A bring-your-own-server workspace: chat, calls and shared Office files
OOXML Office Open not published The integrated suite above, as a web app, installable PWAs and a desktop build
Headless npm i ooxml-core Parse, edit, validate and write every format, with no UI
AI agents npm i ooxml-mcp One MCP server for every format

Quick start

Headless: open a Word document, change it, save it

import { loadDocx } from 'ooxml-core/docx';

const loaded = await loadDocx(bytes); // Uint8Array | ArrayBuffer
loaded.model.blocks; // paragraphs and tables
const edited = await loaded.save(); // original package parts are preserved

An editor in your app (React shown; every framework has the same shape)

import { useState } from 'react';
import { createDocument, WordEditor } from 'docx-react-viewer';

export function Editor() {
	const [model, setModel] = useState(() => createDocument());
	return <WordEditor documentModel={model} onDocumentChange={setModel} />;
}

Each product's README has the snippet for every framework: PowerPoint, Word, Excel, Visio and OpenTeams. The library's areas and API are in the ooxml-core README, and the MCP server has its own setup.

How it fits together

pptx-*-viewer       ┐
docx-*-viewer       │
xlsx-*-viewer       │  framework bindings: lifecycle and events only
visio-*-viewer      ├── ooxml-ui ──┐   Lit web components: ribbons, grids, dialogs (DOM only)
openteams-*-viewer  ┘              │
                                   ├── ooxml-core ──┬── ole2 (legacy binary codecs)
ooxml-mcp ─────────────────────────┘   (all logic)   ├── emf-converter
                                                      └── mtx-decompressor
  • ooxml-core owns the logic: packaging, XML, every format's model, parser, writer and editing commands, layout, validation and collaboration. It has no UI.
  • ooxml-ui owns the DOM: the shared elements and the product editors as ooxml-ui/<product> subpaths. The core never imports it.
  • Viewers own only the framework bindings, demos, end-to-end tests and docs. They never copy logic from the library.

What is in this repository

The logic of every Office product lives in this repository, and so do the interfaces for PowerPoint, Word, Excel, Visio and OpenTeams. They are all members of one Bun workspace with one lockfile. Each folder below links to its own README.

Folder Published as What it is
src/core ooxml-core The library: every format's model, parser, writer, editing commands, layout and the shared areas under them. No UI. Its README is the package's npm page.
src/ui ooxml-ui The shared browser elements (Lit web components): ribbons, dialogs, menus, the title and status bars, and the Word, Excel, Visio and OpenTeams editors as ooxml-ui/<product> subpaths. DOM only; the core never imports it.
mcp/ ooxml-mcp The combined MCP server that lets an AI assistant work with Office documents.
viewers/pptx PowerPoint packages (below) The PowerPoint editor and its bindings for React, Vue, Angular, Svelte and vanilla JavaScript, its CLI and MCP tools. Docs and demos.
viewers/docx Word packages (below) The Word editor (<docx-editor>) and its bindings for React, Vue, Angular, Svelte, Solid and vanilla JavaScript. Docs and demos.
viewers/xlsx Excel packages (below) The Excel editor (<xlsx-editor>) and its bindings. Docs and demos.
viewers/visio Visio packages (below) The local-first Visio viewer and its bindings. Docs and demos.
viewers/teams OpenTeams packages (below) A bring-your-own-server team workspace (channels, chat, calls, shared Office files), its bindings and a reference server. Docs and demos.
apps/office-suite not published The OOXML Office application: the integrated suite, the standalone PWAs and the desktop frontend.
site/ not published The HTML and CSS shell of the app at https://christophervr.github.io/ooxml/. Each viewer's documentation and demos are built into the same site, under /pptx/, /docx/, /xlsx/, /visio/ and /teams/.
Every published package

The viewers keep only what is specific to a framework: the bindings, demos, end-to-end tests and docs. Format logic stays in src/core/, and a viewer must not copy it.

Fidelity and compatibility

These are early implementations. They are approximations of the Office applications, not parity, and saving is not lossless for content a model does not cover. Features a product does not support are reported rather than hidden, and each viewer's docs list its known gaps (Word, Excel, Visio). The roadmap says what comes next.

Development

You need Bun and Node.js 22 or newer. One install at the root sets up the library, the UI and every viewer.

bun install
bun run typecheck      # strict project and the pptx project
bun run test           # the library's unit tests
bun run build          # the library
bun run test:package   # packs the build and imports every entry point from a clean install

The viewers resolve ooxml-ui to the copy in this workspace through its built dist, so build the library and the UI before working on one:

bun run build && bun run --cwd src/ui build
cd viewers/docx        # or pptx, xlsx, visio, teams
bun run typecheck && bun run test
bun run demo           # docx, xlsx: the demo app (visio, teams: bun run dev)

Each viewer has its own scripts and browser tests; the root typecheck, test, fmt and lint do not cover viewers/. CI (.github/workflows/ci.yml) decides from the files a change touches what to run, including which viewers to verify.

Releases are automated. Every published package has its own version and tag (<npm-name>@<version>), planned from conventional commits, with changelogs and npm publishing through trusted publishing (OIDC, with provenance). See docs/releasing.md. Commits must follow Conventional Commits, and nobody publishes or tags by hand.

The working agreements are in AGENTS.md, and PROVENANCE.md records where each module came from.

Documentation and related projects

  • The viewers, in this repository under viewers/ (pptx, docx, xlsx, visio, teams): the editors and viewers built on this package.
  • OOXML Office: the integrated suite (apps/office-suite, with its shell in site/). Each viewer's docs and demos are built into the same site.
  • ole2: the compound-file container and legacy binary Office codecs.
  • emf-converter and mtx-decompressor: EMF/WMF rendering and embedded-font (MicroType Express) decompression, used by the library.

Community and support

  • Questions and usage help: ask in Discussions, Q&A and mark the answer that solved it.
  • Ideas: talk them through in Ideas; agreed ones become feature requests.
  • Built something? Share it in Show and tell.
  • Bugs and fidelity gaps: open an issue, ideally with a sample file.
  • Security problems: report them privately, see SECURITY.md.

License

Apache-2.0. Third-party notices are in NOTICE and THIRD-PARTY-LICENSES.

About

All the logic behind the Office viewers (DOCX, PPTX, OPC, XML, DrawingML shapes): one package, ooxml-core

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

10 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages