Compatibility and Versions
This page answers: which versions of the Wow TypeScript packages work with which Wow servers and runtimes, and how sure is that?
Release status
| Package | Status |
|---|---|
@ahoo-wang/wow-client | On npm since Wow 9.2.0 (2026-10-03) |
@ahoo-wang/wow-generator | On npm since Wow 9.2.0 (2026-10-03) |
@ahoo-wang/wow-react | On npm since Wow 9.2.0 (2026-10-03) |
@ahoo-wang/wow-view-engine | On npm since Wow 9.2.0 (2026-10-03) |
@ahoo-wang/wow-view-store | On npm since Wow 9.2.0 (2026-10-03) |
Every version is published from CI with npm provenance. latest points to the newest stable release; a release candidate, when there is one, goes to the next dist-tag (pnpm add @ahoo-wang/wow-client@next). Applications still on @ahoo-wang/fetcher-wow and @ahoo-wang/fetcher-generator 5.x move with the migration guide.
Versions
The TypeScript packages share one version with the Kotlin modules and are released from the same tag: @ahoo-wang/wow-client 9.2.0 is released together with Wow 9.2.0. Breaking changes ship only in an x.Y.0 release and are listed under "Breaking" in the release notes.
- Use one version for all Wow packages of an application.
wow-generatorandwow-reactdeclare@ahoo-wang/wow-clientas a peer with~x.y.z, so the package manager warns when they differ in minor version. - Prefer the version of the service you call. That combination is the one CI tests end to end.
- Regenerate with the generator of the same version as the
wow-clientthe generated code compiles against.
Version ranges
The version follows Wow, not semver: a minor release (x.Y.0) may break the TypeScript API, and only patch releases (x.y.Z) are guaranteed compatible. By default pnpm add and npm install save a caret range (^x.y.z), which lets a later install pick up the next minor without anyone deciding to upgrade. Save a tilde range instead, which accepts patches of one minor only. Set it in the project before installing the Wow packages; where it goes depends on the package manager.
pnpm reads its settings from pnpm-workspace.yaml (pnpm 11 no longer reads them from .npmrc). Add this line to the project's pnpm-workspace.yaml, creating the file if the project has none; pnpm 10 and 11 both honour it:
savePrefix: '~'pnpm config set save-prefix '~' --location project writes the same line. Without --location project the setting goes into your user configuration and applies to every project on the machine.
npm reads it from the project's .npmrc:
save-prefix=~Or pin exact versions:
pnpm add --save-exact @ahoo-wang/wow-client
pnpm add -D --save-exact @ahoo-wang/wow-generatorMove to the next minor on purpose, all Wow packages together, after reading the "Breaking" section of its release notes. The Fetcher peers follow semver; a caret range suits them, but the tilde setting above applies to every package you add, so add them with an explicit range (pnpm add @ahoo-wang/fetcher@^<version>) or accept the tilde.
Support window
The TypeScript npm packages follow the same support policy as the rest of Wow, stated in the security policy: fixes land on the latest stable release line, and fixes for older lines are decided case by case. Staying on one minor with ~ or an exact version is safe for a while; plan to move to the latest minor to receive fixes.
Wow servers
The root entry of @ahoo-wang/wow-client and every default speak the FilterExpression query model, which Wow 8.11 introduced. Wow 8.10 understands only the older Condition model, which the package keeps on its own subpath, @ahoo-wang/wow-client/legacy, until v10.
| Server | Queries | How the application builds them | What CI verifies |
|---|---|---|---|
| Wow 9.x | FilterExpression | Root entry: filter.*, singleQuery / listQuery / pagedQuery | Changes to the server, the client or the generator: the generator's output against a server built from the same commit must equal the committed clients byte for byte and compile, and the integration tests run against that server. Client and generator changes also run a smoke test against the published 9.1.3 and 9.1.5 example servers, and type-check the code generated from them |
| Wow 8.11.x | FilterExpression; raw() is not available | Root entry, as for 9.x | Client and generator changes: a runtime smoke test against the published 8.11.5 example server, and the code generated from it type-checks |
| Wow 8.10.x | Condition only | @ahoo-wang/wow-client/legacy for the queries, the root entry for everything else | Client and generator changes: the code generated from the published 8.10.8 example server type-checks. Nothing runs against it |
| Before 8.10 | — | Not supported | — |
What the rows mean in practice:
- 8.10. Build queries with
@ahoo-wang/wow-client/legacy; the query clients accept both models.getByIdandgetStateByIdsend aFilterExpression, so against 8.10 callsingleorsingleStatewith a/legacyquery built fromaggregateId(id). Code the generator produces from an 8.10 document imports itsConditiontypes from/legacyby itself. Only type checking covers this row: test the queries your application uses against your own 8.10 server. See Wow 8.10 servers. raw(), theConditionoperator that passes a raw query to the store, exists only on/legacy, and servers from 8.11.0 on answer it with 400. It has noFilterExpressionreplacement.- Before 8.11.1, the OpenAPI document does not publish
x-wow-query-fields; the generator then reads an aggregate's query fields from theConditionschema instead. - Newer client, older server. A client method whose endpoint the server does not have yet — for example
EventStreamQueryClient.loadorWowMetadataClient— fails there, typically with 404. Everything the server has works. - Older client, newer server. The server may send fields the client's types do not name; they arrive in the JSON and the types ignore them. Regenerate to see them.
List queries without a limit
listQuery() sends a limit only when you give one; the client adds no default and leaves the list size to the server, which is the contract of Wow 9.1.5. What a list or list-stream query without limit gets depends on the server:
| Server | A list query without limit |
|---|---|
| Wow 9.1.5 and later | The server's default list size: 100 unless wow.webflux.query.default-list-size says otherwise |
| Wow 8.11.0 to 9.1.3 | IllegalArgument: HTTP list query limit[0] must be between 1 and 1000.: a list fails with HTTP 400, a list stream answers 200 and ends with that error event. Pass limit explicitly; the WowError of the rejection says so in its message |
Wow 8.10.x, through /legacy | /legacy's listQuery sends limit: 10 unless given another |
An application that has to work against a server older than 9.1.5 passes limit in every listQuery(). CI holds each row to a released server: the smoke test of the 8.11.5, 9.1.3 and 9.1.5 images sends a list and a list stream without limit and expects exactly this. The wow-react hooks take the query as given, so the same holds for useListQuery and useListStreamQuery.
The CI jobs are in typescript-contract.yml; the compatibility code they protect is listed in docs/compat-debt.md.
Runtimes and peers
| Requirement | Version | Notes |
|---|---|---|
| Node.js | >=22.12.0 | Declared in engines of every package; the generator CLI needs it too |
| Browsers | Current evergreen browsers | The packages use fetch, ReadableStream and TextDecoderStream |
React and React DOM (wow-react, wow-view-engine UI) | ^19.0.0 | React 18 is not supported: the build imports react/compiler-runtime. 19.0.0 is smoke-tested as a consumer (type check, server render, client render); CI builds and tests on a current 19.x |
React Router (wow-view-engine/react-router only) | ^7.0.0 || ^8.0.0 | Optional peer: only that entry imports it. 7.0.0 is smoke-tested as a consumer; CI builds and tests on a current 8.x |
| TypeScript | >=6.0 | 6 is the minimum; CI type-checks the packed packages as a consumer on TypeScript 6.0 and the latest 7.x. Generated clients need experimentalDecorators: true; moduleResolution Bundler, NodeNext or Node16 |
@ahoo-wang/fetcher, fetcher-decorator, fetcher-eventstream | ^5.1.5 || ^6.0.0 | Peers: the application installs them. 5.1.5 is the floor: 5.1.4 is the first version whose declarations resolve under require (Node16, NodeNext), and 5.1.5 also type-checks when one program holds both ESM and CJS consumers. Fetcher 6, released on 2026-10-04, is accepted from Wow 9.2.1 (9.2.0 accepts ^5.1.5 only). CI builds and tests on the latest 6.x; a floor job reruns the client, React, generator and view store tests on 5.1.5 and checks the packed packages as a consumer on it |
@ahoo-wang/wow-client (for the other Wow packages) | ~x.y.z | Same minor version |
pnpm 8 and later and npm 7 and later install missing peers by themselves; Yarn does not, so a Yarn project adds each peer explicitly. The install command of each reference page lists them.
What v10 removes
Wow 9.x keeps everything below working; v10 removes all of it in one breaking release:
| Kept through 9.x | Replacement |
|---|---|
| Wow 8.10 and 8.11 servers | Wow 9.x or later |
@ahoo-wang/wow-client/legacy (the Condition API, Operator, the operator locales) and the Condition overloads of the query clients and hooks | FilterExpression and filter.* |
The fetcher-generator command | wow-generator |
Reading fetcher-generator.config.json and .fetcher-generator.json | wow-generator.config.json and .wow-generator.json |
The complete list, with the code that implements each item, is docs/compat-debt.md.