* Tests: shapes and pictures can be clicked, resized, dragged and nudged Fixed by #46 but only text boxes were covered. These walk the editor's path for shapes (rectangle, ellipse, star, arrow) and pictures: hit test, select, resize with arrange.bounds, drag to float with Square wrap, nudge, undo. Covers #142 and #82. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Font list offers every weight a family installs, named as Word names them (#219) Fonts were listed and matched only by their typographic family name (name ID 16, e.g. "Roboto"), so a face other than Regular, Bold or Italic (Light, Medium, SemiBold, Black, Condensed...) never appeared in the font list, and a document asking for "Roboto Light" fell back to a substitute. Each face now also carries its legacy family name, the one Word lists and stores in documents: name ID 1 for static fonts ("Source Sans 3 Semibold"), or the family plus the style words other than Regular, Bold and Italic for a variable font's named instances ("Inter Light"). The font list includes these names, has_family and face() resolve them (bold and italic still choose or synthesise within the faces the name covers), and asking for a legacy name loads the whole installed family. The system font scan now also reads fvar, so a variable font's instances are listed before it is loaded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Absolutely positioned VML text boxes float instead of sitting inline (#149) A legacy VML shape (w:pict > v:shape / v:rect) with position:absolute in its style was read as an inline object, so a tall text box in a header made the header as tall as the box and pushed the body down the page. The reader now maps the VML style to the same float model DrawingML anchors use: left/margin-left and top/margin-top offsets, mso-position-*-relative reference areas, mso-position-horizontal/vertical alignment, mso-wrap-distance-* and w10:wrap (square, tight, through, topAndBottom; none or absent is in front of the text, or behind it at a negative z-index). Shapes without position:absolute stay inline. Saving writes the boxes as DrawingML anchors with the same placement. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Reject All removes paragraph breaks inserted with Track Changes on (#229) Enter under Track Changes already recorded the new paragraph mark as an insertion, but accepting or rejecting only cleared that flag, so Reject All left the paragraphs split. Rejecting an inserted mark (or accepting a deleted one) now joins the paragraph with the next one again; Accept All, Reject All, Accept/Reject at the caret or over a selection, Next/Previous Change and the Reviewing Pane all see paragraph marks. Backspace at a paragraph start and Delete at a paragraph end now record a tracked deletion of the mark (or remove a mark the same author inserted) instead of only moving the caret; tracked deletions across paragraphs mark the paragraph marks too. DOCX reads and writes paragraph-mark revisions (w:ins / w:del in the mark's w:rPr), and a tracked mark is drawn in its author's colour when formatting marks are shown. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Table Layout: Text Direction turns cell text (#226) The Text Direction button only flipped a flag that layout and rendering ignored (and docx always wrote it as btLr), so pressing it did nothing visible. Cells now carry a text direction (horizontal, top-to-bottom tbRl, bottom-to-top btLr). The button cycles through them like Word's, for every selected cell. Layout runs turned text along the cell's height: an exact row height sets the line length, otherwise the row grows to fit the unwrapped text. Turned lines are drawn in a turned frame on screen and in PDF, and clicks, caret, and selection follow the turn. docx reads and writes w:textDirection with the matching value. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * File dialogs no longer freeze the window on Linux (#94) Open, Save As, Export and Insert/Change Picture used rfd's blocking FileDialog on the UI thread with no parent window. On Linux the xdg-desktop-portal call blocked the event loop until the dialog closed, and the unparented dialog could open behind WordCraft, so the app looked frozen. The desktop app now shows rfd::AsyncFileDialog parented to the window (set_parent with eframe's Frame, no unsafe) and waits for the answer on a background thread, which hands it back through a channel and wakes the UI. ui-egui gains a backend-agnostic Services::file_dialog hook: the app remembers what the dialog was for and finishes it when the answer arrives (open the file, save, export, insert or change the picture, turn AutoSave on). "Save changes?" -> Save on a new document now runs the held-back New/Open/Close only once the later Save As has saved; a cancelled Save As cancels it. Only one file dialog is open at a time; further clicks are ignored until it is answered. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Chinese interface: embed the Chinese UI font in releases, fall back to an installed one (#241) The release workflow pinned storytold/craft-fonts at abb8331, the commit that added the Japanese fonts. Noto Sans CJK SC came one commit later (8dcdacd), so release builds embedded only the Japanese faces and the Simplified Chinese interface fell back to BIZ UDPGothic, which lacks about 157 simplified-only hanzi (页, 选, 删 …) and drew them as boxes. Document text was unaffected because it uses the system font fallback. - Bump the craft-fonts pin in the release and FreeBSD workflows to 8dcdacd. - With CRAFT_FONTS_REQUIRED, a native build now fails when the craft-fonts manifest has no Jpan or Hans font, so an outdated pin can't ship silently again. - When no embedded face covers the interface language, the UI font families get an installed CJK font (desktop only): a short per-platform list of files in the system font folders (Windows Deng/msyh/simhei/simsun, macOS PingFang/STHeiti, Linux Noto Sans CJK/WenQuanYi), header-checked, size-capped, and the face chosen by coverage (a SC face in a pan-CJK collection), so egui never sees a file it can't parse. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Add a System interface theme that follows the OS appearance (#115) The interface theme is now a three-way choice: Use system setting, Light or Dark, in File > Options > General and in a new Interface Theme menu in View > Dark Mode. System follows the light/dark appearance egui reports (winit on macOS, Windows and Linux; prefers-color-scheme on the web) at launch and live, and falls back to light when the OS reports none. egui's own theme is now pinned to ours, so an OS change no longer swaps in egui's unstyled style. Saved preferences migrate: the old "dark" switch becomes Dark or Light and is never written again. Light stays the default for new installs. New ui.theme command (light/dark/system); ui.dark still sets Light/Dark. The dark page (View > Switch Modes) is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * #248: read the installed CJK UI font only when CJK text is shown A build without craft-fonts read a large system CJK font on the first frame even for an English interface. Now it is loaded only for a CJK interface language, or once File > Options shows the language list (names in their own scripts). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <echelon@gmail.com> |
||
|---|---|---|
| .cargo | ||
| .github/workflows | ||
| apps | ||
| assets | ||
| contributors | ||
| crates | ||
| docs | ||
| packaging | ||
| xtask | ||
| .gitignore | ||
| .shellcheckrc | ||
| AGENTS.md | ||
| ATTRIBUTION.md | ||
| CLAUDE.md | ||
| Cargo.lock | ||
| Cargo.toml | ||
| LICENSE-APACHE | ||
| LICENSE-MIT | ||
| NOTICE | ||
| README.md | ||
| ROADMAP.md | ||
| clippy.toml | ||
| rustfmt.toml | ||
README.md
WordCraft
Writing and document design; an open-source, clean-room reimplementation of Microsoft Word, rebuilt in pure Rust.
A fast, open-source word processor with the Word workflow you already know: the ribbon, styles,
tables, track changes, references and mail merge. It reads and writes .docx, runs natively on
macOS, Windows, Linux and BSD, and in the browser via WebAssembly.
By the ArtCraft team.
WordCraft on getartcraft.com · ArtCraft · All Crafting Apps
The Open Studio Handbook, WordCraft's built-in sample: the ribbon, live Styles gallery, rulers and the Navigation pane.
[!NOTE] ArtCraft is a community of artists from all walks of life. Painters, photographers, filmmakers, illustrators, designers, animators, hobbyists, and people who picked up a pencil last week. If you make things, you're one of us. Come say hi on Discord.
A tour · Why WordCraft · What works today · Quick start · For agents · Architecture · Roadmap · Downloads · The Crafting Apps · License and credits
A tour
Every screenshot below is WordCraft itself, rendered offscreen by its own UI test harness
(cargo run -p wordcraft-ui-egui --example ui_shot).
![]() Review. Track changes, comment balloons in the margin, accept and reject, spelling and grammar as you type. |
![]() References. Tables of contents, footnotes, citations in APA, MLA, Chicago or IEEE, index and captions. |
![]() Design. Themes, style sets, paragraph spacing, watermarks, page colour and borders. |
![]() Dark mode with formatting marks, and the Insert tab: tables, pictures, shapes, links, headers, footers, fields and symbols. |
![]() Layout. Drop caps, text wrapping around pictures and shapes, automatic hyphenation, line numbers and page borders. |
|
![]() File. Start from a template, open recent documents, edit properties, export to PDF and other formats. |
|
Why WordCraft
- Familiar. Word's ribbon tabs, groups, shortcuts and behaviour: Enter continues a list, Tab demotes it, Ctrl/⌘+B bolds the word under the caret, the Styles gallery previews styles live, F4 repeats, F7 checks spelling, F8 extends the selection.
- Your files. Opens and saves .docx (OOXML), and also .odt, .rtf, .html, .md, .tex (LaTeX), .txt; opens Word 97-2003 .doc; exports PDF with real, selectable text, links and bookmarks.
- Fast. Paragraph layout is cached, so typing in a 188-page document re-lays it out in about 1.4 ms; pages render on demand.
- Everywhere. One Rust codebase for macOS, Windows, Linux, BSD and the web. No Electron, no Tauri: native egui on the GPU.
- Built for agents. Every action is a command with an id. The same 389 commands drive the ribbon, keyboard shortcuts, the command search, a command-line tool, a JSON control channel and an MCP server.
- Private. Spelling, grammar and everything else work offline.
- Open. MIT OR Apache-2.0. Clean-room: built from public specifications and observation, with every asset original or openly licensed.
What works today
| Area | Highlights |
|---|---|
| Writing | Fast typing with IME, smart quotes, AutoCorrect, list autoformat (* , 1. ), dashes; word, sentence, paragraph selection; drag-select; clipboard with formatting; undo/redo; find and replace with regex |
| Formatting | Fonts, sizes, bold/italic/underline styles, strike, sub/superscript, caps, highlight, colours, character spacing, Format Painter, Change Case, Clear Formatting |
| Paragraphs | Alignment, indents (draggable on the ruler), spacing, line spacing, tabs with leaders, borders, shading, keep with next, widow/orphan control |
| Styles | Built-in style set, live gallery, Styles pane, create/modify/update styles, style sets, themes |
| Lists | Bullets, numbering, multilevel, restart, set value, custom formats |
| Tables | Insert by grid, merge/split, styles with banded rows, borders, shading, header rows repeated across pages, rows that split across pages, sort, formulas, text ↔ table |
| Pages | Margins, orientation, size, columns, page/column/section breaks, headers and footers (first page, odd/even), page numbers, watermark, page borders, line numbers, vertical alignment, drop caps, automatic hyphenation |
| Objects | Pictures (resize, crop, recolour, brightness/contrast, transparency, background removal, picture styles, rotate), shapes, text boxes, floating position with text wrapping (square, top and bottom, behind or in front of text) |
| References | Table of contents, footnotes and endnotes, citations and bibliography (APA, MLA, Chicago, IEEE), captions, table of figures, cross-references, index, table of authorities |
| Review | Spelling and grammar with suggestions, thesaurus, word count, comments in margin balloons or a pane, track changes, accept/reject, compare documents, restrict editing, accessibility checker, document inspector |
| Mailings | Mail merge from CSV, merge fields, address block, greeting line, rules, preview, finish to a document; envelopes and labels |
| View | Print layout, web layout, draft, read mode, focus, zoom, one/multiple pages, page width, Navigation pane, rulers, gridlines, dark mode; interface in English, 简体中文, 繁體中文, 日本語, Português (Brasil), Español or Українська (follows the system language by default) |
| Files | .docx read/write (opens in Word), Word 97-2003 .doc import, PDF export, .odt, .rtf, .html, .md, .tex, .txt import/export, page images |
The honest picture, area by area, is in ROADMAP.md and the generated feature parity report.
Quick start
git clone https://github.com/storytold/wordcraft
cd wordcraft
cargo run --release -p wordcraft -- --sample # the desktop app with the sample document
cargo run --release -p wordcraft -- report.docx # open a document
Command line:
wordcraft-cli convert report.docx report.pdf # docx, pdf, odt, rtf, html, md, tex, txt, png
wordcraft-cli text report.docx # plain text
wordcraft-cli inspect report.docx # structure as JSON
wordcraft-cli run --template sample \
--cmd 'select.text={"text":"Membership"}' --cmd format.bold --save out.docx
Web: cd apps/wordcraft-web && trunk serve, then open http://127.0.0.1:8771/?sample.
For agents: CLI and MCP
WordCraft was designed to be driven by people and by AI agents.
claude mcp add wordcraft -- wordcraft-cli mcp # headless documents
wordcraft --control 7981 & # or drive the running app…
claude mcp add wordcraft-app -- wordcraft-cli mcp --connect 127.0.0.1:7981
Tools include list_commands, execute, batch, type_text, select_text, inspect_document,
render_page, save_document, and, with a running app, screenshot, click and key. Agents
can check their work through inspect_document without screenshots. See docs/mcp.md
and the control protocol. Macros record any sequence of commands and
play it back (tools.recordMacro, tools.macros).
Logs
The desktop app writes its log records to standard error and to logs/wordcraft.log next to its
preferences: on Linux $XDG_CONFIG_HOME/wordcraft/logs/ (by default ~/.config/wordcraft/logs/),
on macOS ~/Library/Application Support/WordCraft/logs/, on Windows %APPDATA%\WordCraft\logs\.
A start from a desktop menu or the Dock has no terminal, so this file is what to attach to a bug
report: unreadable parts of a .docx, pictures or fonts a PDF export had to leave out and panics the
command guard recovered from land there. Each launch moves the previous log to wordcraft.1.log
(and that one to wordcraft.2.log), so the log of a run that crashed survives the next start; a
log stops growing at 16 MiB. --version writes no file, and runs with WORDCRAFT_NO_PREFS (agents'
test runs) log to standard error only. Document text is never logged; a panic message leaves out
the text it quotes.
By default WordCraft's own crates log at info and everything else at warn. RUST_LOG replaces
that with env_logger-style directives, for example RUST_LOG=debug,
RUST_LOG=warn,wordcraft_docx=trace or RUST_LOG=info,wgpu_core=warn; a directive ending in *
covers every target starting with it (wordcraft*=debug). The logger is
apps/wordcraft/src/logging.rs.
Architecture
| Layer | Crate | Job |
|---|---|---|
| L0 | wordcraft-geom |
units and measurements |
| L1 | wordcraft-doc, wordcraft-fonts, wordcraft-proof |
document model and editing; fonts and shaping; spelling, grammar, hyphenation |
| L2 | wordcraft-layout, wordcraft-docx, wordcraft-formats |
line breaking, pagination, tables, notes, hit testing; OOXML; ODT/RTF/HTML/Markdown/TXT |
| L3 | wordcraft-render, wordcraft-pdf |
rasteriser (vello_cpu); PDF (krilla) |
| L4 | wordcraft-engine |
session, undo, 389 commands, Word feature catalog |
| L5 | wordcraft-mcp |
MCP server |
| L6 | wordcraft-ui-egui |
the Word-style front end (swappable) |
| apps | wordcraft, wordcraft-cli, wordcraft-web |
desktop, command line, browser |
cargo xtask ci runs formatting, clippy, ~250 tests, the asset-attribution check, the layering
check and the wasm build. Contributor and agent instructions: AGENTS.md.
Roadmap
WordCraft covers 87% of Word's ribbon features with commands today; counting depth and fidelity, we estimate about 62% of real feature parity. An alpha for everyday writing is close: the remaining work is mostly testing against real-world .docx files, native printing and the first signed builds. Charts, SmartArt, the equation editor and the Draw tab come after. Details and estimates: ROADMAP.md.
Downloads
Download WordCraft from GitHub: the latest release has every build listed below, and all releases has earlier versions and their notes. <ver> in the file names is the version number, and SHA256SUMS.txt lists a checksum for every file.
Windows
| Build | Installer | Portable |
|---|---|---|
| x64 (64-bit Intel/AMD) | wordcraft-<ver>-windows-x64.msi |
wordcraft-<ver>-windows-x64-portable.zip |
| arm64 (Snapdragon and other ARM PCs) | wordcraft-<ver>-windows-arm64.msi |
wordcraft-<ver>-windows-arm64-portable.zip |
| x86 (32-bit) | wordcraft-<ver>-windows-x86.msi |
wordcraft-<ver>-windows-x86-portable.zip |
Installers and executables are code-signed.
If the app doesn't open on Windows: the desktop app initializes only DirectX 12 by default.
Letting wgpu also create an OpenGL instance can crash some graphics drivers (AMD's
atio6axx.dll) before the window appears, so the app would flash in Task Manager and quit.
WGPU_BACKEND overrides the default for troubleshooting (for example dx12 or vulkan). In
PowerShell, from the folder containing the executable:
$env:WGPU_BACKEND = "vulkan"
& .\wordcraft.exe
Remove-Item Env:WGPU_BACKEND # restore the default for later launches
An explicit gl override can bring the driver crash back on affected systems. The macOS, Linux
and web backend defaults are unchanged.
macOS
| Build | File | Notes |
|---|---|---|
| App, universal (Apple silicon + Intel) | wordcraft-<ver>-macos-universal.dmg |
Signed and notarized |
| Command-line tool, universal | wordcraft-cli-<ver>-macos-universal.zip |
Signed and notarized |
Linux
| Format | x86_64 | aarch64 (ARM64) | Notes |
|---|---|---|---|
| AppImage | wordcraft-<ver>-linux-x86_64.AppImage |
wordcraft-<ver>-linux-aarch64.AppImage |
Runs anywhere; updates itself with AppImageUpdate (.zsync files) |
| Flatpak | wordcraft-<ver>-linux-x86_64.flatpak |
wordcraft-<ver>-linux-aarch64.flatpak |
Sandboxed; flatpak install --user <file> |
| Debian/Ubuntu | wordcraft-<ver>-linux-x86_64.deb |
wordcraft-<ver>-linux-aarch64.deb |
|
| Fedora/RHEL/openSUSE | wordcraft-<ver>-linux-x86_64.rpm |
wordcraft-<ver>-linux-aarch64.rpm |
|
| Tarball | wordcraft-<ver>-linux-x86_64.tar.gz |
wordcraft-<ver>-linux-aarch64.tar.gz |
Unpack anywhere |
FreeBSD
| Build | File |
|---|---|
| x86_64 | wordcraft-<ver>-freebsd-x86_64.tar.gz |
Web (WebAssembly)
| Build | File | Notes |
|---|---|---|
| Static site | wordcraft-web-<ver>.zip |
Runs in a modern browser; host it on any static server |
The Crafting Apps
WordCraft is one of the Crafting Apps: free, open-source creative tools from the ArtCraft team, each written from scratch in Rust and each able to stand on its own.
| App | What it's for | Code | Learn more | |
|---|---|---|---|---|
| PhotoCraft | Image editing: layers, masks, type and real PSD files | GitHub | Website | |
| VectorCraft | Vector illustration | GitHub | Website | |
| FilmCraft | Video editing, color and sound | GitHub | Website | |
| LightCraft | Photo library and raw development | GitHub | Website | |
| PdfCraft | Reading, organizing and protecting PDFs | GitHub | Website | |
| EffectCraft | Motion graphics and visual effects | GitHub | Website | |
| DesignCraft | Page layout and publishing | GitHub | Website | |
| WordCraft | Writing and document design · you are here | GitHub | Website |
And ArtCraft itself, our AI image and video studio for artists who want real control.
Come make things with us
Our Discord is where artists of every kind hang out: people who paint, shoot, draw, cut film, set type, and people still figuring out what they like to make. Share what you're working on, ask for help, tell us what's broken, or tell us what you wish these tools could do. Whatever your medium and however long you've been at it, you're welcome here.
discord.gg/artcraft · getartcraft.com · The Crafting Apps · WordCraft
License and credits
WordCraft is dual-licensed under MIT or Apache-2.0, at your option. Copyright (c) 2026 ArtCraft Team and the WordCraft contributors. Required notices are in NOTICE.
Bundled fonts, icons, images and other assets keep their own open licenses; each one is listed with its author, source and license in ATTRIBUTION.md.
The spelling dictionary and hyphenation come from Grady Ward's public-domain Moby Hyphenator II word list. The sample documents and templates are original text written for WordCraft.
The ArtCraft name, wordmark and logos in docs/brand/ are trademarks of the
ArtCraft Team and are not covered by this license. They may be used only unmodified, and only as
part of this repository and WordCraft, under docs/brand/LICENSE-brand.txt.
Forks and modified versions must remove them.
Microsoft and Microsoft Word are trademarks of the Microsoft group of companies. Adobe, Photoshop, Illustrator, Premiere Pro, Lightroom, Acrobat, After Effects and InDesign are trademarks or registered trademarks of Adobe Inc. in the United States and/or other countries. WordCraft is an independent, open-source project and is not affiliated with, sponsored by or endorsed by Microsoft Corporation or Adobe Inc.; these names are used only to describe the workflows it is compatible with.
Made by the ArtCraft team and community.





