DEV Community

Filip Luca
Filip Luca

Posted on

The most complete Angular UI library has 35 open accessibility bugs. A fair teardown of PrimeNG on Angular 21.

PrimeNG calls itself "the most complete Angular UI component library," and points at Fortune 500s and governments as users. It's genuinely one of the most-used libraries in the Angular ecosystem — 12.5k stars, a release the same week Angular 21 shipped, vendor-backed by PrimeTek. I reach for it myself.

So this isn't a hit piece. It's the exact 5-day architecture review I run for clients, pointed at a public, production-grade target, on a specific date (v21.1.9, the current latest, checked 15 July 2026). Every finding below links to PrimeNG's own issue tracker or source. If you're betting an enterprise Angular app on PrimeNG in 2026, here's what I'd check before you commit — six findings with receipts, then a few more I'd dig into in a full review.

Why v21 and not the v22 release candidate

PrimeNG 22 is in RC (rc.3 landed 15 July, tracking Angular 22). I'm reviewing 21.1.9 deliberately: it's what npm install primeng gives you today, and it's what every production Angular team is actually running.

It's also worth noticing that 21.1.9 shipped on 4 June — the stable line has had no release in six weeks while the RC moves, and the accessibility backlog below sits open in the meantime. If your answer to a v21 finding is "that's fixed in v22," check it — and then check what upgrading a real app to a new Angular major costs you.

1. Accessibility: the marketing says "enterprise," the tracker says otherwise

PrimeNG carries 35 open issues under its own Component: Accessibility label, and 57 open issues mentioning aria (open a11y issues).

These aren't theoretical — and they cluster. Breadcrumb alone carries three separate open a11y defects: #19527 (a nav with no aria-label, tripping the axe landmark-unique rule), #19523 (aria-current="page" simply not implemented), and #19520 (separators not hidden from the accessibility tree). One small component, three ways to fail an audit.

Recent reports keep landing: #19635 (Table and TreeTable emit th elements without scope, June 2026) and #19626 (DatePicker screen-reader defects).

Why it matters: if you sell into the EU, the European Accessibility Act turned WCAG 2.2 AA from a nice-to-have into a legal obligation in 2025. "We used a component library" is not a defence — the audit lands on your product.

The fix: before adopting any component, run it through axe + a screen reader in your app; treat the library's a11y as unverified until you've checked the specific components you ship.

2. The accessibility gap is in keyboard behaviour — the part axe can't see

Automated tooling catches contrast, missing labels, ARIA misuse. It cannot tell you whether a keyboard user can actually operate the thing — that's roughly 70% of real accessibility work, and it's where PrimeNG's open backlog concentrates.

On v21 today:

Why it matters: a green axe run on a page built from these components will tell you you're compliant. You aren't. Every one of these passes automated scanning and fails a real user with a keyboard.

The fix: for every interactive component you adopt, tab through it yourself before you commit — no mouse, then again with a screen reader on. It takes ten minutes per component and it's the only test that finds this class of defect.

3. Signals: the migration started, and it's genuinely mid-flight

PrimeNG began modernizing toward signal inputs in v20, but the Table — the component most enterprise apps lean on hardest — tells the story. In v21.1.9 its source carries 94 @Input() decorators against 13 signal input()s, and 26 @Output() EventEmitters against zero output(). Library-wide, output() does not appear in the component source at all.

Why it matters: a half-migrated API means inconsistent ergonomics today and a second wave of breaking changes still ahead of you — you will pay the migration cost, just later and on someone else's schedule.

The fix: wrap the components you use behind your own thin presentational components, so the eventual signal-API churn hits one adapter layer in your code, not 200 call sites.

4. Zoneless is "Initial" — their word — and the one fix I can find hasn't reached a release

PrimeNG's v21 launch announcement lists "✅ Initial Zoneless Support." "Initial" is doing a lot of work.

#19401p-select with virtual scroll rendering a blank dropdown until you interact — is still open, tagged Resolution: Workaround.

And there's #19497, where DynamicDialog throws a TypeError on offsetHeight under provideZonelessChangeDetection(). It was closed on 6 July with no linked commit or PR — but here's the thing: npm install primeng@21.1.9 today still resolves @primeuix/motion@0.0.10, the exact version the reporter hit, and the offsetHeight read in it is still unguarded. PrimeNG's last stable release was 4 June — a month before the issue was closed. Whatever the fix was, no released version contains it.

Why it matters: a closed issue is not a shipped fix, and "it's fixed on master" doesn't help an app in production. If your architecture is zoneless — and it should be, for new Angular apps — you inherit this until a stable release says otherwise.

The fix: build a spike with the specific PrimeNG components you depend on under provideZonelessChangeDetection() before you commit, and check the resolved version of the transitive dep, not just the headline one.

5. Table performance is a known, current regression

The Table is PrimeNG's flagship and its perf pressure point. #19537 "Table: rendering performance regression" is open and explicitly describes a v20/v21 regression versus v17; #18028 reports TreeTable re-render cost.

PrimeNG's own docs steer large-data users elsewhere: "Virtual Scrolling is an efficient way to render large amount data" (primeng.dev/table) — i.e., the naive table isn't meant to scale by default.

Why it matters: "it was fast in our prototype with 50 rows" is how you find this in production with 10,000.

The fix: don't trust a vendor benchmark or mine — measure it in your build: render your real row count with your real columns, profile change detection, and decide virtual-scroll/lazy up front, not after launch.

6. The licence is MIT — until the moment you need LTS

This is the one nobody checks, and it's a procurement problem, not an engineering one.

PrimeNG's community versions are MIT, and that's genuinely generous. But LICENSE.md contains a second licence: every version with an -lts suffix is proprietary — "source-code cannot be resold or distributed," "can modify source-code but cannot distribute modifications." And an LTS line exists on npm for v14 through v20 (primeng@20.5.1-lts, 19.2.0-lts, 18.0.7-lts…).

Why it matters: LTS is exactly what you reach for when you're an enterprise pinned to an older Angular major and can't upgrade on PrimeTek's cadence — which is precisely the moment the licence stops being MIT. "We're on the MIT one" is true right up until the support conversation.

The fix: if there's any chance you'll need LTS, read that second half of LICENSE.md with whoever signs your contracts, before you standardise on the library — not during the incident that makes you need it.

What I'd dig into with more time

API consistency across the 90+ components, SSR/hydration behaviour of overlay components, and theming/token governance after the v20 styled-mode overhaul — each is a place I'd spend an hour in a paid review.

What PrimeNG does genuinely well

Because a fair teardown says so.

Breadth is unmatched: 90+ components from one vendor is a real procurement advantage. The Angular-major parity is disciplined (v21 out the same week as Angular 21; v22 already in RC alongside Angular 22). The community line is MIT, it's actively patched, and the styled/unstyled mode in recent versions is a thoughtful answer to theming.

They also fix things — two issues I had flagged for this piece in June were closed before I published.

For a lot of internal tools, PrimeNG is the right call. The point isn't "don't use PrimeNG" — it's "know exactly what you're inheriting before you do."

The close

That's a 20-minute read of a public repo.

The version I run for clients is 5 days, on your codebase, across architecture, change detection, performance, accessibility, security, tests, and API hygiene — every finding rated impact × effort and sequenced into a fix order. Written report + a 30-minute walkthrough, €999 flat, full refund if I can't find 10 things worth fixing.

If that'd be useful: artificialsense.ai/audit

— Filip Luca

Top comments (0)