Skip to content

Conversation

fulopkovacs
Copy link

@fulopkovacs fulopkovacs commented Oct 4, 2025

Turns out typed Readable Streams are in high demand thanks to AI apps (I actually use them myself with TanStack Start), but we didn't have any examples for it yet, so I added one.

I'm happy to update the docs too, but not sure where.

Summary by CodeRabbit

  • New Features

    • Added a runnable React example showcasing typed streaming responses with a Start Streaming button and live text output.
    • Includes basic navigation (Index, About) and integrated router devtools.
    • Provides default error and “not found” pages and scroll restoration.
  • Style

    • Introduced simple global styles for body, links, and layout.
  • Chores

    • Set up project scaffolding with scripts (dev, build, start), dependencies, TypeScript config, and Vite config (dev server on port 3000).

Copy link

nx-cloud bot commented Oct 4, 2025

View your CI Pipeline Execution ↗ for commit 5d18df4

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 47s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 3s View ↗

☁️ Nx Cloud last updated this comment at 2025-10-04 18:00:49 UTC

Copy link
Contributor

coderabbitai bot commented Oct 4, 2025

Warning

Rate limit exceeded

@fulopkovacs has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 21 minutes and 21 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 31c2a5d and 5d18df4.

⛔ Files ignored due to path filters (2)
  • examples/react/start-typed-readable-stream/public/favicon.ico is excluded by !**/*.ico
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (8)
  • examples/react/start-typed-readable-stream/package.json (1 hunks)
  • examples/react/start-typed-readable-stream/src/routeTree.gen.ts (1 hunks)
  • examples/react/start-typed-readable-stream/src/router.tsx (1 hunks)
  • examples/react/start-typed-readable-stream/src/routes/__root.tsx (1 hunks)
  • examples/react/start-typed-readable-stream/src/routes/index.tsx (1 hunks)
  • examples/react/start-typed-readable-stream/src/styles/app.css (1 hunks)
  • examples/react/start-typed-readable-stream/tsconfig.json (1 hunks)
  • examples/react/start-typed-readable-stream/vite.config.ts (1 hunks)

Walkthrough

Adds a new React + TanStack Start example app showcasing a typed ReadableStream. Introduces project scaffolding (package, TypeScript, Vite), generated file-based route tree, a router factory, root route/layout, a streaming index route with zod-typed chunks, basic styles, and Vite config.

Changes

Cohort / File(s) Summary of changes
Example app scaffolding & config
examples/react/start-typed-readable-stream/package.json, examples/react/start-typed-readable-stream/tsconfig.json, examples/react/start-typed-readable-stream/vite.config.ts
Adds package manifest, strict TS config with path alias, and Vite setup (port 3000) with React, TanStack Start, and tsconfig paths plugins.
Generated route tree
examples/react/start-typed-readable-stream/src/routeTree.gen.ts
Introduces generated file-based route types, mappings, and routeTree export; augments TanStack Router/Start module types for SSR and router registration.
Router factory
examples/react/start-typed-readable-stream/src/router.tsx
Adds getRouter() using createRouter with routeTree, default preload/error/not-found components, and scroll restoration; augments @tanstack/react-router types.
Routes and app shell
examples/react/start-typed-readable-stream/src/routes/__root.tsx
Adds root route with document shell, navigation, devtools, and Outlet.
Typed streaming example route
examples/react/start-typed-readable-stream/src/routes/index.tsx
Adds zod schema/type for stream chunks, server streamingResponseFn emitting typed chunks, and a component consuming the stream and rendering accumulated text; exports route.
Styles
examples/react/start-typed-readable-stream/src/styles/app.css
Adds base fonts and simple layout styles for body, links, and main.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User
  participant C as Client UI (Index Route)
  participant S as Server (streamingResponseFn)

  U->>C: Click "Start streaming"
  C->>S: GET /stream (invoke streamingResponseFn)
  activate S
  note right of S: Create ReadableStream<TextPart><br/>Enqueue 10 typed chunks<br/>~500ms between chunks
  S-->>C: Response with ReadableStream<TextPart>
  deactivate S

  activate C
  loop While not done
    C->>C: reader.read()<br/>validate chunk (has delta.content)
    C->>C: Append content to state
    note over C: UI re-renders with accumulated text
  end
  deactivate C

  note over U,C: User sees streaming text appear incrementally
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

documentation

Suggested reviewers

  • birkskyum
  • schiller-manuel

Poem

A rabbit taps Vite at port three-oh-oh-oh,
Streams of text hop in, chunk by chunk, slow.
Zod checks the nibble, React renders the chew,
Router maps the burrow, routes crisp and new.
With every delta, my whiskers gleam—
Typed bytes bloom into a readable stream. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly describes the primary change of adding a new example for typed readable streams within the examples directory, accurately reflecting the content of the pull request without unnecessary detail or noise.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0d3bba8 and 31c2a5d.

⛔ Files ignored due to path filters (1)
  • examples/react/start-typed-readable-stream/public/favicon.ico is excluded by !**/*.ico
📒 Files selected for processing (8)
  • examples/react/start-typed-readable-stream/package.json (1 hunks)
  • examples/react/start-typed-readable-stream/src/routeTree.gen.ts (1 hunks)
  • examples/react/start-typed-readable-stream/src/router.tsx (1 hunks)
  • examples/react/start-typed-readable-stream/src/routes/__root.tsx (1 hunks)
  • examples/react/start-typed-readable-stream/src/routes/index.tsx (1 hunks)
  • examples/react/start-typed-readable-stream/src/styles/app.css (1 hunks)
  • examples/react/start-typed-readable-stream/tsconfig.json (1 hunks)
  • examples/react/start-typed-readable-stream/vite.config.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
examples/{react,solid}/**

📄 CodeRabbit inference engine (AGENTS.md)

Keep example applications under examples/react/ and examples/solid/

Files:

  • examples/react/start-typed-readable-stream/tsconfig.json
  • examples/react/start-typed-readable-stream/src/routes/__root.tsx
  • examples/react/start-typed-readable-stream/vite.config.ts
  • examples/react/start-typed-readable-stream/src/routes/index.tsx
  • examples/react/start-typed-readable-stream/src/routeTree.gen.ts
  • examples/react/start-typed-readable-stream/package.json
  • examples/react/start-typed-readable-stream/src/styles/app.css
  • examples/react/start-typed-readable-stream/src/router.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with extensive type safety across the codebase

Files:

  • examples/react/start-typed-readable-stream/src/routes/__root.tsx
  • examples/react/start-typed-readable-stream/vite.config.ts
  • examples/react/start-typed-readable-stream/src/routes/index.tsx
  • examples/react/start-typed-readable-stream/src/routeTree.gen.ts
  • examples/react/start-typed-readable-stream/src/router.tsx
**/src/routes/**

📄 CodeRabbit inference engine (AGENTS.md)

Place file-based routes under src/routes/ directories

Files:

  • examples/react/start-typed-readable-stream/src/routes/__root.tsx
  • examples/react/start-typed-readable-stream/src/routes/index.tsx
**/package.json

📄 CodeRabbit inference engine (AGENTS.md)

Use workspace:* protocol for internal dependencies in package.json files

Files:

  • examples/react/start-typed-readable-stream/package.json
🧠 Learnings (2)
📚 Learning: 2025-09-23T17:36:12.598Z
Learnt from: CR
PR: TanStack/router#0
File: AGENTS.md:0-0
Timestamp: 2025-09-23T17:36:12.598Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript in strict mode with extensive type safety across the codebase

Applied to files:

  • examples/react/start-typed-readable-stream/tsconfig.json
📚 Learning: 2025-10-01T18:31:35.420Z
Learnt from: schiller-manuel
PR: TanStack/router#5330
File: e2e/react-start/custom-basepath/src/routeTree.gen.ts:58-61
Timestamp: 2025-10-01T18:31:35.420Z
Learning: Do not review files named `routeTree.gen.ts` in TanStack Router repositories, as these are autogenerated files that should not be manually modified.

Applied to files:

  • examples/react/start-typed-readable-stream/src/routeTree.gen.ts
🧬 Code graph analysis (3)
examples/react/start-typed-readable-stream/src/routes/__root.tsx (2)
examples/react/start-typed-readable-stream/src/routes/index.tsx (1)
  • Route (60-62)
packages/react-router-devtools/src/TanStackRouterDevtools.tsx (1)
  • TanStackRouterDevtools (46-126)
examples/react/start-typed-readable-stream/src/routes/index.tsx (1)
examples/react/start-typed-readable-stream/src/routes/__root.tsx (1)
  • Route (13-18)
examples/react/start-typed-readable-stream/src/routeTree.gen.ts (2)
e2e/react-router/js-only-file-based/src/routeTree.gen.js (2)
  • IndexRoute (30-34)
  • rootRouteChildren (90-94)
examples/react/start-typed-readable-stream/src/router.tsx (1)
  • getRouter (4-14)
🔇 Additional comments (2)
examples/react/start-typed-readable-stream/tsconfig.json (1)

1-22: LGTM!

The TypeScript configuration correctly enables strict mode with extensive type safety, aligning with the project's coding standards. The modern settings (ESNext, Bundler resolution, ES2022 target) are appropriate for this Vite-based React example.

Based on learnings.

examples/react/start-typed-readable-stream/src/routes/index.tsx (1)

64-100: LGTM!

The client-side streaming implementation correctly demonstrates typed ReadableStream usage. The code properly handles the stream reader, maintains type safety (lines 81-83), and updates the UI incrementally as chunks arrive.

Comment on lines +46 to +54
const stream = new ReadableStream<TextPart>({
async start(controller) {
for (const message of messages) {
await sleep(500)
controller.enqueue(message)
}
sleep(500)
controller.close()
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Missing await before final sleep call.

Line 52 calls sleep(500) without await, causing the stream to close immediately instead of waiting 500ms after the last message. This can result in the last chunk being dropped or incomplete.

Apply this diff to fix the missing await:

       for (const message of messages) {
         await sleep(500)
         controller.enqueue(message)
       }
-      sleep(500)
+      await sleep(500)
       controller.close()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const stream = new ReadableStream<TextPart>({
async start(controller) {
for (const message of messages) {
await sleep(500)
controller.enqueue(message)
}
sleep(500)
controller.close()
},
const stream = new ReadableStream<TextPart>({
async start(controller) {
for (const message of messages) {
await sleep(500)
controller.enqueue(message)
}
await sleep(500)
controller.close()
},
🤖 Prompt for AI Agents
In examples/react/start-typed-readable-stream/src/routes/index.tsx around lines
46 to 54, the final sleep(500) call is not awaited so controller.close() runs
immediately; change the code to await the final sleep before calling
controller.close() so the stream waits 500ms after the last message is enqueued
and the last chunk is not dropped.

@fulopkovacs fulopkovacs force-pushed the add-typed-readable-stream-example branch 2 times, most recently from b423956 to f80fc07 Compare October 4, 2025 17:57
@fulopkovacs fulopkovacs force-pushed the add-typed-readable-stream-example branch from f80fc07 to 5d18df4 Compare October 4, 2025 17:58
Copy link

pkg-pr-new bot commented Oct 4, 2025

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/arktype-adapter@5363

@tanstack/directive-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/directive-functions-plugin@5363

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/eslint-plugin-router@5363

@tanstack/history

npm i https://pkg.pr.new/TanStack/router/@tanstack/history@5363

@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/nitro-v2-vite-plugin@5363

@tanstack/react-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router@5363

@tanstack/react-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-devtools@5363

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-ssr-query@5363

@tanstack/react-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start@5363

@tanstack/react-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-client@5363

@tanstack/react-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-server@5363

@tanstack/router-cli

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-cli@5363

@tanstack/router-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-core@5363

@tanstack/router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools@5363

@tanstack/router-devtools-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools-core@5363

@tanstack/router-generator

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-generator@5363

@tanstack/router-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-plugin@5363

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-ssr-query-core@5363

@tanstack/router-utils

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-utils@5363

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-vite-plugin@5363

@tanstack/server-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/server-functions-plugin@5363

@tanstack/solid-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router@5363

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-devtools@5363

@tanstack/solid-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start@5363

@tanstack/solid-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-client@5363

@tanstack/solid-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-server@5363

@tanstack/start-client-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-client-core@5363

@tanstack/start-plugin-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-plugin-core@5363

@tanstack/start-server-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-core@5363

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-static-server-functions@5363

@tanstack/start-storage-context

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-storage-context@5363

@tanstack/valibot-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/valibot-adapter@5363

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/TanStack/router/@tanstack/virtual-file-routes@5363

@tanstack/zod-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/zod-adapter@5363

commit: 5d18df4

@schiller-manuel
Copy link
Contributor

thanks, we are also looking into async generator functions to make this even easier. so let's wait with this example, then we can showcase all of the possibilities

@fulopkovacs
Copy link
Author

fulopkovacs commented Oct 4, 2025

thanks, we are also looking into async generator functions to make this even easier. so let's wait with this example, then we can showcase all of the possibilities

Awesome! Async generator functions sound like a good solution for this problem, can't wait to see them in action.

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