# dolanmiu/docx: generating Word files from TypeScript without a Word install

> The docx package builds .docx documents from a declarative JavaScript or TypeScript object tree, in Node or the browser. It is a good fit for server-side report generation and a poor fit for editing files that already exist.

**dolanmiu/docx** — Easily generate and modify .docx files with JS/TS with a nice declarative API. Works for Node and on the Browser.

- Repository: https://github.com/dolanmiu/docx
- Website: https://docx.js.org/
- Stars: 5,937 · Forks: 613
- Language: TypeScript
- License: MIT
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/dolanmiu-docx

## The problem docx solves, and the developers it targets

Word documents are ZIP archives of XML parts. Writing that XML by hand is possible and unpleasant, and the Open XML specification is large enough that most teams never get past the first paragraph. The docx package exists to hide that layer. You describe a document as nested JavaScript objects, and the library serializes the tree into the parts Word expects.

The audience is narrow and specific. It is Node and browser developers who need to produce a .docx as an artifact: a backend endpoint that returns a generated contract, a React app that exports a formatted CV, a build step that turns structured data into a report. The README's own framing is generation and modification of .docx files with JS/TS, and the package description repeats it. The topics list on the repository points at Angular, React and Vue integrations, which matches how it is actually used: as a library inside another application, not as a standalone tool.

What it is not is a word processor. There is no editing surface, no track-changes review UI, no pagination engine that tells you where lines will fall. If your requirement is "open the user's existing document, change a paragraph, save it back without disturbing anything else", that is a different problem class, and the repository does not present itself as solving it.

## How the declarative API maps onto the Open XML parts

The library is written in TypeScript and ships both ESM and CommonJS entry points. The package.json declares "type": "module" with a main of dist/index.umd.cjs, a module field of ./dist/index.mjs, and an exports map that routes import and require to separate type declarations. The practical consequence: the same package works in a bundler, in a Node ESM script, and in a CommonJS require, without a separate build.

At the top of the object tree sits Document. Below it you compose sections, and inside a section you place paragraphs, tables, headers and footers. Each paragraph carries text runs, and the formatting lives on those runs and on the paragraph properties. That is the mechanism: you are not writing XML, you are building the same hierarchy the XML represents, and the library walks it and emits the parts.

The demo folder is the real specification. There are over a hundred numbered files, and their names tell you what the library covers: demo/1-basic.ts, demo/14-page-numbers.ts, demo/17-footnotes.ts, demo/21-bookmarks.ts, demo/28-table-of-contents.ts, demo/100-table-look.ts, demo/103-track-change-images.ts. Numbering above 100 suggests the feature set kept growing past the original set of examples. The ooxml-schemas directory at the repository root is the other half of the story: the types are generated or checked against the schema, which is why the API can offer typed options for things like table borders and numbering levels rather than accepting arbitrary XML strings.

There is an escape hatch. demo/13-xml-styles.ts and demo/25-table-xml-styles.ts show styles being supplied as XML, so when the typed API does not expose a property, you are not stuck.

## Installing docx and writing a first document

The package is published on npm as docx. The README points at npmjs.org/package/docx for the package and at docx.js.org for usage documentation, and the repository ships a demo folder plus a browser playground called Docx.js Editor for trying code without a local install.

Install it into an existing project:

```bash
npm install docx
```

The repository's own scripts show how the maintainers run the examples locally. The demo script executes demo/index.ts through tsx, and predemo runs the build first, so the demo runs against the built output rather than src.

```bash
npm run demo
```

For the shape of a first document, the README points at the RunKit demos rather than pasting code: docx-demo1 covers a simple paragraph and text, docx-demo2 advanced paragraphs and text, docx-demo3 bullet points, docx-demo4 a simple table, docx-demo5 images, docx-demo6 margins, docx-demo7 landscape, docx-demo8 header and footer, and docx-demo10 a CV generated with docx. After running one of those you should get a .docx that opens in Word, LibreOffice or Google Docs with the content that demo describes.

In the browser the shape is identical; the difference is where the bytes go. The README links CodePen and JSFiddle examples for plain HTML/JS, StackBlitz projects for Angular, React and Vue.js, and a React example specifically for adding images. The npm scripts also include a serve.docs script that runs a docsify server from the docs directory, and a typedoc script that generates API documentation from src/index.ts.

## Where generation stops and editing begins

The honest limitation is the boundary between creating a document and modifying one. The README says the library generates and modifies .docx files, but the examples are all construction: you build a document from scratch and pack it. There is no example in the list that loads an arbitrary existing .docx, mutates a node, and saves it back.

That matters because the two workflows have different failure modes. When you generate from scratch, you control every part, and an unexpected attribute is your bug. When you ingest a file produced by Word, you inherit styles, numbering definitions, content controls and revision marks that the library may not model. The repository does ship scripts/extract-document.ts and an npm run extract script, which suggests there is tooling for pulling a document apart, but the README does not document a supported round-trip editing workflow, and the demo list does not include one.

A second constraint is fidelity of layout. The library emits the document; it does not render it. Page counts, where a table splits across a page, and how a font substitution shifts a line are decided by the application that opens the file. Anything that depends on knowing the rendered result, such as fitting content onto exactly one page, cannot be answered from the object tree alone.

A third is that the project is a library, not a service. There is no queue, no template registry, no versioned document store. You supply all of that.

## Alternatives and the real difference in approach

The most direct alternative is a template-filling library such as docxtemplater. The difference is where the document definition lives. With docx you write the structure in code, so the layout is versioned alongside the application and reviewable in a pull request. With a template approach you author a .docx in Word, place placeholders in it, and the library substitutes values at runtime. That puts layout decisions in the hands of whoever can open Word, which is often what a design team wants, and it means the document can be edited without a deploy.

The trade-off is real in both directions. Code-defined documents are painful to tweak for someone who does not read TypeScript, and template-defined documents break quietly when a placeholder is renamed or a style is removed from the template. If your documents change shape often and the people changing them are not engineers, the template route fits better. If your documents are generated from a schema and must be reproducible, the code route fits better.

A second alternative is driving LibreOffice or Word headlessly through a conversion pipeline. That gives you the actual layout engine, at the cost of a large runtime dependency and a process to manage. It is the option to consider when the rendered result is the requirement rather than the file.

## Maintenance, release cadence and licence

The repository is not archived, and the last push was on 2026-08-07. Releases show a steady cadence: 9.6.1 on 2026-03-10, 9.7.0 on 2026-05-24, and 9.7.1 on 2026-05-27. The package.json version matches 9.7.1, so the published package and the repository are in step.

The upgrade cost is the usual one for a typed API surface that tracks a large specification. Minor versions have moved within the 9.x line, and the package ships generated type declarations for both import and require paths, so a TypeScript project will get compile errors rather than silent runtime changes when an option is renamed or removed. The npm scripts include a test suite run through vitest with coverage, a lint step, and a prettier check, and the pre-commit hook runs prettier and lint, which is a reasonable signal about how changes are gated.

The licence is MIT, declared in the LICENSE file at the repository root. In practical terms that permits commercial use and modification with attribution and without a copyleft obligation on your own code. That is a summary of what the licence identifier means, not legal advice; if you are redistributing the library itself or embedding it in a product with unusual licensing constraints, read the LICENSE file and talk to your own counsel.

The README lists a Patreon and a BrowserStack sponsorship, which indicates funding for cross-browser testing rather than a commercial support contract. There is no paid tier described, so support is whatever the issue tracker and the documentation provide.

## Conclusion

Adopt docx when you generate .docx files from data you already hold: invoices, CVs, reports, exports from a web app. Do not adopt it if your job is round-tripping documents that users edited in Word, since the repository presents generation, not fidelity-preserving editing. Before committing, check the demo file closest to your output shape, confirm the version you install matches the API in the docs at docx.js.org, and verify on the machines that will open the files.

## FAQ

### How do I install docx?

Install it from npm with npm install docx. The README points to npmjs.org/package/docx for the package and to docx.js.org for usage documentation and examples.

### Is there a free DOCX editor for docx?

The repository links Docx.js Editor, an interactive playground where you can write code and preview the result in real time. It is a browser playground for the library, not a general word processor.

### Does docx work in Node and in the browser?

Yes. The package description states it works for Node and on the Browser, and the README links examples for plain HTML/JS as well as Angular, React and Vue.js.

### What licence does docx use?

The repository declares MIT in its LICENSE file. That permits commercial use and modification, but the article's summary is not legal advice.

### Which version of docx should I install?

The repository package.json is at 9.7.1, released on 2026-05-27. Installing the docx package gets you the latest published version unless you pin one.

## Sources

- [dolanmiu/docx on GitHub](https://github.com/dolanmiu/docx)
- [License: MIT](https://github.com/dolanmiu/docx/blob/master/LICENSE)
- [Project website](https://docx.js.org/)
- [README](https://github.com/dolanmiu/docx/blob/master/README.md)
- [Releases](https://github.com/dolanmiu/docx/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/dolanmiu-docx
