@docen/docx
v0.3.0
Published
DOCX editor and converter powered by @office-open/docx with Tiptap editing layer, supporting bidirectional conversion between DOCX, HTML, and Markdown
Maintainers
Readme
@docen/docx
DOCX editor and converter powered by @office-open/docx with Tiptap editing layer, supporting bidirectional conversion between DOCX, HTML, and Markdown.
Features
- 📝 Tiptap Editor — Full-featured WYSIWYG editor with DOCX-aware extensions
- 🔄 DOCX Round-trip — Near-lossless DOCX ↔ Editor conversion via @office-open/docx
- 🌐 HTML Conversion — Bidirectional Tiptap JSON ↔ HTML (editor path + standalone)
- 📄 Markdown Support — Tiptap JSON ↔ Markdown conversion
- 🎨 DOCX Properties — Custom Tiptap extensions carry shading, borders, indent, spacing, floating, crop
- 🔗 Template Patching — Replace
{{placeholders}}in DOCX templates with Tiptap-JSON content
Installation
# Install with pnpm
$ pnpm add @docen/docx
# Install with npm
$ npm install @docen/docxQuick Start
import { createDocxEditor, docxExtensions, parseDOCX, generateDOCX } from "@docen/docx";
// Create editor
const editor = createDocxEditor({
element: document.querySelector("#editor"),
});
// Load a DOCX file
editor.commands.setContent(parseDOCX(buffer));
// Save back to DOCX
const output = await generateDOCX(editor.getJSON());API
Standalone Functions (Core)
These work without an editor instance — for headless/server/batch use.
import {
parseDOCX,
generateDOCX,
generateDOCXSync,
generateDOCXStream,
parseHTML,
generateHTML,
parseMarkdown,
generateMarkdown,
} from "@docen/docx";
// DOCX pipeline: DOCX binary ↔ Tiptap JSON
const json = parseDOCX(buffer); // → JSONContent
const buffer = await generateDOCX(json); // → Buffer (pre-fetches http images by default)
const blob = await generateDOCX(json, { packer: { type: "blob" } }); // → Blob
const sync = generateDOCXSync(json); // → Buffer (skips prepare)
const stream = await generateDOCXStream(json); // → ReadableStream<Uint8Array>
// HTML pipeline: HTML string ↔ Tiptap JSON
const json = parseHTML("<p>Hello</p>"); // → JSONContent
const html = generateHTML(json); // → string
// Markdown pipeline: Markdown string ↔ Tiptap JSON
const json = parseMarkdown("# Hello"); // → JSONContent
const md = generateMarkdown(json); // → stringEditor
import { createDocxEditor, docxExtensions } from "@docen/docx";
const editor = createDocxEditor({
element: document.querySelector("#editor"),
extensions: docxExtensions,
spellcheck: true,
editable: true,
});Extension Commands (Thin Wrappers)
Convenience commands that call standalone functions internally.
// Load DOCX into editor (calls parseDOCX → setContent)
editor.commands.importDocx(buffer);
// Export editor content as DOCX (calls getJSON → generateDOCX)
const buffer = await editor.commands.exportDocx();Template Patching
Replace {{placeholders}} in a DOCX template with Tiptap-JSON content. Each
patch's content is prepared (default: fetch http images) then compiled to DOCX.
import { patchDOCX, parseHTML } from "@docen/docx";
const result = await patchDOCX({
template: templateBuffer,
patches: {
title: { content: parseHTML("<h1>Report</h1>") },
},
outputType: "nodebuffer",
});Advanced: Model Bridge
generateDOCX runs prepareDocument → compileDocument → generateDocument
internally. You rarely need these directly — reach for them only when working
with the intermediate DocumentOptions (the OOXML persistence model):
import { resolveDocument, compileDocument, prepareDocument } from "@docen/docx";
const json = resolveDocument(docOpts); // DocumentOptions → JSONContent
const docOpts = compileDocument(json); // JSONContent → DocumentOptions
await prepareDocument(json); // in place: http image URLs → data URLsArchitecture
Standalone Functions (core)
parseDOCX / generateDOCX / generateDOCXSync / generateDOCXStream / patchDOCX
parseHTML / generateHTML / parseMarkdown / generateMarkdown
resolveDocument / compileDocument / prepareDocument (model bridge, advanced)
↕ used by
Tiptap Extension Commands (thin wrappers)
editor.commands.importDocx() / exportDocx()
↕ used by
@docen/ui (Fluent UI Web Components)
<docx-editor> toolbar / ribbon / menus- Runtime model: Tiptap JSON with DOCX-rich attributes via custom extensions
- Persistence model: DocumentOptions (complete OOXML expressiveness)
- Standalone functions are core — extension commands are thin wrappers
