Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
answerzhao avatar

Docx

  • 20 installs
  • 26 repo stars
  • Updated January 15, 2026
  • answerzhao/agent-skills

Docx is a skill for generating and editing Microsoft Word .docx files using the JavaScript/TypeScript docx library and bundled OOXML schemas.

About

Docx is a skill for programmatically creating and manipulating Microsoft Word .docx documents. It documents the JavaScript/TypeScript docx library for building documents with text formatting, tables, images, headers and footers, hyperlinks, and a table of contents, and it bundles OOXML schemas with pack, unpack, and validate scripts for working at the raw XML level. Developers use it to generate Word documents at scale.

  • Generates .docx files with the JavaScript/TypeScript docx library
  • Bundles OOXML schemas plus pack/unpack/validate scripts for raw document XML
  • Covers text, tables, images, headers/footers, hyperlinks, and TOC

Docx by the numbers

  • 20 all-time installs (skills.sh)
  • Ranked #435 of 687 Office & Documents skills by installs in the Skillselion catalog
  • Data as of Jul 28, 2026 (Skillselion catalog sync)
At a glance

docx capabilities & compatibility

Capabilities
documentation · pdf parsing
Use cases
documentation
Runs
Runs locally
Pricing
Free
From the docs

What docx says it does

# DOCX Library Tutorial Generate .docx files with JavaScript/TypeScript.
docx-js.md
// IMPORTANT: Never use \n for line breaks - always use separate Paragraph elements
docx-js.md
npx skills add https://github.com/answerzhao/agent-skills --skill docx

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs20
repo stars26
Last updatedJanuary 15, 2026
Repositoryanswerzhao/agent-skills

What it does

Programmatically create or edit Word .docx files with formatted text, tables, images, and headers using the docx JS library.

Who is it for?

Programmatically generating or editing Word .docx documents with rich formatting and tables.

When should I use this skill?

You need to create, edit, or process a Microsoft Word .docx document at scale.

What you get

  • .docx document

By the numbers

  • bundled OOXML XSD schema set
  • pack/unpack/validate scripts

Files

docx-js.mdMarkdownGitHub ↗

DOCX Library Tutorial

Generate .docx files with JavaScript/TypeScript.

Important: Read this entire document before starting. Critical formatting rules and common pitfalls are covered throughout - skipping sections may result in corrupted files or rendering issues.

Setup

Assumes docx is already installed globally If not installed: npm install -g docx

const { Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell, ImageRun, Media, 
        Header, Footer, AlignmentType, PageOrientation, LevelFormat, ExternalHyperlink, 
        InternalHyperlink, TableOfContents, HeadingLevel, BorderStyle, WidthType, TabStopType, 
        TabStopPosition, UnderlineType, ShadingType, VerticalAlign, SymbolRun, PageNumber,
        FootnoteReferenceRun, Footnote, PageBreak } = require('docx');

// Create & Save
const doc = new Document({ sections: [{ children: [/* content */] }] });
Packer.toBuffer(doc).then(buffer => fs.writeFileSync("doc.docx", buffer)); // Node.js
Packer.toBlob(doc).then(blob => { /* download logic */ }); // Browser

Text & Formatting

// IMPORTANT: Never use \n for line breaks - always use separate Paragraph elements
// ❌ WRONG: new TextRun("Line 1\nLine 2")
// ✅ CORRECT: new Paragraph({ children: [new TextRun("Line 1")] }), new Paragraph({ children: [new TextRun("Line 2")] })

// Basic text with all formatting options
new Paragraph({
  alignment: AlignmentType.CENTER,
  spacing: { before: 200, after: 200 },
  indent: { left: 720, right: 720 },
  children: [
    new TextRun({ text: "Bold", bold: true }),
    new TextRun({ text: "Italic", italics: true }),
    new TextRun({ text: "Underlined", underline: { type: UnderlineType.DOUBLE, color: "FF0000" } }),
    new TextRun({ text: "Colored", color: "FF0000", size: 28, font: "Arial" }), // Arial default
    new TextRun({ text: "Highlighted", highlight: "yellow" }),
    new TextRun({ text: "Strikethrough", strike: true }),
    new TextRun({ text: "x2", superScript: true }),
    new TextRun({ text: "H2O", subScript: true }),
    new TextRun({ text: "SMALL CAPS", smallCaps: true }),
    new SymbolRun({ char: "2022", font: "Symbol" }), // Bullet •
    new SymbolRun({ char: "00A9", font: "Arial" })   // Copyright © - Arial for symbols
  ]
})

Styles & Professional Formatting

const doc = new Document({
  styles: {
    default: { document: { run: { font: "Arial", size: 24 } } }, // 12pt default
    paragraphStyles: [
      // Document title style - override built-in Title style
      { id: "Title", name: "Title", basedOn: "Normal",
        run: { size: 56, bold: true, color: "000000", font: "Arial" },
        paragraph: { spacing: { before: 240, after: 120 }, alignment: AlignmentType.CENTER } },
      // IMPORTANT: Override built-in heading styles by using their exact IDs
      { id: "Heading1", name: "Heading 1", basedOn: "Normal", next: "Normal", quickFormat: true,
        run: { size: 32, bold: true, color: "000000", font: "Arial" }, // 16pt
        paragraph: { spacing: { before: 240, after: 240 }, outlineLevel: 0 } }, // Required for TOC
      { id: "Heading2", name: "Heading 2", basedOn: "Normal", next: "Normal", quickFormat: true,
        run: { size: 28, bold: true, color: "000000", font: "Arial" }, // 14pt
        paragraph: { spacing: { before: 180, after: 180 }, outlineLevel: 1 } },
      // Custom styles use your own IDs
      { id: "myStyle", name: "My Style", basedOn: "Normal",
        run: { size: 28, bold: true, color: "000000" },
        paragraph: { spacing: { after: 120 }, alignment: AlignmentType.CENTER } }
    ],
    characterStyles: [{ id: "myCharStyle", name: "My Char Style",
      run: { color: "FF0000", bold: true, underline: { type: UnderlineType.SINGLE } } }]
  },
  sections: [{
    properties: { page: { margin: { top: 1440, right: 1440, bottom: 1440, left: 1440 } } },
    children: [
      new Paragraph({ heading: HeadingLevel.TITLE, children: [new TextRun("Document Title")] }), // Uses overridden Title style
      new Paragraph({ heading: HeadingLevel.HEADING_1, children: [new TextRun("Heading 1")] }), // Uses overridden Heading1 style
      new Paragraph({ style: "myStyle", children: [new TextRun("Custom paragraph style")] }),
      new Paragraph({ children: [
        new TextRun("Normal with "),
        new TextRun({ text: "custom char style", style: "myCharStyle" })
      ]})
    ]
  }]
});

Professional Font Combinations:

  • Arial (Headers) + Arial (Body) - Most universally supported, clean and professional
  • Times New Roman (Headers) + Arial (Body) - Classic serif headers with modern sans-serif body
  • Georgia (Headers) + Verdana (Body) - Optimized for screen reading, elegant contrast

Key Styling Principles:

  • Override built-in styles: Use exact IDs like "Heading1", "Heading2", "Heading3" to override Word's built-in heading styles
  • HeadingLevel constants: HeadingLevel.HEADING_1 uses "Heading1" style, HeadingLevel.HEADING_2 uses "Heading2" style, etc.
  • Include outlineLevel: Set outlineLevel: 0 for H1, outlineLevel: 1 for H2, etc. to ensure TOC works correctly
  • Use custom styles instead of inline formatting for consistency
  • Set a default font using styles.default.document.run.font - Arial is universally supported
  • Establish visual hierarchy with different font sizes (titles > headers > body)
  • Add proper spacing with before and after paragraph spacing
  • Use colors sparingly: Default to black (000000) and shades of gray for titles and headings (heading 1, heading 2, etc.)
  • Set consistent margins (1440 = 1 inch is standard)

Lists (ALWAYS USE PROPER LISTS - NEVER USE UNICODE BULLETS)

// Bullets - ALWAYS use the numbering config, NOT unicode symbols
// CRITICAL: Use LevelFormat.BULLET constant, NOT the string "bullet"
const doc = new Document({
  numbering: {
    config: [
      { reference: "bullet-list",
        levels: [{ level: 0, format: LevelFormat.BULLET, text: "•", alignment: AlignmentType.LEFT,
          style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] },
      { reference: "first-numbered-list",
        levels: [{ level: 0, format: LevelFormat.DECIMAL, text: "%1.", alignment: AlignmentType.LEFT,
          style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] },
      { reference: "second-numbered-list", // Different reference = restarts at 1
        levels: [{ level: 0, format: LevelFormat.DECIMAL, text: "%1.", alignment: AlignmentType.LEFT,
          style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] }
    ]
  },
  sections: [{
    children: [
      // Bullet list items
      new Paragraph({ numbering: { reference: "bullet-list", level: 0 },
        children: [new TextRun("First bullet point")] }),
      new Paragraph({ numbering: { reference: "bullet-list", level: 0 },
        children: [new TextRun("Second bullet point")] }),
      // Numbered list items
      new Paragraph({ numbering: { reference: "first-numbered-list", level: 0 },
        children: [new TextRun("First numbered item")] }),
      new Paragraph({ numbering: { reference: "first-numbered-list", level: 0 },
        children: [new TextRun("Second numbered item")] }),
      // ⚠️ CRITICAL: Different reference = INDEPENDENT list that restarts at 1
      // Same reference = CONTINUES previous numbering
      new Paragraph({ numbering: { reference: "second-numbered-list", level: 0 },
        children: [new TextRun("Starts at 1 again (because different reference)")] })
    ]
  }]
});

// ⚠️ CRITICAL NUMBERING RULE: Each reference creates an INDEPENDENT numbered list
// - Same reference = continues numbering (1, 2, 3... then 4, 5, 6...)
// - Different reference = restarts at 1 (1, 2, 3... then 1, 2, 3...)
// Use unique reference names for each separate numbered section!

// ⚠️ CRITICAL: NEVER use unicode bullets - they create fake lists that don't work properly
// new TextRun("• Item")           // WRONG
// new SymbolRun({ char: "2022" }) // WRONG
// ✅ ALWAYS use numbering config with LevelFormat.BULLET for real Word lists

Tables

// Complete table with margins, borders, headers, and bullet points
const tableBorder = { style: BorderStyle.SINGLE, size: 1, color: "CCCCCC" };
const cellBorders = { top: tableBorder, bottom: tableBorder, left: tableBorder, right: tableBorder };

new Table({
  columnWidths: [4680, 4680], // ⚠️ CRITICAL: Set column widths at table level - values in DXA (twentieths of a point)
  margins: { top: 100, bottom: 100, left: 180, right: 180 }, // Set once for all cells
  rows: [
    new TableRow({
      tableHeader: true,
      children: [
        new TableCell({
          borders: cellBorders,
          width: { size: 4680, type: WidthType.DXA }, // ALSO set width on each cell
          // ⚠️ CRITICAL: Always use ShadingType.CLEAR to prevent black backgrounds in Word.
          shading: { fill: "D5E8F0", type: ShadingType.CLEAR }, 
          verticalAlign: VerticalAlign.CENTER,
          children: [new Paragraph({ 
            alignment: AlignmentType.CENTER,
            children: [new TextRun({ text: "Header", bold: true, size: 22 })]
          })]
        }),
        new TableCell({
          borders: cellBorders,
          width: { size: 4680, type: WidthType.DXA }, // ALSO set width on each cell
          shading: { fill: "D5E8F0", type: ShadingType.CLEAR },
          children: [new Paragraph({ 
            alignment: AlignmentType.CENTER,
            children: [new TextRun({ text: "Bullet Points", bold: true, size: 22 })]
          })]
        })
      ]
    }),
    new TableRow({
      children: [
        new TableCell({
          borders: cellBorders,
          width: { size: 4680, type: WidthType.DXA }, // ALSO set width on each cell
          children: [new Paragraph({ children: [new TextRun("Regular data")] })]
        }),
        new TableCell({
          borders: cellBorders,
          width: { size: 4680, type: WidthType.DXA }, // ALSO set width on each cell
          children: [
            new Paragraph({ 
              numbering: { reference: "bullet-list", level: 0 },
              children: [new TextRun("First bullet point")] 
            }),
            new Paragraph({ 
              numbering: { reference: "bullet-list", level: 0 },
              children: [new TextRun("Second bullet point")] 
            })
          ]
        })
      ]
    })
  ]
})

IMPORTANT: Table Width & Borders

  • Use BOTH columnWidths: [width1, width2, ...] array AND width: { size: X, type: WidthType.DXA } on each cell
  • Values in DXA (twentieths of a point): 1440 = 1 inch, Letter usable width = 9360 DXA (with 1" margins)
  • Apply borders to individual TableCell elements, NOT the Table itself

Precomputed Column Widths (Letter size with 1" margins = 9360 DXA total):

  • 2 columns: columnWidths: [4680, 4680] (equal width)
  • 3 columns: columnWidths: [3120, 3120, 3120] (equal width)

Links & Navigation

// TOC (requires headings) - CRITICAL: Use HeadingLevel only, NOT custom styles
// ❌ WRONG: new Paragraph({ heading: HeadingLevel.HEADING_1, style: "customHeader", children: [new TextRun("Title")] })
// ✅ CORRECT: new Paragraph({ heading: HeadingLevel.HEADING_1, children: [new TextRun("Title")] })
new TableOfContents("Table of Contents", { hyperlink: true, headingStyleRange: "1-3" }),

// External link
new Paragraph({
  children: [new ExternalHyperlink({
    children: [new TextRun({ text: "Google", style: "Hyperlink" })],
    link: "https://www.google.com"
  })]
}),

// Internal link & bookmark
new Paragraph({
  children: [new InternalHyperlink({
    children: [new TextRun({ text: "Go to Section", style: "Hyperlink" })],
    anchor: "section1"
  })]
}),
new Paragraph({
  children: [new TextRun("Section Content")],
  bookmark: { id: "section1", name: "section1" }
}),

Images & Media

// Basic image with sizing & positioning
// CRITICAL: Always specify 'type' parameter - it's REQUIRED for ImageRun
new Paragraph({
  alignment: AlignmentType.CENTER,
  children: [new ImageRun({
    type: "png", // NEW REQUIREMENT: Must specify image type (png, jpg, jpeg, gif, bmp, svg)
    data: fs.readFileSync("image.png"),
    transformation: { width: 200, height: 150, rotation: 0 }, // rotation in degrees
    altText: { title: "Logo", description: "Company logo", name: "Name" } // IMPORTANT: All three fields are required
  })]
})

Page Breaks

// Manual page break
new Paragraph({ children: [new PageBreak()] }),

// Page break before paragraph
new Paragraph({
  pageBreakBefore: true,
  children: [new TextRun("This starts on a new page")]
})

// ⚠️ CRITICAL: NEVER use PageBreak standalone - it will create invalid XML that Word cannot open
// ❌ WRONG: new PageBreak() 
// ✅ CORRECT: new Paragraph({ children: [new PageBreak()] })

Headers/Footers & Page Setup

const doc = new Document({
  sections: [{
    properties: {
      page: {
        margin: { top: 1440, right: 1440, bottom: 1440, left: 1440 }, // 1440 = 1 inch
        size: { orientation: PageOrientation.LANDSCAPE },
        pageNumbers: { start: 1, formatType: "decimal" } // "upperRoman", "lowerRoman", "upperLetter", "lowerLetter"
      }
    },
    headers: {
      default: new Header({ children: [new Paragraph({ 
        alignment: AlignmentType.RIGHT,
        children: [new TextRun("Header Text")]
      })] })
    },
    footers: {
      default: new Footer({ children: [new Paragraph({ 
        alignment: AlignmentType.CENTER,
        children: [new TextRun("Page "), new TextRun({ children: [PageNumber.CURRENT] }), new TextRun(" of "), new TextRun({ children: [PageNumber.TOTAL_PAGES] })]
      })] })
    },
    children: [/* content */]
  }]
});

Tabs

new Paragraph({
  tabStops: [
    { type: TabStopType.LEFT, position: TabStopPosition.MAX / 4 },
    { type: TabStopType.CENTER, position: TabStopPosition.MAX / 2 },
    { type: TabStopType.RIGHT, position: TabStopPosition.MAX * 3 / 4 }
  ],
  children: [new TextRun("Left\tCenter\tRight")]
})

Constants & Quick Reference

  • Underlines: SINGLE, DOUBLE, WAVY, DASH
  • Borders: SINGLE, DOUBLE, DASHED, DOTTED
  • Numbering: DECIMAL (1,2,3), UPPER_ROMAN (I,II,III), LOWER_LETTER (a,b,c)
  • Tabs: LEFT, CENTER, RIGHT, DECIMAL
  • Symbols: "2022" (•), "00A9" (©), "00AE" (®), "2122" (™), "00B0" (°), "F070" (✓), "F0FC" (✗)

Critical Issues & Common Mistakes

  • CRITICAL: PageBreak must ALWAYS be inside a Paragraph - standalone PageBreak creates invalid XML that Word cannot open
  • ALWAYS use ShadingType.CLEAR for table cell shading - Never use ShadingType.SOLID (causes black background).
  • Measurements in DXA (1440 = 1 inch) | Each table cell needs ≥1 Paragraph | TOC requires HeadingLevel styles only
  • ALWAYS use custom styles with Arial font for professional appearance and proper visual hierarchy
  • ALWAYS set a default font using styles.default.document.run.font - Arial recommended
  • ALWAYS use columnWidths array for tables + individual cell widths for compatibility
  • NEVER use unicode symbols for bullets - always use proper numbering configuration with LevelFormat.BULLET constant (NOT the string "bullet")
  • NEVER use \n for line breaks anywhere - always use separate Paragraph elements for each line
  • ALWAYS use TextRun objects within Paragraph children - never use text property directly on Paragraph
  • CRITICAL for images: ImageRun REQUIRES type parameter - always specify "png", "jpg", "jpeg", "gif", "bmp", or "svg"
  • CRITICAL for bullets: Must use LevelFormat.BULLET constant, not string "bullet", and include text: "•" for the bullet character
  • CRITICAL for numbering: Each numbering reference creates an INDEPENDENT list. Same reference = continues numbering (1,2,3 then 4,5,6). Different reference = restarts at 1 (1,2,3 then 1,2,3). Use unique reference names for each separate numbered section!
  • CRITICAL for TOC: When using TableOfContents, headings must use HeadingLevel ONLY - do NOT add custom styles to heading paragraphs or TOC will break
  • Tables: Set columnWidths array + individual cell widths, apply borders to cells not table
  • Set table margins at TABLE level for consistent cell padding (avoids repetition per cell)

Related skills

Office & Documentsnotesworkflow

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.