Paragraph
Everything (text, images, graphs etc) in OpenXML is organized in paragraphs.
Paragraphs requires an understanding of Sections.
You can create Paragraphs in the following ways:
Shorthand
import { Paragraph } from "betterdocx";
const paragraph = new Paragraph("Short hand Hello World");Children Method
This method is useful for adding different text with different styles, symbols, or adding images inline.
const paragraph = new Paragraph({
children: [
new TextRun("Lorem Ipsum Foo Bar"),
new TextRun("Hello World"),
new SymbolRun("F071"),
],
});Explicit
const paragraph = new Paragraph({
text: "Short hand notation for adding text.",
});After you create the paragraph, you must add the paragraph into a section:
const doc = new Document({
sections: [{
children: [paragraph],
}];
});Or the preferred convention, define the paragraph inside the section and remove the usage of variables:
const doc = new Document({
sections: [{
children: [
new Paragraph({
children: [new TextRun("Lorem Ipsum Foo Bar"), new TextRun("Hello World")],
}),
],
}];
});Options
This is the list of options for a paragraph. A detailed explanation is below:
| Property | Type | Mandatory? | Possible Values |
|---|---|---|---|
| text | string | Optional | |
| heading | HeadingLevel | Optional | HEADING_1, HEADING_2, HEADING_3, HEADING_4, HEADING_5, HEADING_6, TITLE |
| border | IBorderOptions | Optional | top, bottom, left, right, between. Each of these are of type IBorderPropertyOptions. Click here for Example |
| spacing | ISpacingProperties | Optional | See below for ISpacingProperties |
| outlineLevel | number | Optional | |
| alignment | AlignmentType | Optional | START, CENTER, END, BOTH, MEDIUM_KASHIDA, DISTRIBUTE, NUM_TAB, HIGH_KASHIDA, LOW_KASHIDA, THAI_DISTRIBUTE, LEFT, RIGHT, JUSTIFIED |
| heading | HeadingLevel | Optional | |
| bidirectional | boolean | Optional | |
| thematicBreak | boolean | Optional | |
| pageBreakBefore | boolean | Optional | |
| contextualSpacing | boolean | Optional | |
| indent | IIndentAttributesProperties | Optional | |
| keepLines | boolean | Optional | |
| keepNext | boolean | Optional | |
| children | (TextRun or ImageRun or Hyperlink)[] | Optional | |
| style | string | Optional | |
| tabStops | { type: TabStopType; position: number; leader?: LeaderType }[] | Optional | type: LEFT, RIGHT, CENTER, BAR, CLEAR, DECIMAL, END, NUM, START. leader: DOT, HYPHEN, MIDDLE_DOT, NONE, UNDERSCORE |
| rightTabStop | number | Optional | |
| leftTabStop | number | Optional | |
| bullet | { level: number } | Optional | |
| numbering | { reference: string; level: number; instance?: number; custom?: boolean } or false | Optional | |
| widowControl | boolean | Optional | |
| frame | IFrameOptions | Optional | |
| run | IRunOptions | Optional | |
| wordWrap | boolean | Optional | |
| overflowPunctuation | boolean | Optional | |
| autoSpaceEastAsianText | boolean | Optional | |
| suppressLineNumbers | boolean | Optional |
Text
This is the text in a paragraph. You can also add text by using the Paragraph shorthand (mentioned above) or adding children.
Example:
const paragraph = new Paragraph({
text: "Hello World",
});Heading
Example:
Setting a Heading 1 paragraph with "Hello World" as it's text:
const paragraph = new Paragraph({
text: "Hello World",
heading: HeadingLevel.HEADING_1,
});Border
Add borders to a Paragraph. Good for making the Paragraph stand out. Border top and border bottom can be used as a horizontal rule (also known as horizontal line).
IBorderPropertyOptions
top, bottom, left, right, between of the border
| Property | Type | Notes |
|---|---|---|
| color | string | Required |
| space | number | Required |
| style | string | Required |
| size | number | Required |
Example:
Add border on the top and the bottom of the paragraph
const paragraph = new Paragraph({
text: "I have borders on my top and bottom sides!",
border: {
top: {
color: "auto",
space: 1,
style: "single",
size: 6,
},
bottom: {
color: "auto",
space: 1,
style: "single",
size: 6,
},
},
});Shading
Add color to an entire paragraph block
const paragraph = new Paragraph({
text: "shading",
shading: {
type: ShadingType.REVERSE_DIAGONAL_STRIPE,
color: "00FFFF",
fill: "FF0000",
},
});Widow Control
Allow First/Last Line to Display on a Separate Page
const paragraph = new Paragraph({
text: "shading",
widowControl: true,
});Spacing
Adding spacing between paragraphs
ISpacingProperties
| Property | Type | Notes | Possible Values |
|---|---|---|---|
| after | number | Optional | |
| before | number | Optional | |
| line | number | Optional | |
| lineRule | LineRuleType | Optional | AT_LEAST, EXACTLY, EXACT, AUTO |
| beforeAutoSpacing | boolean | Optional | Let Word decide the spacing before the paragraph (the before value is ignored) |
| afterAutoSpacing | boolean | Optional | Let Word decide the spacing after the paragraph (the after value is ignored) |
Note: The lineRule property has different values depending on the version of Word you are using. The EXACTLY value is only available in Word 2016 and above. Use EXACT for greater support, including LibreOffice etc. Read this issue for more information: https://github.com/dolanmiu/docx/issues/1773.
Example:
Add spacing before the paragraph:
const paragraph = new Paragraph({
text: "Paragraph with spacing before",
spacing: {
before: 200,
},
});Contextual Spacing
When set to true, the spacing between this paragraph and adjacent paragraphs of the same style is ignored. This is what Word's "Don't add space between paragraphs of the same style" checkbox does, and it is commonly used for list items so consecutive bullets sit close together.
const paragraph = new Paragraph({
text: "No extra space between me and my siblings of the same style",
contextualSpacing: true,
});Set it to false to explicitly turn the behaviour off (e.g. to override a style that enables it).
Indent
Indentation is set via the indent option. Distances are given in twentieths of a point (twips) when a number is used, or as a universal measure string such as "1cm", "18pt", "0.5in" (supported units: mm, cm, in, pt, pc, pi).
| Property | Type | Notes | Description |
|---|---|---|---|
| start | number or UniversalMeasure | Optional | Indentation at the start of the paragraph (left in LTR text). May be negative. |
| end | number or UniversalMeasure | Optional | Indentation at the end of the paragraph (right in LTR text). May be negative. |
| left | number or UniversalMeasure | Optional | Left indentation. Prefer start/end, which respect text direction. |
| right | number or UniversalMeasure | Optional | Right indentation. Prefer start/end, which respect text direction. |
| hanging | number or PositiveUniversalMeasure | Optional | Indent all lines except the first one by this amount (hanging indent). |
| firstLine | number or PositiveUniversalMeasure | Optional | Additional indentation for the first line only. |
Example:
const paragraph = new Paragraph({
text: "Indented paragraph with a hanging first line",
indent: {
start: "1cm",
hanging: 360,
},
});Numbering
To attach a paragraph to a numbering (multi-level list) definition, reference the definition by name together with the level to use:
const paragraph = new Paragraph({
text: "Numbered item",
numbering: {
reference: "my-numbering",
level: 0,
},
});| Property | Type | Notes | Description |
|---|---|---|---|
| reference | string | Required | Name of a numbering definition configured on the document. |
| level | number | Required | Which level of the list this paragraph is on (0-based). |
| instance | number | Optional | Concrete numbering instance, allowing the same definition to restart as a separate list. Defaults to 0. |
| custom | boolean | Optional | When true, the built-in ListParagraph style is not applied automatically. |
You can also pass numbering: false to explicitly remove numbering inherited from a paragraph style. See the numbering documentation for how to create numbering definitions.
Tab Stop Shorthands
In addition to the tabStops array, rightTabStop and leftTabStop are shorthands that add a single right or left tab stop at the given position (in twips):
const paragraph = new Paragraph({
children: [new TextRun("Left side"), new TextRun("\tRight side")],
rightTabStop: TabStopPosition.MAX,
});Paragraph Mark Run Properties
The run option sets run formatting for the paragraph mark itself (the invisible pilcrow at the end of the paragraph), as defined in ECMA-376 § 17.3.1.29. This affects, for example, the height of an empty paragraph or the formatting applied to a numbering symbol. It accepts the same IRunOptions as a TextRun:
const paragraph = new Paragraph({
text: "Paragraph with a large paragraph mark",
run: {
size: 48,
bold: true,
},
});Typography and Line Numbering
| Property | Type | Notes | Description |
|---|---|---|---|
| wordWrap | boolean | Optional | When true, allows lines to break mid-word (emits w:wordWrap w:val="0"), useful for long unbreakable strings such as URLs. |
| overflowPunctuation | boolean | Optional | Allows punctuation at the end of a line to extend slightly past the text margin. |
| autoSpaceEastAsianText | boolean | Optional | Automatically adjusts inter-character spacing between regions of numbers and regions of East Asian text. Microsoft Word only; not part of the ECMA-376 OOXML standard. |
| suppressLineNumbers | boolean | Optional | Excludes this paragraph from line numbering applied to the section. |
const paragraph = new Paragraph({
text: "https://a-very-long-url.example.com/that/should/wrap",
wordWrap: true,
suppressLineNumbers: true,
});Outline Level
Example:
const paragraph = new Paragraph({
outlineLevel: 0,
});Styles
To create styles, please refer to the styling documentation
TODO replace this image Word 2013 Styles men
Headings and titles
import { HeadingLevel, Paragraph } from "betterdocx";
const paragraph = new Paragraph({
text: "Hello World",
heading: HeadingLevel.TITLE,
});Text Alignment
To change the text alignment of a paragraph, add an AlignmentType option on the paragraph.for center, left, right or justified:
Example:
const paragraph = new Paragraph({
text: "Hello World",
heading: HeadingLevel.HEADING_1,
alignment: AlignmentType.CENTER,
});The above will create a heading 1 which is centered.
Justified text with breaks
When a paragraph is justified, you may want to not justify the contents of incomplete lines, which end in a soft line break.

This is possible to achieve using:
this.doc.Settings.addCompatibility().doNotExpandShiftReturn();The result is:

Thematic Break
To add a thematic break in the Paragraph:
const paragraph = new docx.Paragraph("Amazing Heading");
const paragraph = new Paragraph({
text: "Amazing Heading",
heading: HeadingLevel.HEADING_1,
thematicBreak: true,
});The above example will create a heading with a page break directly under it.
Page Break
To move to a new page (insert a page break):
const paragraph = new docx.Paragraph({
children: [new TextRun("Amazing Heading"), new PageBreak()],
});The above example will create a heading and start a new page immediately afterwards.
Column Break
Similarly, a ColumnBreak moves the following content to the next column in a multi-column section:
const paragraph = new Paragraph({
children: [new TextRun("End of first column"), new ColumnBreak()],
});Page break before:
This option (available in word) will make sure that the paragraph will start on a new page (if it's not already on a new page).
const paragraph = new Paragraph({
text: "Hello World on another page",
pageBreakBefore: true,
});
Example: https://github.com/dolanmiu/docx/blob/master/demo/15-page-break-before.ts
Page break control
Paragraphs have keepLines and keepNext properties that allow restricting page breaks within and between paragraphs. See this Microsoft article for more details.
const paragraph = new Paragraph({
text: "Stay on the same page",
keepLines: true,
keepNext: true,
});Adding a run to the front
Paragraph.addRunToFront() inserts a run before the paragraph's existing children and returns the paragraph, so calls can be chained. This is useful when content needs to be prepended after the paragraph has been constructed:
const paragraph = new Paragraph({
children: [new TextRun("World")],
});
paragraph.addRunToFront(new TextRun("Hello "));