Skip to content

Provide a read-only entry point that tree-shakes the write path #582

Description

@fcbwilliams

Summary

A consumer that only wants PDF → Markdown text extraction currently bundles the entire write path,
including ~2.79 MiB of vendored font binaries it never executes. There is no entry point that
expresses "I only read".

Measured with documents.js@1.100.1, one entry point importing only pdfToMarkdown, esbuild
--bundle --minify --format=esm --platform=browser:

minified gzipped
import { pdfToMarkdown } from 'documents.js' 3.83 MiB 2.17 MiB
same, with pdf-codec font assets stubbed 1113 KiB 300 KiB

By package: pdf-codec 3050 KiB, zod 320 KiB, documents.js 232 KiB, markdown-codec 94 KiB,
ooxml.js 66 KiB, odf.js 53 KiB, everything else under 30 KiB each.

Cause, on this side

The root of the font problem is upstream in pdf-codec (filed separately: eager asset imports in
font-registry.js / math-font.js). But documents.js contributes independently: dist/convert/convert.js
carries both conversion directions in a single module, so pdfToMarkdown and markdownToPdf
share a graph. Deep-importing documents.js/convert/convert gives a byte-identical 2.17 MiB — the
./* export map lets you reach the module, but not a narrower slice of it.

That means fixing pdf-codec alone may not be sufficient: as long as the read function and the write
function live in one module, anything the write function needs stays reachable.

Ask

A read-only entry point — documents.js/read, or per-direction modules under convert/ — whose
graph excludes every X-to-PDF renderer and therefore every font asset. No API change for existing
callers; purely additive.

Ideally paired with the pdf-codec change, since both are needed to actually reach ~300 KiB.

Context

The target runtime is Cloudflare Workers, where the entire Worker must fit in 3 MB gzipped on the
free plan (10 MB paid). A 2.17 MiB dependency is most of that budget for one library; 300 KiB is a
non-issue. Fully reproducible from published npm packages.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions