ADR-003: React 19 as Minimum Version
Date: 2026-02-27 Authors: Jean-Francois Meyers Scope: All
@granit/*React packages
Context
Section titled “Context”The @granit/* packages declare react: "^19.0.0" in their peerDependencies.
This requires consumer applications to use React 19 as a minimum.
React 19 introduces several features leveraged by the framework:
- React Compiler: automatic re-render optimization (replaces manual
useMemo/useCallback) use()hook: read promises and contexts during render- Actions: native integration with forms and mutations
- Suspense improvements: native streaming SSR support
refas prop: eliminates the need forforwardRefin wrapper components
Decision
Section titled “Decision”Set React 19 as the minimum version in all @granit/* packages that have a
peer dependency on React:
{ "peerDependencies": { "react": "^19.0.0" }}React 18 and earlier versions are not supported.
Alternatives considered
Section titled “Alternatives considered”Option 1: React 19 minimum (selected)
Section titled “Option 1: React 19 minimum (selected)”- Advantage: modern APIs without conditions or polyfills, React Compiler benefits, simpler codebase
- Disadvantage: excludes applications still on React 18
Option 2: React 18+ with conditional features
Section titled “Option 2: React 18+ with conditional features”- Advantage: broader compatibility
- Disadvantage: conditional branches for multiple major versions, cannot use new APIs unconditionally, maintenance burden
Option 3: React 18 minimum
Section titled “Option 3: React 18 minimum”- Advantage: maximum compatibility
- Disadvantage: cannot leverage React 19 features, technical debt from day one
Justification
Section titled “Justification”| Criterion | React 19 min | React 18+ conditional | React 18 min |
|---|---|---|---|
| API surface | Full React 19 | Partial (conditional) | React 18 only |
| React Compiler | Automatic | Not available | Not available |
| Code complexity | Simple | Higher (version branches) | Simple |
| Forward-looking | Yes | Partial | No |
| Consumer constraint | React 19 required | React 18+ | React 18+ |
Consequences
Section titled “Consequences”Positive
Section titled “Positive”- Modern API: framework code uses new APIs without conditions or polyfills
- Performance: automatic benefit from React Compiler in consumer applications
- Simplicity: no conditional branches for multiple React major versions
- Forward-looking: all consumer applications are already on React 19
Negative
Section titled “Negative”- Exclusion: applications still on React 18 cannot use
@granit/*packages - Ecosystem: some third-party libraries may not yet support React 19 (transitory risk)
Re-evaluation conditions
Section titled “Re-evaluation conditions”This decision should be re-evaluated if:
- A major consumer application cannot upgrade to React 19
- React 20 introduces breaking changes that require multi-version support
References
Section titled “References”- React 19 release notes: https://react.dev/blog/2024/12/05/react-19
- React Compiler: https://react.dev/learn/react-compiler