|
| 1 | +# v9 → v10 Migration Guide — Client Construction |
| 2 | + |
| 3 | +> Scope: this guide covers **only** changes to `StreamChat` construction (`new StreamChat(...)` and `StreamChat.getInstance(...)`) and the shape of `StreamChatOptions`. Other v10 changes will be documented separately. |
| 4 | +
|
| 5 | +## TL;DR |
| 6 | + |
| 7 | +- `secret` is gone. The constructor and `getInstance` no longer accept it. **v10 does not support server-side use.** |
| 8 | +- The constructor and `getInstance` are now a single signature: `(key, options?)`. The `(key, secret, options?)` overload has been removed. |
| 9 | +- `StreamChatOptions` no longer extends `AxiosRequestConfig`. Axios-level fields (`timeout`, `httpsAgent`, `withCredentials`, headers, etc.) must now be passed via the dedicated `axiosRequestConfig` property. |
| 10 | +- The same axios defaults (`timeout: 3000`, `withCredentials: false`, keep-alive `httpsAgent` in node) are still applied, but in v10 they can be overridden through `axiosRequestConfig`. In v9 they could not be — `axiosRequestConfig` only affected per-request calls. |
| 11 | +- `paramsSerializer` cannot be overridden. Any `paramsSerializer` passed in `axiosRequestConfig` is ignored; the client always uses its internal `axiosParamsSerializer`. |
| 12 | + |
| 13 | +## Server-side users — stop here |
| 14 | + |
| 15 | +v10 removes all server-side functionality (secret-based auth, server-side JWT signing, etc.). If your integration uses `stream-chat` with a `secret` on a backend, **do not migrate to v10**. Switch to the dedicated server SDK: |
| 16 | + |
| 17 | +- https://github.com/GetStream/stream-node |
| 18 | + |
| 19 | +For client-side / React Native / browser apps that previously called `new StreamChat(key)` without a secret, keep reading. |
| 20 | + |
| 21 | +## Constructor signature |
| 22 | + |
| 23 | +### Removed: the `secret` parameter and its overload |
| 24 | + |
| 25 | +```ts |
| 26 | +// v9 — all of these worked |
| 27 | +new StreamChat(API_KEY); |
| 28 | +new StreamChat(API_KEY, 'a-secret'); |
| 29 | +new StreamChat(API_KEY, { timeout: 5000 }); |
| 30 | +new StreamChat(API_KEY, 'a-secret', { timeout: 5000 }); |
| 31 | +new StreamChat(API_KEY, undefined, { timeout: 5000 }); |
| 32 | +new StreamChat(API_KEY, ''); // empty string was treated as "no secret" |
| 33 | +``` |
| 34 | + |
| 35 | +```ts |
| 36 | +// v10 — only this shape is valid |
| 37 | +new StreamChat(API_KEY); |
| 38 | +new StreamChat(API_KEY, options); |
| 39 | +``` |
| 40 | + |
| 41 | +Same change applies to `StreamChat.getInstance`: |
| 42 | + |
| 43 | +```ts |
| 44 | +// v9 |
| 45 | +StreamChat.getInstance(API_KEY, 'a-secret', { timeout: 5000 }); |
| 46 | + |
| 47 | +// v10 |
| 48 | +StreamChat.getInstance(API_KEY, { axiosRequestConfig: { timeout: 5000 } }); |
| 49 | +``` |
| 50 | + |
| 51 | +### Removed: `client.secret` |
| 52 | + |
| 53 | +The `secret` field on the client instance no longer exists. The internal `_isUsingServerAuth()` method has also been removed; any guard that branched on it should be deleted (the branch was always the server-side path). |
| 54 | + |
| 55 | +## `StreamChatOptions` no longer extends `AxiosRequestConfig` |
| 56 | + |
| 57 | +In v9, `StreamChatOptions = AxiosRequestConfig & { ... }`. That meant you could pass axios fields directly at the top level: |
| 58 | + |
| 59 | +```ts |
| 60 | +// v9 |
| 61 | +new StreamChat(API_KEY, { |
| 62 | + timeout: 5000, |
| 63 | + withCredentials: true, |
| 64 | + httpsAgent: customAgent, |
| 65 | + headers: { 'Cache-Control': 'no-cache' }, |
| 66 | +}); |
| 67 | +``` |
| 68 | + |
| 69 | +In v10, axios fields must go through the dedicated `axiosRequestConfig` property: |
| 70 | + |
| 71 | +```ts |
| 72 | +// v10 |
| 73 | +new StreamChat(API_KEY, { |
| 74 | + axiosRequestConfig: { |
| 75 | + timeout: 5000, |
| 76 | + withCredentials: true, |
| 77 | + httpsAgent: customAgent, |
| 78 | + headers: { 'Cache-Control': 'no-cache' }, |
| 79 | + }, |
| 80 | +}); |
| 81 | +``` |
| 82 | + |
| 83 | +The full mapping for top-level axios fields previously accepted in v9 → `axiosRequestConfig.<same-key>` in v10. |
| 84 | + |
| 85 | +### `axiosRequestConfig` now actually configures the axios instance |
| 86 | + |
| 87 | +In v9, `axiosRequestConfig` was stored on `client.options` but **not** applied to `axios.create` during construction — it was only spread into per-request calls. As a result, defaults like `timeout: 3000` could not be overridden through it. |
| 88 | + |
| 89 | +In v10, `axiosRequestConfig` is spread into the `axios.create` call during construction, so it can override the baked-in defaults: |
| 90 | + |
| 91 | +```ts |
| 92 | +const client = new StreamChat(API_KEY, { |
| 93 | + axiosRequestConfig: { timeout: 9999, withCredentials: true }, |
| 94 | +}); |
| 95 | +client.axiosInstance.defaults.timeout; // 9999 |
| 96 | +client.axiosInstance.defaults.withCredentials; // true |
| 97 | +``` |
| 98 | + |
| 99 | +The defaults (`timeout: 3000`, `withCredentials: false`, keep-alive `https.Agent` in node) still apply when `axiosRequestConfig` does not set them. |
| 100 | + |
| 101 | +### `httpsAgent` location moved |
| 102 | + |
| 103 | +```ts |
| 104 | +// v9 — top-level |
| 105 | +new StreamChat(API_KEY, { browser: false, httpsAgent: customAgent }); |
| 106 | + |
| 107 | +// v10 — under axiosRequestConfig |
| 108 | +new StreamChat(API_KEY, { browser: false, axiosRequestConfig: { httpsAgent: customAgent } }); |
| 109 | +``` |
| 110 | + |
| 111 | +In both versions, node mode (`browser: false` or auto-detected) auto-creates a keep-alive `https.Agent` when none is supplied. Browser mode does not. |
| 112 | + |
| 113 | +### `paramsSerializer` is fixed |
| 114 | + |
| 115 | +Any `paramsSerializer` passed via `axiosRequestConfig` is silently dropped. The client always uses its internal `axiosParamsSerializer`: |
| 116 | + |
| 117 | +```ts |
| 118 | +const client = new StreamChat(API_KEY, { |
| 119 | + axiosRequestConfig: { paramsSerializer: () => 'overridden' }, |
| 120 | +}); |
| 121 | +client.axiosInstance.defaults.paramsSerializer; // === axiosParamsSerializer (NOT the override) |
| 122 | +``` |
| 123 | + |
| 124 | +If you relied on a custom serializer, file an issue — there is no supported way to change this in v10. |
| 125 | + |
| 126 | +## Unchanged behavior worth confirming |
| 127 | + |
| 128 | +These are intentionally listed so agents don't "fix" them during migration: |
| 129 | + |
| 130 | +- `new StreamChat(key)` still works with no options. |
| 131 | +- `StreamChat.getInstance(key)` still returns the same cached instance on repeated calls and ignores the `key`/`options` of subsequent calls. |
| 132 | +- All non-axios options are unchanged: `allowServerSideConnect`, `baseURL`, `browser`, `device`, `disableCache`, `enableInsights`, `enableWSFallback`, `notifications`, `persistUserOnConnectionFailure`, `recoverStateOnReconnect`, `warmUp`, `wsConnection`, `wsUrlParams`. |
| 133 | +- `STREAM_LOCAL_TEST_RUN` / `STREAM_LOCAL_TEST_HOST` env-var overrides on `baseURL` still work the same way. |
| 134 | +- `browser` auto-detection (`typeof window !== 'undefined'`) and the `browser: true | false` override still work the same way. |
| 135 | +- The subsystem managers constructed on the client (`state`, `notifications`, `uploadManager`, `moderation`, `tokenManager`, `threads`, `polls`, `reminders`, `messageDeliveryReporter`, `messageComposerCache`, `insightMetrics`) are identical in v10. |
| 136 | + |
| 137 | +## Mechanical migration recipe |
| 138 | + |
| 139 | +1. If the call site passes a secret, **stop** — migrate that code to `stream-node` instead. |
| 140 | +2. Remove any `secret` argument and any `undefined`/`''` placeholders in the second slot: |
| 141 | + - `new StreamChat(key, undefined, opts)` → `new StreamChat(key, opts)` |
| 142 | + - `new StreamChat(key, '', opts)` → `new StreamChat(key, opts)` |
| 143 | + - `StreamChat.getInstance(key, undefined, opts)` → `StreamChat.getInstance(key, opts)` |
| 144 | +3. For each option key in the `options` object, check whether it's an axios field (`timeout`, `withCredentials`, `httpsAgent`, `headers`, `adapter`, `proxy`, `responseType`, etc. — anything from `AxiosRequestConfig`). If yes, move it under a new `axiosRequestConfig` sub-object. |
| 145 | +4. Remove any reads of `client.secret` and any branches gated on `client._isUsingServerAuth()`. |
| 146 | +5. Drop any custom `paramsSerializer` you were passing — it has no effect in v10. |
0 commit comments