# Reading DOCX

Inputs, options, results, warnings and errors of parseDocx, and where styles, numbering and images end up in the result.

```ts
parseDocx(buffer: Uint8Array, options?: ParseOptions): Promise<ParseResult>
```

## Preparing the input

`parseDocx` only accepts bytes and never reads files itself, so in every environment the caller obtains the bytes:

| Source | Code |
| --- | --- |
| A file in Node | `new Uint8Array(await readFile(path))` |
| A browser `<input type="file">` or dropped `File` | `new Uint8Array(await file.arrayBuffer())` |
| A `fetch` response | `new Uint8Array(await response.arrayBuffer())` |

`Blob` and `File` cannot be passed directly; convert them to bytes first.

## The result

`ParseResult` has exactly two fields:

- `ast`: the root of the document tree, with `type` `"document"`. Body blocks are its `children`; see [The LitAST node model](/en/guide/litast) for their shape.
- `warnings`: non-fatal problems. Each has a stable `code`, a readable `message`, and optionally a `location` (where in the XML) and an `element` (the tag name).

Parsing avoids stopping: when one piece of content cannot be recognized or fails to process, it becomes a warning and the rest of the document is still read.

### Where the data lives

Styles, numbering and images are not returned as separate fields:

- **Images** are embedded in `image` nodes as a data URL in `attrs.src`. Image types and file signatures are checked before the URL is created.
- **Styles and numbering** are used during parsing to compute the formatting of paragraphs, text and lists, and the results appear on those nodes. The original `styles.xml` and `numbering.xml` are kept in `ast.meta.rawXmlFiles` and written back on generation.
- **Comments, footnotes, endnotes, document properties and settings** are package-level data under `ast.meta`.

## Parse options

| Option | Default | Effect |
| --- | --- | --- |
| `preserveRawXml` | keep | Unrecognized elements become `unknownBlock` / `unknownInline` nodes with their original XML in `rawXml`, written back unchanged on generation. Only an explicit `false` drops them |
| `numberingMode` | `"nested-lists"` | `"nested-lists"` rebuilds numbered paragraphs as nested `list` / `listItem` nodes; `"flat-numbered-paragraphs"` keeps Word's flat numbered paragraphs |
| `malformedFieldMode` | `"best-effort"` | For malformed complex fields, `best-effort` keeps the content with a warning, `strict` rejects the current text story |
| `plugins` | none | Extra parser plugins, consulted after the built-in ones |
| `chartSourceLimits` | built-in limits | Bounds the size of chart source data; exceeding them rejects the import |

## Errors

These cases throw `DocxPackageError` before any content is read; tell them apart by `code`:

| `code` | Meaning |
| --- | --- |
| `invalid-zip-container` | The bytes are not a ZIP package, for example the wrong file was passed |
| `unsupported-compound-file-container` | An OLE compound file, typically an encrypted DOCX or a legacy `.doc` |

```ts
try {
  const { ast } = await parseDocx(bytes);
} catch (error) {
  if (error instanceof DocxPackageError && error.code === "unsupported-compound-file-container") {
    // Tell the user the file is encrypted or a legacy .doc
  } else throw error;
}
```
