Skip to content

Images ​

Embed images in your documents with sizing, floating layout, and alt text support.

Basic Image ​

ts
import { createDocx } from 'docx-kit/node'
import { readFileSync } from 'node:fs'

const imageBytes = readFileSync('./logo.png')

const doc = createDocx()

doc
  .h1('Report')
  .image({
    data: imageBytes,
    width: 200,
    height: 80,
    alt: 'Company Logo',
  })
  .p('Report content...')
  .save('with-logo.docx')

Image Data Sources ​

Images can be provided in multiple formats:

ts
// From file (Node.js)
import { readFileSync } from 'node:fs'
doc.image({ data: readFileSync('./chart.png'), width: 400, height: 300 })

// From Uint8Array
const bytes = new Uint8Array([...])
doc.image({ data: bytes, width: 200, height: 200 })

// From ArrayBuffer
const buffer = await fetch('/image.png').then(r => r.arrayBuffer())
doc.image({ data: buffer, width: 200, height: 200 })

// From Blob (browser)
const blob = new Blob([...], { type: 'image/png' })
doc.image({ data: blob, width: 200, height: 200 })

// From base64 data URL
const dataUrl = 'data:image/png;base64,iVBORw0K...'
doc.image({ data: dataUrl, width: 200, height: 200 })

Local Image Paths ​

Local paths and file: URLs are also accepted by the Node entry point:

ts
import { createDocx } from 'docx-kit/node'

const doc = createDocx().image({ data: './logo.png', width: 200 })

Paths resolve when exporting, relative to the process working directory. The core/browser entry does not read local files or fetch image URLs automatically. Supply bytes/data URLs, or configure resolveImage(source) to return bytes or a Blob from an application-controlled source.

Sizing ​

Images can be sized with absolute values. Omit one dimension to preserve the source image's aspect ratio:

ts
// Both dimensions specified
doc.image({ data: imageBytes, width: 400, height: 300 })

// Width only (height auto-calculates)
doc.image({ data: imageBytes, width: 200 })

// Height only
doc.image({ data: imageBytes, height: 150 })

Image Format ​

Auto-detected from data; optionally explicit:

ts
doc.image({
  data: imageBytes,
  width: 200,
  height: 200,
  imageType: 'png', // 'png' | 'jpeg' | 'jpg' | 'gif' | 'bmp'
})

Floating Layout ​

Make images float with text wrapping:

ts
// Simple floating
doc.image({
  data: imageBytes,
  width: 150,
  height: 150,
  floating: true,
})

// With wrap mode and position
doc.image({
  data: imageBytes,
  width: 150,
  height: 150,
  floating: {
    wrap: 'square',  // 'square' | 'tight' | 'topAndBottom'
    x: 100,          // horizontal offset
    y: 50,           // vertical offset
  },
})

Alt Text ​

Add alt text for accessibility:

ts
doc.image({
  data: chartBytes,
  width: 400,
  height: 300,
  alt: 'Quarterly revenue bar chart showing growth from Q1 to Q4',
})

Inline Image in Paragraph ​

Images can also be used as inline content (child nodes of a paragraph):

ts
doc
  .p('Here is an inline icon: ')
  .add({
    type: 'paragraph',
    children: [
      { type: 'text', text: 'Click here → ' },
      { type: 'image', data: iconBytes, width: 16, height: 16 },
      { type: 'text', text: ' to continue.' },
    ],
  })

Browser: Loading Images from Input ​

ts
// HTML: <input type="file" id="fileInput" accept="image/*" />

import { createDocx, normalizeImageData } from 'docx-kit/browser'

const input = document.querySelector('#fileInput') as HTMLInputElement
const file = input.files![0]

// Browser Blob → normalized data for ImageRun
const data = await normalizeImageData(file)

const doc = createDocx()
doc
  .h1('User-Uploaded Image')
  .image({ data, width: 300, height: 200 })

const url = URL.createObjectURL(await doc.toBlob())
const anchor = document.createElement('a')
anchor.href = url
anchor.download = 'upload.docx'
anchor.click()
URL.revokeObjectURL(url)

Browser: Loading Image from URL ​

ts
import { createDocx } from 'docx-kit'

async function loadImage(url: string) {
  const response = await fetch(url)
  const blob = await response.blob()
  return blob
}

const doc = createDocx()
const imageBlob = await loadImage('https://example.com/chart.png')

doc
  .h1('Remote Image')
  .image({ data: imageBlob, width: 500, height: 350 })

Note: Loading images from URLs requires CORS headers on the server or a proxy.

Complete Image Examples ​

Product Catalog with Images ​

ts
import { createDocx } from 'docx-kit/node'
import { readFileSync } from 'node:fs'

const doc = createDocx({
  page: { size: 'A4', margin: '15mm' },
})

doc
  .h1('Product Catalog')
  .h2('Widget Pro')
  .image({
    data: readFileSync('./widget-pro.png'),
    width: 300,
    height: 200,
    alt: 'Widget Pro product image',
  })
  .p('The Widget Pro is our flagship product...', {
    style: { lineHeight: 1.5 },
  })
  .pageBreak()
  .h2('Gadget Max')
  .image({
    data: readFileSync('./gadget-max.png'),
    width: 300,
    height: 200,
    alt: 'Gadget Max product image',
  })
  .p('The Gadget Max features...', {
    style: { lineHeight: 1.5 },
  })
  .save('catalog.docx')

Charts Generated by Plugins ​

Plugins like ECharts render charts as images automatically — see the Plugins guide.

Released under the MIT License.