Skip to content

feat(build)!: shrink bundle, ship ESM only#62

Merged
johnie merged 2 commits into
mainfrom
feature/updates-2026-05-16
May 16, 2026
Merged

feat(build)!: shrink bundle, ship ESM only#62
johnie merged 2 commits into
mainfrom
feature/updates-2026-05-16

Conversation

@johnie

@johnie johnie commented May 16, 2026

Copy link
Copy Markdown
Owner

What

  • Add bundle size tooling: size-limit + @size-limit/preset-small-lib, enabled on every pnpm run ci.
  • Enable tsdown minify, report, publint, and attw so every build prints sizes and validates the package shape.
  • Drop the CJS build. Ship a single ESM entry (breaking).
  • Routine dev-dep bumps (biome, @types/node, ultracite, vite, vitest, pnpm).
  • Repin domhandler to ^5.0.3 to match cheerio's transitive and remove duplicate install.

Why

Bundle output was effectively unmeasured. tsdown's default behavior already externalizes deps, so the shipped dist is small (~1 KB) — but nothing was gating regressions, and CJS was carrying weight (extra files, dual-package hazard, two attw resolution modes to keep green) for negligible upside. Modern Node has supported ESM natively for years, and the only meaningful bundle-size lever for consumers is cheerio, which a CJS/ESM split doesn't affect.

How

  • .size-limit.json defines two budgets: 2 KB for the dist file alone, 100 KB for the consumer-facing cost (xscrape + cheerio, brotlied). Today: 402 B dist, 88.23 KB consumer.
  • tsdown.config.ts switches to format: ['esm'] with attw: { profile: 'esm-only' } to ignore the expected node10 / CJS-resolution warnings.
  • package.json collapses the exports map to a single conditionless entry, points main at dist/index.mjs, and adds --profile esm-only to check-exports.

Changes

  • feat(build)!: ship ESM only — drop CJS, collapse exports, update attw profile.
  • chore(build): add bundle size tooling and bump dev deps — size-limit, publint, tsdown report/minify, domhandler dedup, dev-dep bumps.

Deployment

Breaking change for consumers using require('xscrape') — must migrate to import (Node 18+) or use dynamic import(). A .changeset/esm-only.md major bump is included; the next changesets release will publish v4.

johnie added 2 commits May 16, 2026 13:06
Add size-limit + @size-limit/preset-small-lib with a 2 KB budget for the
dist file and a 100 KB ceiling for the consumer cost (dist + cheerio,
brotlied). Enable tsdown report, minify, publint, and attw on every
build for visibility into output size and package correctness.

Bump biome, @types/node, ultracite, vite, vitest, and packageManager.
Repin domhandler to ^5.0.3 to match cheerio's transitive resolution and
remove the duplicate install.
Drop the CJS build. The package now publishes a single ESM entry; the
exports map, main, and tsdown formats collapse accordingly. attw runs
with the esm-only profile to ignore the expected node10/CJS-resolution
warnings.

BREAKING CHANGE: consumers using require('xscrape') must migrate to
import. Node 18+ supports ESM natively; CJS callers can use dynamic
import().
@changeset-bot

changeset-bot Bot commented May 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 82fcbe6

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
xscrape Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@johnie johnie merged commit 7ae414f into main May 16, 2026
1 check passed
@johnie johnie deleted the feature/updates-2026-05-16 branch May 16, 2026 11:30
@github-actions github-actions Bot mentioned this pull request May 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant