Skip to content

Bundle Size ​

One of the primary design goals of @crimson_dev/use-resize-observer is an aggressively small bundle. The full main entry — pool, scheduler, and hook — weighs just 1.12 kB min+gzip.

Size Budget ​

Entry PointMin+GzipLimitDescription
Main (useResizeObserver)1.12 kB1.2 kBFull hook with pool + scheduler
Core (/core)329 B500 BEventTarget-based, framework-agnostic
Server (/server)115 B300 BSSR/RSC no-op entry
Shim (/shim)527 B1.5 kBLegacy browser polyfill
Worker (/worker)1.17 kB1.5 kBSAB-based measurement sharing

Measured with size-limit

All size figures are measured using size-limit with the project's .size-limit.json config. The CI pipeline enforces these budgets on every push and pull request -- a PR that exceeds a budget will fail.

Why So Small? ​

Zero dependencies ​

The library has no runtime dependencies. The only peer dependency is react itself. There is no polyfill, no utility library, no abstraction layer.

ESM-only ​

By shipping only ESM, we avoid the overhead of CJS compatibility wrappers, __esModule markers, and dual-package interop code. Your bundler receives clean ES modules that tree-shake perfectly.

Single observer pattern ​

The shared observer pool is a handful of lines: one ResizeObserver, one WeakMap<Element, Callback | Set<Callback>> with single-callback fast path, and a double-buffered RafScheduler. There is no class hierarchy, no plugin system, no event emitter.

ES2026 target ​

By targeting ES2026, we avoid shipping polyfills or transpilation output for features like using declarations, optional chaining, or nullish coalescing. The raw source is nearly identical to the compiled output.

Tree-Shaking ​

The library is structured as multiple entry points to enable granular tree-shaking:

text
@crimson_dev/use-resize-observer       -- core hook only
@crimson_dev/use-resize-observer/worker -- worker mode
@crimson_dev/use-resize-observer/server -- SSR/RSC entry

If you only import the core hook, the worker and server code is never included in your bundle:

tsx
// Only the main hook is bundled (1.12 kB)
import { useResizeObserver } from '@crimson_dev/use-resize-observer';
tsx
// Main + worker addon is bundled (~2.3 kB)
import { useResizeObserver } from '@crimson_dev/use-resize-observer';
import { useResizeObserverWorker } from '@crimson_dev/use-resize-observer/worker';

Verifying tree-shaking ​

You can verify what gets included using your bundler's analysis tools:

bash
# With esbuild
npx esbuild src/index.tsx --bundle --minify --metafile=meta.json --outfile=out.js
npx esbuild --analyze=verbose meta.json

# With webpack
npx webpack --stats-modules-by-issuer

# With vite
npx vite build --report

Size Comparison ​

How does this compare to alternatives?

LibraryMin+GzipDependenciesESM
@crimson_dev/use-resize-observer1.12 kB0ESM only
use-resize-observer@10.0.0~1.1KB0Dual
react-resize-detector~3.4KB2Dual
@react-hook/resize-observer~1.8KB2Dual
react-use (useResizeObserver)~15KB+20+No

Enforcing the Budget ​

The CI pipeline runs a size check on every PR:

yaml
# .github/workflows/ci.yml (simplified)
- name: Check bundle size
  run: npx size-limit

Breaking the budget

If a PR increases any entry point beyond its configured limit, the CI size check will fail. To add new features without breaking the budget, consider adding them as a separate entry point (like /worker or /server).

Import Cost ​

If you use the Import Cost VS Code extension, you will see the size inline next to your import statement. The main hook should display as approximately 1.12 kB gzip.

Next Steps ​

  • Performance -- Runtime performance, not just bundle size
  • Architecture -- Why the pool pattern keeps code minimal
  • Worker Mode -- The additional 1.17 kB for SAB-based measurement sharing

Released under the MIT License.