Analysis (v2, dist/index.mjs = 48.4 kB min / ~16 kB brotli with all exports, ~11.7 kB brotli in a real app bundle)
Measured with an esbuild metafile over src/index.ts (externals: pinia, vue, uuid, nanoid):
| Contributor |
minified |
query/Query.ts |
12.2 kB |
| relation attributes (all 11) |
10.6 kB — morphs alone 4.9 kB, belongsToMany/hasManyThrough/hasManyBy 2.9 kB |
model/Model.ts |
9.8 kB |
repository/Repository.ts |
3.0 kB |
| @pinia-orm/normalizr + Schema |
3.9 kB |
| support/Utils |
2.4 kB |
External packages are NOT the problem — the only bundled dependency is our own normalizr fork (~1 kB brotli). Everything else is core code.
Verified dead ends:
sideEffects: false: zero effect (48 381 → 48 381 bytes) — the dist is flat-bundled and every class is reachable from Model/Query, so per-module shaking has nothing to drop.
- Making normalizr external: only moves bytes, users install & load it anyway.
Why nothing shakes today
Model exposes every relation as a static method (this.hasMany(...)), so all 11 relation classes are statically reachable from any app that touches Model — bundlers cannot drop method bodies. Same for Query's instanceof MorphTo/BelongsToMany handling.
Proposal
- Tree-shakeable relation factories (target: 3.0, or additive in 2.x with the static methods deprecated):
import { hasMany, morphMany } from 'pinia-orm'
static fields () { return { posts: hasMany(() => Post, 'userId') } }
Each factory imports only its relation class. Apps without morph relations save ~4.9 kB min (~1.5 kB brotli), without the exotic many-relations another ~2.9 kB min. Query's relation handling needs to dispatch via the relation instances instead of instanceof imports.
- Purpose-built normalization replacing the generic normalizr fork (~3.9 kB min potential, high effort/risk — separate evaluation).
- Keep measuring: the esbuild-metafile analysis should become a repeatable script so regressions show up in PRs.
Not a 2.0.0 blocker — the release is API-frozen; this is the follow-up plan with real numbers.
Analysis (v2, dist/index.mjs = 48.4 kB min / ~16 kB brotli with all exports, ~11.7 kB brotli in a real app bundle)
Measured with an esbuild metafile over
src/index.ts(externals: pinia, vue, uuid, nanoid):query/Query.tsmodel/Model.tsrepository/Repository.tsExternal packages are NOT the problem — the only bundled dependency is our own normalizr fork (~1 kB brotli). Everything else is core code.
Verified dead ends:
sideEffects: false: zero effect (48 381 → 48 381 bytes) — the dist is flat-bundled and every class is reachable fromModel/Query, so per-module shaking has nothing to drop.Why nothing shakes today
Modelexposes every relation as a static method (this.hasMany(...)), so all 11 relation classes are statically reachable from any app that touchesModel— bundlers cannot drop method bodies. Same forQuery'sinstanceof MorphTo/BelongsToManyhandling.Proposal
Not a 2.0.0 blocker — the release is API-frozen; this is the follow-up plan with real numbers.