Browser editor and framework-neutral engine for OOXML .docx documents.
English · 简体中文 · Português (Brasil)
stella · npm · Issues · Discord
Folio is an embeddable Word-document editor for web applications. Pass it a
.docx as a File, Blob, ArrayBuffer, or Uint8Array; it renders editable,
paginated content in the browser and returns a .docx when the user saves.
Use the React, Vue, or Nuxt editor in an application, or use folio-core
directly for parsing, editing, layout, and document review without a UI.
bun add @stll/folio-react react react-dom use-intl@stll/folio-core is installed with the React editor.
import { useState } from "react";
import { IntlProvider } from "use-intl";
import { DocxEditor } from "@stll/folio-react";
import { getFolioMessages } from "@stll/folio-react/messages";
import "@stll/folio-react/standalone.css";
const DOCX_MIME = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
const downloadDocx = (buffer: ArrayBuffer) => {
const url = URL.createObjectURL(new Blob([buffer], { type: DOCX_MIME }));
const link = document.createElement("a");
link.href = url;
link.download = "edited.docx";
document.body.append(link);
link.click();
link.remove();
URL.revokeObjectURL(url);
};
export function Editor() {
const [file, setFile] = useState<File | null>(null);
return (
<IntlProvider locale="en" messages={getFolioMessages("en")}>
<input
type="file"
accept=".docx"
onChange={(event) => setFile(event.currentTarget.files?.[0] ?? null)}
/>
{file && <DocxEditor documentBuffer={file} author="Editor" onSave={downloadDocx} />}
</IntlProvider>
);
}The editor toolbar calls onSave with the updated DOCX bytes. You can also hold
a DocxEditorRef and call await editorRef.current?.save() yourself.
- Paginated text, formatting, lists, tables, images, sections, headers, and footers
- Comments, footnotes, and tracked changes that Microsoft Word can review, accept, or reject
- DOCX round trips that preserve untouched package parts and unsupported OOXML
- Editing modes, find, page setup, document outline, and save hooks
- Bundled messages for 17 locales, including right-to-left editor chrome
| Package | Choose it when you need |
|---|---|
@stll/folio-react |
The complete editor as a React component |
@stll/folio-vue |
The complete editor as a Vue 3 component |
@stll/folio-nuxt |
SSR-safe registration of the Vue editor in Nuxt 3 or 4 |
@stll/folio-core |
DOCX parsing, ProseMirror editing, page layout, review, or redline APIs |
@stll/docx-core |
The typed OOXML model, validation, serialization, and projection kernel |
@stll/folio-agents |
Tools that read documents and propose comments or tracked changes |
@stll/folio-cli |
A command line and MCP server that review .docx files on disk |
Install the Vue editor with bun add @stll/folio-vue vue, the Nuxt module with
bun add @stll/folio-nuxt, or the framework-neutral engine with
bun add @stll/folio-core.
Compare two DOCX files and write their differences as native tracked changes:
import { generateRedlineDocx } from "@stll/folio-core/redline";
const result = await generateRedlineDocx(originalDocx, revisedDocx, {
author: "Reviewer",
});
await store(result.buffer);For deterministic changes to one document, use FolioDocxReviewer. See the
folio-core review APIs.
- Use
standalone.cssby itself. Applications that already use Tailwind can instead follow theeditor.csssetup. - The editor requires the DOM. In an SSR application, load it from a client-only
component or dynamic import; Nuxt users can use
@stll/folio-nuxt. - Architecture and test methodology live in the DOCX platform boundary and interoperability guide. How folio keeps the reading of an OOXML sentinel in one place is in reserved values.
bun install
bun run build
bun run typecheck
bun run test
bun run lint
bun run validate-distPublished-package source changes require a Changeset.
Folio originated as a fork of Eigenpal's
docx-editor by
Jedr Blaszyk and is independently maintained as
part of stella. The original license and
copyright are preserved in NOTICE.md.

