Home/Production/Bundle Size

Bundle Size

What GridCraft costs your application, measured rather than estimated — and an honest account of what tree-shaking does and does not remove.

The packages

Packageminmin + gzipmin + brotli
@gridcraft/angular(free)832.7 KB170.4 KB112.3 KB
@gridcraft/enterprise313.2 KB60.1 KB48.7 KB

Measured 2026-08-24. Regenerated by our build on every release and rendered from that file — this table cannot drift from the artifact, because nobody types it.

The free package is gated in CI at 180 KB min+gzip. A change that pushes it over fails the build; there is no "we will look at it later" path.

What it costs a real application

Package size is not the number you care about. This is: three identical Angular applications, production builds, differing only in how much of the grid they use.

ApplicationRawTransfer (gzip)
Angular alone, no grid128.9 KB39.6 KB
Smallest useful grid742.8 KB166.2 KB
Every export used781.4 KB174.8 KB

Three trial applications, production builds, measured 2026-08-10 — nothing in them but Angular and the grid. Unlike the package table above, these are not regenerated by our build: they need three separate applications, so they are re-measured by hand per release and dated here rather than left undated. The recipe is at the end of this page, and yours is the measurement that matters.

Subtract the baseline and the grid costs 126.6 KB gzip at minimum and 135.1 KB if you touch every export. Those two numbers are close together, and the next section is about why.

Where you import from decides your first download

The figures above are what the grid costs across the whole application. A separate question — usually the one that shows up in a Lighthouse report — is how much of it arrives before your first route resolves. If your grid pages are lazy, the answer should be almost none. It is easy to get almost all of it instead, and nothing warns you.

The cause is one import line. app.config.ts, your root component, and your layouts all load eagerly. When any of them imports from the main @gridcraft/angular barrel — even for a single small symbol like provideGridDefaults or GridDirectionService — the barrel brings every grid component with it, and lazy routes cannot help, because the code is already in your initial chunk.

Import those bootstrap symbols from @gridcraft/angular/core instead. It carries the providers, the direction service and every type and interface, and reaches no grid component at all.

This documentation site's initial downloadRawTransfer (gzip)
Bootstrap symbols from the main barrels1.40 MB317.4 KB
From /core and /license, features per page610.7 KB157.6 KB

The second row is this site's build as of 2026-08-23; the first is the same site before the import paths changed. Both are the Angular builder's own Initial total. Both columns are capped in our CI, and so is the property underneath them — no grid component may appear in the eager import graph at all — so a change that puts this download back fails the build rather than quietly ageing this table.

Same site, same pages, same features — 160 KB less to download before anything appears. Every grid component moved into the lazy chunk of the page that actually renders it.

The main barrel stays correct everywhere else. A page component that renders a grid already imports GridcraftComponent and GridConfig from it, and should keep doing exactly that — it is loading the grid on purpose. The rule is only about files that run before your router does.

Tree-shaking: what it removes, and what it cannot

Both packages set "sideEffects": false and every component is standalone, so your bundler does remove what you never import. Measured, that is 8.5 KB gzip — the difference between the last two rows of the three-application table above.

The grid is one unit. Importing GridcraftComponent brings the header, the body, the virtual scroller, pagination, the filter row, the loading and empty states, the column directives and the core services — because the component genuinely references all of them. Which of those you switch on at runtime is a config value, and no bundler can see a config value at build time. So a minimal grid already ships about 94% of the package.

There is no modules build, and that is deliberate

We measured what a per-feature entry-point split would save before building one. The answer was the 8.5 KB above — because sub-path exports remove what you do not import, and the remaining 126.6 KB is not extra imports, it is the grid.

Shipping a modules API would have meant a permanent public surface, a longer install story and a migration, in exchange for a saving that tree-shaking already delivers. So there is one import path and nothing to configure:

// Everything the grid needs, in one import
import { GridcraftComponent } from '@gridcraft/angular';

The honest framing: if 126 KB gzip for a full-featured data grid is too much for your budget, a smaller build of this grid would not fix that — a simpler table would.

What you can actually do about the number

  • Lazy-load the route. The single most effective change available, and it needs nothing from us: a grid on a lazily-loaded route costs your landing page zero.
  • Do not install the enterprise package if you are not licensing it. It is a separate package for exactly this reason — a free-tier application never downloads a byte of paid code.
  • Serve brotli. The table above shows it against gzip; the difference is free and needs one server setting.
  • Narrow your browserslist. Fewer down-levelling transforms, smaller output. See Supported Browsers.

Measure it in your own application

Our numbers come from a trial app with nothing else in it. Yours will differ, and yours is the one that matters — Angular is shared, so the grid's marginal cost in an application that already uses Angular is lower than a naive sum suggests:

# Measure it yourself — this is what a bundler reports for YOUR app
ng build --configuration production --stats-json
npx source-map-explorer dist/**/main*.js

One thing the figures include

Developer diagnostics. The grid carries a few dozen explanatory console messages — the ones that tell you a feature combination is unsupported or that a transaction was dropped. Most of them never print in a production build, but their text is still in the bundle. It is a small share of the total, and we would rather state that than quote a number that quietly excludes it. See Dev-time Validation for which messages those are.