Show HN: DOM-docx – HTML to native, editable Word docs (MIT)

floodtide/dom-docx
main
Branches
Tags
Go to file
Code
Open more actions menu
Folders and files
Name
Name
Last commit message
Last commit date
Latest commit
History
42 Commits
42 Commits
.github/
workflows
.github/
workflows
docs
docs
examples
examples
output
output
scripts
scripts
src
src
tools
tools
.gitignore
.gitignore
.nvmrc
.nvmrc
AGENTS.md
AGENTS.md
API.md
API.md
CHANGELOG.md
CHANGELOG.md
CONTRIBUTING.md
CONTRIBUTING.md
LICENSE
LICENSE
README.md
README.md
package-lock.json
package-lock.json
package.json
package.json
tsconfig.build.json
tsconfig.build.json
tsconfig.json
tsconfig.json
View all files
Repository files navigation
README
Contributing
MIT license
More
items
dom-docx
Convert semantic
HTML fragments
to native, editable
Word documents
(OOXML): paragraphs, runs, lists, tables, images. Not screenshots or layout hacks.
Live demo:
dom-docx.com
. Try the converter, browse showcases, read the learn guide.
Built with a visual regression loop: render HTML in Chromium, convert to docx, rasterize via LibreOffice, score layout + structural fidelity against a human-validated metric, iterate. Latest scores:
TEST-SCORES.md
· methodology:
SCORING.md
.
Install
npm install dom-docx
Requires
Node.js ≥ 20
. No browser or Playwright is needed for the default
inline
path.
When is Playwright needed?
Entry
styleSource: “inline”
styleSource: “computed”
rasterizeInPlace
Node
(
dom-docx
)
Pure JS, no browser
Playwright + Chromium
Playwright + Chromium
(same headless page)
Browser
(
dom-docx/browser
)
Pure JS, no live DOM
Live page
: native
getComputedStyle
Live page
: canvas/SVG → PNG

in the tab
On Node,
playwright
is an
optional peer dependency
.
npm install dom-docx
pulls only
docx
,
cheerio
and
fflate
, nothing heavy. It is loaded lazily when you pass
styleSource: “computed”
or
rasterizeInPlace
. To use those paths, install Playwright and Chromium yourself, once:
npm install playwright
npx playwright install chromium
Playwright is also used by the
dev test harness
(not required to use the library). Contributors:
npm run setup
after clone.
LibreOffice is
not
needed to convert. It is only used for the visual test harness.
CLI
Convert a file without writing any code:
npx dom-docx input.html -o output.docx
npx dom-docx input.html
#
writes input.docx next to it
cat fragment.html
|
npx dom-docx – -o –
#
stdin → binary stdout (pipelines)
npx dom-docx input.html -s computed
#
stylesheet/class HTML (needs playwright installed)
npm install -g dom-docx
#
optional: install globally, then run “dom-docx” without npx
Input is a
body HTML fragment
, same as the API.
–help
for all options.
Quick start
Browser
import
{
convertHtmlToDocx
}
from
“dom-docx/browser”
;
const
html
=
`

Quarterly Report

Revenue grew 12% year over year.

  • North America
  • EMEA

`
;
const
blob
=
await
convertHtmlToDocx
(
html
)
;
// e.g. trigger a download in the browser
const
a
=
document
.
createElement
(
“a”
)
;
a
.
href
=
URL
.
createObjectURL
(
blob
)
;
a
.
download
=
“output.docx”
;
a
.
click
(
)
;
No Playwright, no Node. This runs entirely in the user’s tab. See
Browser bundle
below.
Node
import
{
writeFile
}
from
“node:fs/promises”
;
import
{
convertHtmlToDocx
}
from
“dom-docx”
;
const
html
=
`

Quarterly Report

Revenue grew 12% year over year.

  • North America
  • EMEA

`
;
const
docx
=
await
convertHtmlToDocx
(
html
)
;
await
writeFile
(
“output.docx”
,
docx
)
;
Pass a
body fragment only
(no

/

/

required). Defaults: US Letter, 1″ margins, Arial 10.5pt body text.
v0.1.x capability
Supported (default
styleSource: “inline”
):
Headings, paragraphs, lists (