Skip to content

docs: v10 breaking-changes inventory and v9β†’v10 ledger audit - #3870

Merged
isekovanic merged 2 commits into
claude/v10-audit-fixesfrom
claude/sdk-v10-breaking-changes-b84ec2
Oct 19, 2026
Merged

isekovanic merged 2 commits into
claude/v10-audit-fixesfrom
claude/sdk-v10-breaking-changes-b84ec2

Conversation

@oliverlaz

@oliverlaz oliverlaz commented Oct 19, 2026 •

Copy link
Copy Markdown
Member

🎯 Goal

Collect every breaking change between v9 (develop) and v10 (V10) in one place, as the source of truth for the v10 migration guide and the docs update. Also verify the running ledger ai-docs/ai-migration-v9-to-v10.md and measure the impact on the getstream.io React Native docs.

πŸ›  Implementation details

  • ai-docs/v10-breaking-changes.md (new): the full list, grouped by surface: dependencies, removed exports, component props, contexts, hooks, utilities, types, classes and stores, slots and theme, i18n, offline DB, stream-chat v10 changes RN integrators hit, behavioural changes, deep imports and new APIs. Each entry has a one-line migration and links to the ledger section and PR.

  • ai-docs/v10-docs-impact.md (new): per-page impact on getstream.io/content/docs/chat-sdk/react-native/v9-latest. 109 of 302 pages are affected: 6 to delete or replace, 22 major rewrites, 56 snippet or prop-table updates and 25 mentions. It also lists about 12 new pages or sections.

  • ai-docs/ai-migration-v9-to-v10.md: fixes 23 stale or wrong entries. Examples:

    • *WithLocalUpdate β†’ channel.messageOperations.*
    • there is no deactivate(); activate() returns its release function
    • client.activeChannels β†’ client.channelManager
    • queryChannelsOverride should use queryChannelsAndHydrate
    • channel.markRead() vs markReadViaReporter()
    • dbVersion goes 16 β†’ 18
    • connection.changed is no longer dispatched
    • Β§18.4 described a channelManager prop that v9 never had

    Also adds Part R (R.1–R.11) for the gaps the audit found: RN/Expo peer floors, the ChatContext.isOnline removal, the delivery-receipt props, more removed context fields and props, behaviour changes in <Channel>/<Thread>/channel list, stream-chat state and client APIs, the offline DB contract, i18n gaps and deep imports.

  • ai-docs/i18n-v10-migration.md: two corrections. The app-callable formatter keys were not dead in v9, and the date helpers were deep imports in v9.

  • .claude/plans/v10-breaking-changes.md: the audit plan.

How the list was produced:

  1. A TypeScript-compiler snapshot of both public surfaces (about 1,285 exports, with props, context values and class members flattened, plus the referenced stream-chat types), diffed mechanically.
  2. The v9 SampleApp and ExpoMessaging type-checked against V10: 0 errors on v9 and 144 on v10, and every error cluster maps to an entry.
  3. A review of all 40 PRs merged into V10, the examples/ diff, and the deleted or rewritten tests.
  4. A cross-check against the stream-chat and stream-chat-react v10 breaking-change lists.

Stack: #3866 β†’ #3867 β†’ #3868 β†’ #3869 β†’ #3871 β†’ this PR. The known-issue notes for the SDK bugs the audit found are removed here because #3871 fixes them. The inventory covers V10 plus #3866–#3869: the surface diff and the v9 sample-app compile were re-run against the stack tip.

🎨 UI Changes

None (docs only).

πŸ§ͺ Testing

Docs only. yarn lint passes. Every replacement API the new file names was checked against the V10 exports and stream-chat 10.0.0-rc.22.

β˜‘οΈ Checklist

  • I have signed the Stream CLA (required)
  • PR targets the develop branch (targets V10)
  • Documentation is updated
  • New code is tested in main example apps, including all possible scenarios (n/a, docs only)

@oliverlaz
oliverlaz changed the base branch from V10 to claude/v10-audit-fixes October 19, 2026 07:02
@oliverlaz
oliverlaz added this pull request to stack #3872 October 19, 2026 07:06
Add ai-docs/v10-breaking-changes.md, the single list of public API breaks
between develop (v9) and V10, built from a TypeScript surface diff of both
branches, the v9 sample apps type-checked against v10, and a review of all
PRs merged into V10.

Add ai-docs/v10-docs-impact.md, a per-page assessment of the getstream.io
React Native docs (99 of 302 pages affected, new pages needed).

Fix stale guidance in ai-docs/ai-migration-v9-to-v10.md (WithLocalUpdate
methods, deactivate(), client.activeChannels, queryChannels, dbVersion,
channel.markRead semantics, and others) and add Part R covering the gaps
the audit found. Correct two claims in i18n-v10-migration.md.
@oliverlaz
oliverlaz force-pushed the claude/sdk-v10-breaking-changes-b84ec2 branch from fa1e250 to 11d39c3 Compare October 19, 2026 08:17
@oliverlaz
oliverlaz removed this pull request from stack #3872 October 19, 2026 08:20
@oliverlaz
oliverlaz added this pull request to stack #3874 October 19, 2026 08:21
@oliverlaz
oliverlaz removed this pull request from stack #3874 October 19, 2026 08:22
@oliverlaz
oliverlaz added this pull request to stack #3873 October 19, 2026 08:23
The inventory was taken against V10; the stack underneath this PR adds more
public API changes. Re-ran the surface diff and the v9 sample-app compile
against the stack tip (refactor/stop-creating-sdk-paginator) and covered them:

- v10-breaking-changes.md: standalone <Thread> next to <Channel> (removed
  Channel thread/threadList/allowThreadMessagesInChannel/shouldSyncChannel,
  Thread props, threadList everywhere, ThreadMessageComposer slot,
  ThreadContext shape, onAlsoSentToChannelHeaderPress move), message actions
  built on demand (argument-less useMessageActions/useMessageActionHandlers,
  removed Message handleX/messageActions/supportedReactions), and the
  app-owned <ChannelList paginator> (removed filters/sort/options/
  lockChannelOrder/queryChannelsOverride).
- ai-migration-v9-to-v10.md: correct the removed Thread prop names
  (additionalMessageComposerProps, additionalMessageFlashListProps), add
  shouldSyncChannel, and move R.6 and its quick-reference rows onto the
  ChannelPaginator.
- v10-docs-impact.md: re-scan the docs for the stack's changes (109 pages
  affected, was 99).
@isekovanic
isekovanic merged commit b4924cd into V10 Oct 19, 2026
2 checks passed
@isekovanic
isekovanic deleted the claude/sdk-v10-breaking-changes-b84ec2 branch October 19, 2026 09:53
isekovanic pushed a commit that referenced this pull request Oct 19, 2026
…useCreateChatClient (#3871)

## 🎯 Goal

Fix the SDK-side problems the v10 public-API audit found (listed in
`ai-docs/v10-breaking-changes.md` Β§16 in #3870), so they ship fixed
instead of documented as limitations.

The docs PR #3870 already drops these known-issue notes from
`ai-docs/v10-breaking-changes.md` and
`ai-docs/ai-migration-v9-to-v10.md` (Β§13.1, Β§16.1, Β§R.5), so it assumes
this PR lands first or together with it. This PR is code only.

**Stacked on #3869** (Ivan's stack: #3866 β†’ #3867 β†’ #3868 β†’ #3869). The
branch is rebased onto `refactor/stop-creating-sdk-paginator`; until the
PR base is moved there, the diff also shows that stack's commits.

## πŸ›  Implementation details

- **`<Channel>` overrode a registered page size.** On every mount it ran
`channel.messagePaginator.pageSize = 25` (now in `useChannelLifecycle`,
after #3868). That setter is a runtime `updateConfig` patch, which
outranks every declarative layer, so a `client.config.set({ channel: {
messagePaginator: { pageSize } } })` registration (the migration guide's
advice) never took effect. `useChannelLifecycle` now applies the
25-message default only when no `pageSize` is registered under
`channel.messagePaginator` or the general `messagePaginator` key, the
two places the paginator resolves it from.
- **`useCreateChatClient({ userData })` rejected `{ id, name, image
}`.** It was typed `OwnUserResponse | UserResponse`, which require
server-owned fields (`role`, `created_at`, …) in stream-chat v10. It is
now `ClientUser`, exactly what `client.connectUser` accepts. The `as
UserResponse` casts in ExpoChatGPTSample and ExpoMessaging are gone
(ExpoMessaging keeps `as ClientUser` only to narrow away `null`).
- **`AGENTS.md`** said the main entry must never reach
`@stream-io/state-store`, but the `state-store/` stores and Poll
contexts import it at runtime. The rule now matches
`package/bin/validate-entry-isolation.js` (`@stream-io/state-store` and
`lodash` are shared; only `react-syntax-highlighter`,
`@khanacademy/simple-markdown`, `zod`, `victory-native` and Skia are
AI-only), and the script path is corrected.

## 🎨 UI Changes

None.

## πŸ§ͺ Testing

- `Channel.test.tsx` (still passes on the rebased base) β†’ "message page
size": default 25 with nothing registered, and a registered
`channel.messagePaginator.pageSize` / `messagePaginator.pageSize` is
kept after mount. The two registration cases fail with the guard
removed.
- New `useCreateChatClient.userData.test.ts`: a type-level assertion
that the hook's `userData` and `connectUser`'s parameter are mutually
assignable (it fails `test:typecheck` under the old typing), plus a
runtime check that a `{ id, name, image }` user is passed to
`connectUser`.
- After the rebase onto #3869: `yarn lint`, `cd package && yarn
test:typecheck`, and the `Channel` and `useCreateChatClient` suites
pass. Before the rebase, locally green: `yarn build`, `yarn lint`, `cd
package && yarn test:typecheck`, `yarn typecheck` (covers the example
apps without the casts), `yarn test:unit` (2200 passed).

## β˜‘οΈ Checklist

- [ ] I have signed the [Stream
CLA](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform)
(required)
- [ ] PR targets the `develop` branch (targets `V10`: v10 release fix)
- [x] Documentation is updated (`AGENTS.md`; migration docs in #3870)
- [ ] New code is tested in main example apps, including all possible
scenarios
  - [ ] SampleApp iOS and Android
  - [ ] Expo iOS and Android
isekovanic pushed a commit that referenced this pull request Oct 28, 2026
## 🎯 Goal

E2E test automation for the SDK, on par with the native iOS/Android and
Flutter suites, running on PRs.

Linear: [RN-450](https://linear.app/stream/issue/RN-450),
[RN-451](https://linear.app/stream/issue/RN-451),
[RN-452](https://linear.app/stream/issue/RN-452),
[RN-453](https://linear.app/stream/issue/RN-453),
[RN-454](https://linear.app/stream/issue/RN-454),
[RN-455](https://linear.app/stream/issue/RN-455),
[RN-457](https://linear.app/stream/issue/RN-457) (parent
[RN-449](https://linear.app/stream/issue/RN-449))

## πŸ›  Implementation details

**Dedicated app: `examples/E2ETestApp`.** A new bare RN 0.88 workspace
with only the SDK and its required peer dependencies (no Firebase, maps,
video or navigation library), like the native SDKs'
`StreamChatUITestsApp`. It has three screens: a user selector, the
channel list, and a channel stacked over the list. It reads a
`MOCK_SERVER_URL` launch argument (`react-native-launch-arguments`),
never persists a login and runs without offline storage, so every test
starts clean. A clean Release build takes ~2 min on an M-series Mac; the
SampleApp took ~15 min on Android. **The SampleApp app is unchanged**;
only its Fastfile gains the e2e lanes.

**Framework ([RN-450](https://linear.app/stream/issue/RN-450)):** Detox
20 + Jest 30 in `examples/E2ETestApp/e2e/`, with `ios.sim.*`,
`android.emu.*` and `android.att.*` configs (debug and release).

**Mock server ([RN-451](https://linear.app/stream/issue/RN-451)):** the
shared
[`stream-chat-test-mock-server`](https://github.com/GetStream/stream-chat-test-mock-server),
one server per test through its driver (port 4569).

**Page objects ([RN-452](https://linear.app/stream/issue/RN-452)) and
robots ([RN-453](https://linear.app/stream/issue/RN-453),
[RN-454](https://linear.app/stream/issue/RN-454),
[RN-455](https://linear.app/stream/issue/RN-455)):** structure and
naming follow the native suites:

- `BackendRobot` / `ParticipantRobot`: 1:1 ports of the Android robots
- `UserRobot` + `UserRobot*Asserts`: assert extensions, like Android's
- `LoginPage` / `ChannelListPage` / `MessageListPage`
- `setUpStreamTestCase()`, `step()`, and uiautomator-style element
helpers

Robots chain fluently like the native ones: `await
userRobot.login().openChannel().assertMessage('Hi')`.

**Smoke suite:** 6 tests (MessageList Γ—3, ChannelList Γ—3), named after
their Android counterparts and keeping the native expectations.

**SDK (additive testIDs only):** `channel-preview-title`,
`channel-preview-message`, `channel-preview-sender`, and
`message-status-{read,delivered,sending,sent}`, with a unit test.

**CI ([RN-457](https://linear.app/stream/issue/RN-457)):**
`.github/workflows/e2e-test.yml`.

- **Android** runs on PRs: `ubuntu-latest`, KVM, API 36 AOSP emulator,
`pixel` profile (the native Android SDK's setup).
- **iOS** runs only on demand (`workflow_dispatch` with `ios: true`),
not on PRs, to save CI time and macOS runners: `macos-15`, Xcode 26.2,
iPhone 17 Pro.
- Gated like the iOS SDK: a cheap `Check E2E Required` job runs
`is_check_required` over the e2e sources (Fastfile `impact_analysis`),
and `test_e2e` checks it too.
- **`Test E2E Result` is the check to require in branch protection.** It
covers Android (it doesn't wait for iOS) and passes when the Android job
passes or is skipped as not required.
- Caching:
- the built `.app` / `.apk`, keyed on the app and SDK sources but not on
`e2e/`, so a test-only change skips the native build
  - `node_modules` of `yarn workspaces focus e2etestapp`
- CocoaPods, ccache (with `CCACHE_BINARY` exported, without which RN's
ccache wrappers silently skip ccache), the Detox framework, Gradle
(`cache-read-only: false`, since `setup-gradle` otherwise only writes on
the default branch), and the mock server's gems
- each PR fills its own caches (the workflow doesn't run on `develop`):
its first run builds cold, and later pushes reuse them
- On failure, uploads the mock server logs, Detox's logs and
screenshots, and the emulator's crash data.

**Fastlane** (in `examples/SampleApp/fastlane`, next to the repo's other
lanes): `start_mock_server`, `stop_mock_server`, `e2e_pod_install`,
`test_e2e`, `e2e_check_required`.

**Notable findings**, documented in `examples/E2ETestApp/e2e/README.md`:

- Fabric mounts some testID'd views (`message-list-item-*`,
`message-text-container`) empty, with their content as siblings, so page
objects scope to `message-content-wrapper` or the list instead.
- iOS runs without Detox's idle synchronization, which can wedge on RN's
UIManager shadow queue. Robots wait explicitly, and taps retry while the
target isn't hittable yet.
- `launchApp({ permissions })` makes Detox restart SpringBoard once per
permission on every launch. On CI that cost 1.5–3 min per test, so the
suite doesn't pass any.
- Android sets the composer text directly (as the native suite does).
Typing through Gboard left the text in a composing state that the
composer didn't send.

How to run and extend the suite: `examples/E2ETestApp/e2e/README.md`.

## 🎨 UI Changes

None (testIDs only).

## πŸ§ͺ Testing

- Locally (release builds): iOS simulator 6/6, 31s for the whole suite;
Android emulator 6/6.
- CI: green on
[39459700744](https://github.com/GetStream/stream-chat-react-native/actions/runs/39459700744)
and
[39467760315](https://github.com/GetStream/stream-chat-react-native/actions/runs/39467760315).
On the latter the iOS test step took 3m 12s (31 min before the
launch-permission fix), and Android 3m 12s.
- `e2e_check_required` against real PRs: no PR β†’ `true`, #3870 (docs
only) β†’ `false`, #3879 (`package/`) β†’ `true`.
- `yarn build`, `yarn lint`, `yarn typecheck` (now including
`e2etestapp`), `cd package && yarn test:typecheck`, `yarn test:unit`
green.

Not covered yet: Allure TestOps reporting, full suite ports, and iOS on
PRs (manual runs only, to save CI time and macOS runners).

## β˜‘οΈ Checklist

- [ ] I have signed the [Stream
CLA](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform)
(required)
- [x] PR targets the `develop` branch
- [x] Documentation is updated
- [ ] New code is tested in main example apps, including all possible
scenarios
  - [ ] SampleApp iOS and Android
  - [ ] Expo iOS and Android
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants