npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

document-media-extractor

v0.1.2

Published

Local-first extraction of embedded media from document and ZIP containers.

Downloads

448

Readme

Document Media Extractor

Extract original embedded media locally from OOXML, OpenDocument, EPUB, CBZ, and ZIP containers—no uploads or backend required.

What it supports

The stable release supports the local ZIP-based document and archive formats below through a Node API and CLI. It is deliberately local-first: no backend, account, upload, or remote URL is involved.

| Input | Embedded media path | Provenance recorded | | --- | --- | --- | | Word OOXML: DOCX, DOCM, DOTX, DOTM | word/media/ | Word accessibility descriptions, where relationship mapping is reliable | | PowerPoint OOXML: PPTX, PPTM, POTX, POTM | ppt/media/ | slide number and OOXML relationship | | Excel OOXML: XLSX, XLSM, XLTX, XLTM | xl/media/ | workbook, worksheet, drawing, and OOXML relationship | | OpenDocument: ODT, ODS, ODP | embedded image paths | original archive path | | EPUB 2 / EPUB 3 | cover and illustration paths | original archive path | | CBZ | comic page paths, ordered naturally | original archive path | | ZIP | image files in nested folders | original archive path |

Legacy binary Office formats (.doc, .ppt, .xls), PDF, iWork, and DRM-protected ebook formats are intentionally not supported yet. Convert legacy Office files to OOXML first.

Need a no-install, browser-only workflow for one Office document? Use the matching local browser tool: Word image extractor, PPT image extractor, or Excel image extractor. Browser-only equivalents for OpenDocument, EPUB, CBZ, and ZIP archives are available on the same site.

Install from npm

npm install document-media-extractor

Run the CLI without cloning the repository:

npx document-media-extractor ./brief.docx --out ./extracted

The CLI accepts every format in the table above. It writes retained original media files and a manifest.json, and refuses to overwrite an existing output directory.

Develop from GitHub

git clone https://github.com/WanderZil/document-media-extractor.git
cd document-media-extractor
pnpm install
pnpm build
node dist/cli.js ./brief.docx --out ./extracted

For a policy file:

node dist/cli.js ./brief.xlsx --out ./extracted --policy ./policy.json

To process every supported document directly inside one folder (non-recursive), use batch mode. Each successful input gets its own numbered output folder, and batch-manifest.json records both successes and isolated failures.

node dist/cli.js --batch ./documents --out ./extracted-batch --policy ./policy.json

Node API

import { readFile } from "node:fs/promises";
import { extractDocumentMedia } from "document-media-extractor";

const result = await extractDocumentMedia({
  sourceName: "book.epub", // see the supported-format table above
  bytes: new Uint8Array(await readFile("book.epub")),
  policy: {
    minWidth: 320,
    minPixels: 100_000,
    exactDuplicates: "exclude",
    namingTemplate: "{source}-{index}-{name}",
  },
});

result.assets contains only retained original media bytes. result.manifest retains every discovered item with source provenance, SHA-256, measurements, export name, and an INCLUDED or exclusion decision. The default policy retains every media file.

Image dimensions are read without decoding pixels for PNG, GIF, and baseline/progressive JPEG. Other media remains extractable, but dimension filters mark it UNREADABLE_DIMENSIONS instead of guessing.

{name} uses a Word accessibility description only when its OOXML relationship maps it reliably to one media part; otherwise it falls back to the embedded filename. Names are sanitized and collision-resolved deterministically.

Safety and batches

Callers can opt into bounded work for CI or user-supplied files. Limit errors are explicit (for example, LIMIT_EXPANDED_BYTES), and AbortSignal cancellation reports CANCELLED rather than returning partial results. extractDocumentMediaBatch(inputs) isolates failures: successful inputs retain their results while other items report a stable error code.

policy: {
  limits: {
    maxInputBytes: 50_000_000,
    maxArchiveEntries: 2_000,
    maxExpandedBytes: 200_000_000,
    maxMediaCount: 500,
    maxMediaBytes: 20_000_000,
    maxTotalMediaBytes: 100_000_000,
  },
}

Local review UI

Start a static server from this checkout, then open it in a modern Chromium browser:

python3 -m http.server 4173 --directory review

Choose a CLI output folder in the browser. The UI reads manifest.json and the exported files directly from the local file picker. It shows every Manifest decision; only retained files have a selectable preview because excluded originals are not written to the output folder.

It uses Canvas dHash (Hamming distance ≤ 8) to mark possible visual matches among browser-decodable retained images. This is an advisory UI feature, capped at 250 items to keep the browser responsive; it never changes the extractor’s exact-byte duplicate decision or removes files. Reviewers can select retained assets and download a new ZIP containing the original files plus a review annotation in its Manifest.

For the most useful review, extract with the default preservation policy so all media remains available to inspect.

Scope and privacy

Processing is local. The project does not use a backend, upload documents, require an account, or fetch remote URLs. The browser UI is optional: the Node API and CLI are the primary extraction interfaces, while the UI is for manual visual review before a ZIP export.

Related workflow

Need images from webpages rather than local document containers? Bulk Image Download handles URL-based, browser-aware collection.

Contributing

See CONTRIBUTING.md. All fixtures must be safe to redistribute.

License

MIT