Context
I maintain @darkroomengineering/fitbox, a text-fitting library built on pretext. We import only four symbols from the main entry:
import {
prepareWithSegments,
measureNaturalWidth,
measureLineStats,
layoutWithLines,
} from '@chenglou/pretext';
Observation
package.json doesn't declare "sideEffects": false, so downstream bundlers (Vite/webpack/rollup) conservatively ship the full transitive closure of pretext's internal modules:
| File |
Size (raw) |
analysis.js |
37 KB |
line-break.js |
33 KB |
generated/bidi-data.js |
23 KB |
layout.js |
22 KB |
measurement.js |
8 KB |
bidi.js |
6 KB |
| Total |
~129 KB raw |
Every downstream consumer ships all 129 KB, even when they exercise only a fraction of the exported surface.
Ask
A scan of dist/*.js shows only top-level const/let initialization (regexes, Sets, let sharedWordSegmenter = null). All pure expressions, safe to mark side-effect-free. With the flag, bundlers can drop unused exports based on what consumers actually import (e.g., the seven layout.d.ts exports fitbox doesn't use, plus unused helpers in analysis.js/line-break.js).
Realistic impact: 20–40% bundle reduction for consumers using a subset of the API, which is most of them.
Secondary (lower priority, separate issue if interested)
generated/bidi-data.js is 23 KB of Unicode data needed only for RTL text. If bidi.js could lazy-load it (dynamic import() gated on a quick RTL scan), latin-only sites would drop 23 KB automatically. Not worth tackling until the sideEffects change is measured.
Willing to PR
Happy to open a one-line PR for the sideEffects change, plus a small bundle-size regression test if that's welcome.
Context
I maintain
@darkroomengineering/fitbox, a text-fitting library built on pretext. We import only four symbols from the main entry:Observation
package.jsondoesn't declare"sideEffects": false, so downstream bundlers (Vite/webpack/rollup) conservatively ship the full transitive closure of pretext's internal modules:analysis.jsline-break.jsgenerated/bidi-data.jslayout.jsmeasurement.jsbidi.jsEvery downstream consumer ships all 129 KB, even when they exercise only a fraction of the exported surface.
Ask
{ "sideEffects": false }A scan of
dist/*.jsshows only top-levelconst/letinitialization (regexes,Sets,let sharedWordSegmenter = null). All pure expressions, safe to mark side-effect-free. With the flag, bundlers can drop unused exports based on what consumers actually import (e.g., the sevenlayout.d.tsexports fitbox doesn't use, plus unused helpers inanalysis.js/line-break.js).Realistic impact: 20–40% bundle reduction for consumers using a subset of the API, which is most of them.
Secondary (lower priority, separate issue if interested)
generated/bidi-data.jsis 23 KB of Unicode data needed only for RTL text. Ifbidi.jscould lazy-load it (dynamicimport()gated on a quick RTL scan), latin-only sites would drop 23 KB automatically. Not worth tackling until thesideEffectschange is measured.Willing to PR
Happy to open a one-line PR for the
sideEffectschange, plus a small bundle-size regression test if that's welcome.