Technology Sep 01, 2026 · 7 min read

Why we built an MIT Angular data grid instead of paying for the enterprise tier

Every Angular app of a certain size eventually needs a real data grid. Not a styled <table> — a grid: sortable and filterable columns, row grouping, aggregation, an Excel export, sticky columns, inline editing, virtual scroll for the big lists. When you go shopping for one, the market sorts i...

DE
DEV Community
by Inandu SAS
Why we built an MIT Angular data grid instead of paying for the enterprise tier

Every Angular app of a certain size eventually needs a real data grid. Not a
styled <table> — a grid: sortable and filterable columns, row grouping,
aggregation, an Excel export, sticky columns, inline editing, virtual scroll for
the big lists.

When you go shopping for one, the market sorts itself into two piles pretty
quickly:

  1. Lightweight grids that do sorting, filtering and paging, and stop there. The moment you need grouping or an export, you're writing it yourself.
  2. Full-featured grids where the genuinely useful parts — row grouping, Excel export, cell-range selection, aggregation, tree data, pivoting — live behind a per-developer enterprise licence.

We kept landing in pile 2, and kept bouncing off the same wall. This is why we
ended up building inandu-grid
@inandu-solutions/grid-angular, MIT, every feature free — and the decisions
that shaped it.

The enterprise-tier tax

The commercial Angular grids are good software. That's not the complaint. The
complaint is which features are gated.

Look at what a typical "Enterprise" tier includes: row grouping, aggregation,
the Excel exporter, cell-range selection, master/detail, tree data, pivoting,
the server-side row model. Now look at your requirements doc. For a lot of
line-of-business apps, that list is the requirements doc. The free core gets
you a sortable table; the paid tier gets you the thing you were actually asked
to build.

And the licence itself has a cost beyond the invoice:

  • It's per-seat. Every developer who touches the repo needs a seat, CI sometimes counts, and you get to have a conversation with procurement and legal before you can npm install.
  • It's a redistribution question. If you ship a product that embeds the grid, or you're an agency building for clients, the licensing math gets its own meeting.
  • It follows you to renewal. The dependency doesn't stop being load-bearing when the term ends.

For a large app with a budget and a need for pivoting and integrated charts,
that's a completely reasonable trade — and if that's you, AG Grid Enterprise
is genuinely the right tool
and you should buy it. But a huge number of teams
are paying that tax for grouping and an Excel button, and that felt like a gap
worth filling.

What we wanted instead

The brief we wrote for ourselves:

  • MIT, in full. No tier. Row grouping, aggregates, CSV/Excel/PDF export, cell-range selection, inline editing — all in the one package, all under the one licence.
  • Small dependency footprint. A grid shouldn't dominate your bundle. It has four runtime dependencies: @angular/cdk (virtual scroll), @ngx-translate/core (i18n), jspdf (PDF export) and tslib (the TypeScript helper runtime). jspdf is lazy-loaded, so you only pay for it if you call the PDF exporter.
  • Angular-native, current-Angular. Standalone components, signal-based inputs and outputs, no NgModules, no zone.js assumptions baked into the public API. Two components you import and use: <inandu-grid> and <inandu-column>.
  • The grid never owns your data. It consumes a plain array and emits every mutation — rowSave, rowCreate, rowDelete, selectionChange. It never reaches into your model. Fetching, persistence and optimistic updates stay in your app, where they belong.
  • Honest scope. No pivoting. No integrated charts. No built-in server-side row model (there's a serverSide mode that turns off local sort/filter/page and emits the events for you to fetch each page — but you write the fetch). If those are hard requirements, we'll tell you to go buy the enterprise grid.

That last point matters. "Lightweight alternative to the big commercial grids"
only means something if you're willing to say what you left out.

What it looks like in code

Both components are standalone, so they go straight into a component's
imports:

import { Component } from '@angular/core';
import {
  InanduGridComponent,
  InanduColumnComponent,
  InanduGridRow,
} from '@inandu-solutions/grid-angular';

@Component({
  selector: 'app-people',
  imports: [InanduGridComponent, InanduColumnComponent],
  template: `
    <inandu-grid
      [data]="rows"
      [paging]="{ pageSize: 10 }"
      filter="true"
      lang="en">
      <inandu-column field="name"   title="Name"   sortable="true"></inandu-column>
      <inandu-column field="age"    title="Age"    type="number"  sortable="true" aggregate="avg"></inandu-column>
      <inandu-column field="team"   title="Team"   groupable="true"></inandu-column>
      <inandu-column field="joined" title="Joined" type="date"    format="DD/MM/YYYY"></inandu-column>
      <inandu-column field="active" title="Active" type="boolean" format="Yes|No"></inandu-column>
    </inandu-grid>
  `,
})
export class PeopleComponent {
  rows: InanduGridRow[] = [
    { name: 'Ada Lovelace', age: 36, team: 'Analytical', joined: new Date(2021, 2, 14), active: true },
    { name: 'Alan Turing',  age: 41, team: 'Bletchley',  joined: new Date(2019, 8, 1),  active: false },
    { name: 'Grace Hopper', age: 45, team: 'Bletchley',  joined: new Date(2020, 0, 20), active: true },
  ];
}

That's grouping-by-drag, average aggregation, type-aware filtering, date
formatting and pagination — no NgModule, no config object, no licence key.
Each feature is opt-in per column or per grid; an unconfigured grid is just a
table.

Inline editing follows the same "we don't touch your array" rule:

<inandu-grid [data]="rows" creatable deletable (rowSave)="save($event)" (rowCreate)="create($event)">
  <inandu-column field="name"  title="Name"  editable="true" required></inandu-column>
  <inandu-column field="email" title="Email" editable="true" pattern="^\S+@\S+$"></inandu-column>
</inandu-grid>
save({ row, values }: InanduGridRowSave) {
  // you decide: patch locally, call the API, roll back on failure
  Object.assign(row, values);
}

The comparison, with the caveats attached

inandu-grid AG Grid PrimeNG Table
Licence MIT, all features MIT core + paid Enterprise (grouping, Excel, range selection, pivot, tree data…) MIT
Footprint 4 runtime deps (@angular/cdk, @ngx-translate/core, jspdf lazy-loaded, tslib) large ships as part of the full PrimeNG library
Frameworks Angular only (signals, standalone) Angular / React / Vue / vanilla Angular only
Row grouping & aggregates ✅ free Enterprise
Excel / CSV / PDF export ✅ free (.xls + CSV + PDF) CSV free; Excel is Enterprise CSV free
Pivoting, integrated charts Enterprise
Server-side row model bring-your-own (serverSide) Enterprise bring-your-own

This is orientation, not a scorecard — every one of these projects moves, so
check their own docs for the current details. AG Grid runs on four frameworks
and does things inandu-grid deliberately doesn't. PrimeNG's table is excellent
if you're already all-in on PrimeNG. The pitch here is narrow: if what you
need is a solid, free, lightweight Angular grid and the enterprise features are
the ones you were reaching for, you shouldn't have to pay for a tier to get
them.

A couple of design decisions worth calling out

Export without the weight. CSV is UTF-8 with a BOM so Excel opens it
cleanly. The "Excel" export writes SpreadsheetML (.xls) and has zero
dependencies — no bundled xlsx library. PDF uses jspdf, loaded lazily on first
use. (Real .xlsx is the one thing we moved into a separate paid add-on,
grid-pro — the dependency-free .xls covers most "email me the numbers"
needs.)

i18n per grid instance. Five languages ship in the box (en, es, fr, it, zh)
plus customTranslations, and each grid instance is isolated — a grid set to
lang="es-AR" doesn't reach into a global translation service or affect any
other grid on the page.

Theming is just CSS. Three presets (material, dark, minimal), and
every structural element carries a stable inandu-* class with no default rule
attached, so you style from your own global stylesheet without fighting
specificity.

Where this is going

The npm name @inandu-solutions/grid-angular is deliberate: the framework-agnostic
core lives in projects/inandu-grid/src/lib/core/, and the bare
@inandu-solutions/grid name is reserved for a framework-neutral umbrella. A
React port would ship as @inandu-solutions/grid-react against that same core.
No promises on timing — but the architecture is pointed that way.

Try it

npm install @inandu-solutions/grid-angular

Requires Angular ^21.2.0. MIT. If you build something with it, or you hit an
edge we haven't, open an issue — that's the fastest way this gets better.

DE
Source

This article was originally published by DEV Community and written by Inandu SAS.

Read original article on DEV Community
Back to Discover

Reading List