Home/Production/Angular Compatibility

Angular Compatibility

GridCraft supports Angular 19, 20, 21 and 22. Every version in that range is built in CI on every change — twice per major, in two package combinations. Nothing outside it is claimed.

Current release: 1.0.0, both packages, published together and always at the same version. @gridcraft/angular is MIT-licensed; @gridcraft/enterprise is commercial and carries its licence in the package.

The matrix

Two Angular versions per major — the exact lower bound the range promises, and the newest patch a fresh install gets today — each built as a free-only app and as a free + enterprise app. Sixteen builds, every one of them on every change:

Angular@gridcraft/angular+ @gridcraft/enterprise
19.0.0 (range floor)✔✔
latest 19.x✔✔
20.0.0 (range floor)✔✔
latest 20.x✔✔
21.0.0 (range floor)✔✔
latest 21.x✔✔
22.0.0 (range floor)✔✔
latest 22.x✔✔

Each cell installs the published tarball into a throwaway Angular application and runs a production build with strictTemplates on — the same thing your CI does, on the same bytes you download. The sixteen builds run as sixteen separate jobs on every push, and one red cell does not hide the other fifteen.

Why 19 is the floor

Two concrete reasons, not a policy preference:

  • The grid's templates use @let, which requires Angular 18.1. That rules out 17 and 18.0 outright.
  • @gridcraft/enterprise uses provideAppInitializer, which arrived in Angular 19. On 18.2 the free package builds and the enterprise package does not — we measured it.

Rather than publish two different floors, both packages declare 19. It is the lowest version we build, so it is the lowest version we claim.

The upper bound is deliberate

The range ends at <23.0.0. When Angular 23 is released, installing GridCraft alongside it will fail rather than appear to work — until we have built against it and shipped a release that widens the range. That is a feature: an install error the day Angular 23 lands is better than a template compile error three weeks later.

// Both packages declare the same range
"peerDependencies": {
  "@angular/common": ">=19.0.0 <23.0.0",
  "@angular/core":   ">=19.0.0 <23.0.0"
}

What happens if you go outside the range

npm stops you. That matters more than it sounds, because nothing inside the published artifact enforces the range. Angular libraries ship in a partially-compiled form and your own compiler finishes the job — and the version metadata in that format does not track template syntax. A too-old Angular therefore does not produce a polite "unsupported version" message. It produces a parse error pointing into a minified file inside node_modules:

X [ERROR] "as" expression is only allowed on the primary @if block
    node_modules/@gridcraft/enterprise/fesm2022/gridcraft-enterprise.mjs@0:170457

That exact error is real — it is what an Angular 19 build produced before the version matrix existed and found it. The peer range is the only thing standing between a user and that message, which is why it is verified rather than asserted.

npm install @gridcraft/angular

# npm refuses the install if your Angular is outside the range — that refusal
# is the guard. It is not advisory.

TypeScript and Node

Neither is pinned. TypeScript is resolved by your Angular version — whatever @angular/compiler-cli accepts, the grid accepts, and the matrix above installs it the same way your project does, deliberately: pinning a TypeScript would test a combination no consumer has. Node matters only to your build; the grid ships no server-side runtime beyond the optional SSR licence provider.

Zoneless and SSR

The grid is signals-based throughout and runs zoneless. It also runs with zone.js — the trial applications in the matrix use it, so both configurations are built on every version in the table. Server-side rendering is supported, and the enterprise package ships a separate server entry point so a licence key never has to reach the browser; see Security.

When the table changes

Adding a major to the range is a release, not an edit. The version is added to the matrix first, whatever breaks is fixed, and only then does the published range widen — never the other way round. If this page and your node_modules ever disagree, the peerDependencies in the package are the authority.