Quickstart

Load, edit, and save a .docx in the browser with React or Vue in one file.

Build a browser editor that opens a local .docx and downloads the edited file.

Install the editor

Install an adapter and its engine peer:

npm install @docx-editor.dev/react @docx-editor.dev/core

This example runs in client-rendered apps such as Vite. In Next.js, Nuxt, Remix, or Astro, render the editor on the client only. See Installation.

Load and save a document

This component reads a file input, edits the document, and downloads the result:

// App.tsx
import { useRef, useState } from 'react';
import { DocxEditor, type DocxEditorRef } from '@docx-editor.dev/react';
import '@docx-editor.dev/core/styles/editor.css';

export default function App() {
  const editorRef = useRef<DocxEditorRef>(null);
  const [file, setFile] = useState<File | null>(null);
  const [bytes, setBytes] = useState<Uint8Array>();

  async function pick(e: React.ChangeEvent<HTMLInputElement>) {
    const picked = e.target.files?.[0] ?? null;
    setFile(picked);
    setBytes(picked ? new Uint8Array(await picked.arrayBuffer()) : undefined);
  }

  async function download() {
    const buffer = await editorRef.current?.save();
    if (!buffer) return;
    const blob = new Blob([buffer], {
      type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = file?.name ?? 'document.docx';
    a.click();
    URL.revokeObjectURL(url);
  }

  return (
    <div style={{ height: '100vh', display: 'flex', flexDirection: 'column' }}>
      <div style={{ padding: 8, display: 'flex', gap: 8 }}>
        <input type="file" accept=".docx" onChange={pick} />
        <button onClick={download}>Download .docx</button>
      </div>
      <div style={{ flex: 1, minHeight: 0 }}>
        {bytes && <DocxEditor ref={editorRef} document={bytes} mode="edit" />}
      </div>
    </div>
  );
}

Parsing, editing, and serialization run in the browser. The editor does not upload the document anywhere.

Check the required options

OptionValuesNotes
documentUint8Array, ArrayBuffer, DocumentHandle, or 'blank''blank' opens an empty document. An omitted document means no document: the editor shows its loading screen, and editing controls stay unavailable until a document loads. File > Open works once the editor instance exists.
mode'edit' (default), 'view', or 'suggesting'Changes apply without a remount. 'suggesting' requires a review module and a nonempty author.
save() on the refPromise<ArrayBuffer | null>Returns a complete .docx, or null when no document is loaded.
Stylesheet@docx-editor.dev/core/styles/editor.css (React) or @docx-editor.dev/vue/styles.css (Vue)Import it once per app.
Container heightAny nonzero CSS heightThe editor fills its parent. A parent without a height collapses.

Limits

  • The packaged <DocxEditor> shows a document page with loading status while a document opens.
  • To handle the built-in File > Save action, use onSave (React) or @save (Vue). The handler replaces the packaged action, so read the bytes through the ref.
  • Tracked changes and comments require @docx-editor.dev/pro.
  • To load from a URL or autosave, see Loading and saving.

Next steps