Word Document Manipulation
researched 2026-05-25· 1 source · 6 concepts · skill docx
A .docx file is a ZIP archive containing XML files.
Overview
- A .docx file is a ZIP archive containing XML files. [source]
Converting .doc to .docx
- Legacy .doc files must be converted before editing: [source]
Accepting Tracked Changes
- To produce a clean document with all tracked changes accepted (requires LibreOffice): [source]
Creating New Documents
- Generate .docx files with JavaScript, then validate. Install: npm install -g docx [source]
Validation
- After creating the file, validate it. If validation fails, unpack, fix the XML, and repack. [source]
Page Size
Styles (Override Built-in Headings)
- Use Arial as the default font (universally supported). Keep titles black for readability. [source]
Tables
- CRITICAL: Tables need dual widths - set both columnWidths on the table AND width on each cell. Without both, tables render incorrectly on some platforms. [source]
- Table width calculation: [source]
- Always use WidthType.DXA - WidthType.PERCENTAGE breaks in Google Docs. [source]
- Always use WidthType.DXA - never WidthType.PERCENTAGE (incompatible with Google Docs) [source]
- Table width must equal the sum of columnWidths [source]
- Cell width must match corresponding columnWidth [source]
- Cell margins are internal padding - they reduce content area, not add to cell width [source]
- For full-width tables: use content width (page width minus left and right margins) [source]
Multi-Column Layouts
- Force a column break with a new section using type: SectionType.NEXT_COLUMN. [source]
Critical Rules for docx-js
- Set page size explicitly - docx-js defaults to A4; use US Letter (12240 x 15840 DXA) for US documents [source]
- Landscape: pass portrait dimensions - docx-js swaps width/height internally; pass short edge as width, long edge as height, and set orientation: PageOrientation.LANDSCAPE [source]
- Never use \n - use separate Paragraph elements [source]
- Never use unicode bullets - use LevelFormat.BULLET with numbering config [source]
- PageBreak must be in Paragraph - standalone creates invalid XML [source]
- ImageRun requires type - always specify png/jpg/etc [source]
- Always set table width with DXA - never use WidthType.PERCENTAGE (breaks in Google Docs) [source]
- Tables need dual widths - columnWidths array AND cell width, both must match [source]
- Table width = sum of columnWidths - for DXA, ensure they add up exactly [source]
- Always add cell margins - use margins: { top: 80, bottom: 80, left: 120, right: 120 } for readable padding [source]
- Use ShadingType.CLEAR - never SOLID for table shading [source]
- Never use tables as dividers/rules - cells have minimum height and render as empty boxes (including in headers/footers); use border: { bottom: { style: BorderStyle.SINGLE, size: 6, color: "2E75B6", space: 1 } } on a Paragraph instead. For two-column footers, use tab stops (see Tab Stops section), not tables [source]
- TOC requires HeadingLevel only - no custom styles on heading paragraphs [source]
- Override built-in styles - use exact IDs: "Heading1", "Heading2", etc. [source]
- Include outlineLevel - required for TOC (0 for H1, 1 for H2, etc.) [source]
Editing Existing Documents
- Follow all 3 steps in order. [source]
Step 1: Unpack
- Extracts XML, pretty-prints, merges adjacent runs, and converts smart quotes to XML entities (“ etc.) so they survive editing. Use --merge-runs false to skip run merging. [source]
Step 2: Edit XML
- Edit files in unpacked/word/. See XML Reference below for patterns. [source]
- Use "Claude" as the author for tracked changes and comments, unless the user explicitly requests use of a different name. [source]
- Use the Edit tool directly for string replacement. Do not write Python scripts. Scripts introduce unnecessary complexity. The Edit tool shows exactly what is being replaced. [source]
- CRITICAL: Use smart quotes for new content. When adding text with apostrophes or quotes, use XML entities to produce smart quotes: [source]
- Adding comments: Use comment.py to handle boilerplate across multiple XML files (text must be pre-escaped XML): [source]
- Then add markers to document.xml (see Comments in XML Reference). [source]
Step 3: Pack
- Validates with auto-repair, condenses XML, and creates DOCX. Use --validate false to skip. [source]
- Auto-repair will fix: [source]
- durableId >= 0x7FFFFFFF (regenerates valid ID) [source]
- Missing xml:space="preserve" on <w:t> with whitespace [source]
- Auto-repair won't fix: [source]
- Malformed XML, invalid element nesting, missing relationships, schema violations [source]
Common Pitfalls
- Replace entire <w:r> elements: When adding tracked changes, replace the whole <w:r>...</w:r> block with <w:del>...<w:ins>... as siblings. Don't inject tracked change tags inside a run. [source]
- Preserve <w:rPr> formatting: Copy the original run's <w:rPr> block into your tracked change runs to maintain bold, font size, etc. [source]
Schema Compliance
Tracked Changes
- Inside <w:del>: Use <w:delText> instead of <w:t>, and <w:delInstrText> instead of <w:instrText>. [source]
- Minimal edits - only mark what changes: [source]
- Deleting entire paragraphs/list items - when removing ALL content from a paragraph, also mark the paragraph mark as deleted so it merges with the next paragraph. Add <w:del/> inside <w:pPr><w:rPr>: [source]
- Without the <w:del/> in <w:pPr><w:rPr>, accepting changes leaves an empty paragraph/list item. [source]
- Rejecting another author's insertion - nest deletion inside their insertion: [source]
- Restoring another author's deletion - add insertion after (don't modify their deletion): [source]
Comments
Images
Dependencies
Children
- DOCX File Creation (frontier)
- DOCX Editing and Formatting (frontier)
- Table of Contents Generation (frontier)
- Image Insertion (frontier)
Frontier under this node: DOCX Editing and Formatting, DOCX File Creation, Image Insertion, Table of Contents Generation