Skip to content

docx_plus

OOXML-level extensions for python-docx.

python-docx is an excellent library that stops at a well-defined boundary. Past that boundary — the style cascade, content controls, anchored comments, tracked changes, custom numbering, table borders — the usual answer is a StackOverflow snippet that reaches into element._p and builds raw lxml by hand. Everyone writing serious document automation ends up with a private, half-tested pile of that code.

docx_plus is that pile, done properly: typed, tested against documents Word itself authored, and schema-strict about where elements are allowed to go. It composes with python-docx rather than replacing it — you keep your Document object and reach for docx_plus only where you need to.

from docx import Document
from docx_plus.styles import resolve_effective_formatting

doc = Document("report.docx")

# "Why is this heading 13pt and blue?" — a question python-docx can't answer,
# because the value is inherited, not set on the paragraph at all.
resolved = resolve_effective_formatting(doc.paragraphs[0], include_provenance=True)

print(resolved.font_size)                # 13.0
print(resolved.provenance["font_size"])  # FormattingSource(layer='paragraphStyle',
                                         #                  style_id='Heading2', ...)
pip install docx-plus      # or: uv add docx-plus

Requires Python 3.10+. The only dependencies are python-docx and lxml. Current release: v0.6.2, published 2026-08-21 on PyPI.

Start here

  • Getting started

    Install, your first script, and the seven conventions that apply across every module. Read this first.

  • Guides

    One task-oriented page per capability — styles, forms, comments, tracked changes, tables, publishing, linting, and the rest.

  • Concepts

    Why the OOXML behaves the way it does, and why the library is shaped around it. The cascade, the parts model, the design commitments.

  • API reference

    Every public symbol, plus per-module pages with full signatures and docstrings generated from source.

Driving the library from an LLM coding agent? Point it at the agent skill instead of hand-feeding it the API. Working from a shell or CI? See the CLI.

Capabilities

Capability Detail Guide
Style cascade Effective formatting for any paragraph / run / cell through the full eight-layer cascade, with per-field provenance. Create, modify, and remap styles; materialise any of 107 latent Word built-ins. Styles
Content controls Text / dropdown / date / checkbox controls via FormBuilder; round-trip read and write of values. Forms
Comments Anchored comments with the body-side range markers python-docx skips, so "show in document" works. Threading — reply / resolve / reopen — plus durable ids and author presence. Comments
Tracked changes Mark runs as insertions / deletions, read revisions with author and timestamp, accept / reject, toggle track-changes mode. Tracked changes
Fields PAGE / NUMPAGES / DATE / STYLEREF and generic complex fields; mark fields dirty so Word recalculates on next open. Fields
Tables Table / row / cell borders and shading, merge and unmerge, w:hMerge normalization, direct-formatting reads. Conditional <w:tblStylePr> branches resolve the way Word applies them. Tables
Numbering Custom bullet and multi-level numbered list definitions, applied and restarted per paragraph. Numbering
Layout Multi-column sections, mid-document section breaks, distinct even/odd headers, line numbering, page borders. Layout
Bookmarks Paired body markers plus REF / PAGEREF cross-references. Bookmarks
Notes Footnotes and endnotes over the separate footnotes.xml / endnotes.xml parts; insert and edit in place. Notes
Publishing Table of Contents, figure / table captions via SEQ, Table of Figures. Publishing
Protection Form-fill, read-only, comments-only, or tracked-changes enforcement at the document level. Forms
Lint Audit a document for direct formatting fighting the styles, skipped outline levels, hand-typed lists, and whitespace used as layout — then describe the repair as an ordered, serializable plan. Read-only throughout. Linting
Command line docx-plus inspect / restyle / controls / comments / lint / plan / skill over the library. CLI

Project status

v0.6.2 — beta, and shipping. 2,101 tests, 96% coverage, mypy --strict clean with zero ignores. CI runs Python 3.10–3.13 on Linux plus a Windows job, and a lower-bound dependency job pinned to python-docx==1.0.0 / lxml==4.9.0.

The API is stable in practice but pre-1.0: breaking changes are possible on minor versions and are called out in the changelog.

Release Shipped
v0.1.0 Foundation (core/), style inspection / modification / remapping, content controls, fields, protection
v0.2.0 Comments, layout, bookmarks, notes, core/parts; toggle properties, in-place edits, line numbering, page borders, conditional table styles, publishing/
v0.3.0 Tracked changes (revisions/) and the docx-plus CLI (inspect, restyle, controls)
v0.4.0 Threaded comments over commentsExtended.xml, and docx-plus comments
v0.5.0 Table formatting (tables/), custom numbering (numbering/), comment durable ids and author presence, the agent skill in the wheel behind docx-plus skill
v0.6.0 The linter (lint/) — 20 rules, profiles, plan_fixes, and docx-plus lint / plan; the cascade resolver corrected against live Word; the document-wide sweep, stop_below baselines, read_fields

ROADMAP.md is the live record of what is shipped, backlogged, and deliberately declined. On the backlog: content-control data binding to Custom XML Parts, bibliography and BIBLIOGRAPHY fields, theme writing, glossary placeholder text, and password-protected forms.

Contributing

See CONTRIBUTING.md for the development setup, quality gates, and conventions — including the expectation that new OOXML output is verified against a file Word itself authored.

Auditing the project? See the Test Gaps snapshot.