Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
b961381
feat: add start devtools
AlemTuzlak Sep 25, 2025
2599dc3
Update packages/solid-start-devtools/package.json
AlemTuzlak Sep 26, 2025
7c3ad0c
Update packages/start-devtools/package.json
AlemTuzlak Sep 26, 2025
31f11bb
Update packages/react-start-devtools/package.json
AlemTuzlak Sep 26, 2025
50bbb01
fix small issues
AlemTuzlak Sep 26, 2025
ebb82f0
Merge branch 'feat/devtools' of https://github.com/AlemTuzlak/router …
AlemTuzlak Sep 26, 2025
dac6459
add initial request interceptor util for devtools
AlemTuzlak Sep 26, 2025
c14f481
Merge branch 'main' into feat/devtools
AlemTuzlak Mar 11, 2026
dbbc347
feat(start-devtools): rewrite StartEventMap with 12 event types for f…
AlemTuzlak Mar 12, 2026
41a3c0a
feat(start-devtools): add requestId, requestStartTime, eventClient to…
AlemTuzlak Mar 12, 2026
00b3249
feat(start-devtools): add instrumentMiddlewareArray helper with tests
AlemTuzlak Mar 12, 2026
49a4701
feat(start-devtools): instrument createStartHandler with full request…
AlemTuzlak Mar 12, 2026
9c67928
feat(start-devtools): add server function lifecycle, serialization, a…
AlemTuzlak Mar 12, 2026
70b3813
feat(start-devtools): add cross-package middleware-executed event for…
AlemTuzlak Mar 12, 2026
e271c73
feat(start-devtools): add reactive request store with event processin…
AlemTuzlak Mar 12, 2026
3d39223
feat(start-devtools): add UI components - WaterfallBar, FilterBar, Re…
AlemTuzlak Mar 12, 2026
ed3c052
feat(start-devtools): rewrite panel with waterfall timeline, filters,…
AlemTuzlak Mar 12, 2026
866759a
chore: format
AlemTuzlak Mar 12, 2026
1f09649
fix(start-devtools): address code review findings
AlemTuzlak Mar 12, 2026
8462118
feat(start-devtools): Chrome DevTools-style network panel redesign
AlemTuzlak Mar 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion examples/react/start-basic-react-query/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@
"start": "pnpx srvx --prod -s ../client dist/server/server.js"
},
"dependencies": {
"@tanstack/devtools-vite": "^0.3.3",
"@tanstack/react-devtools": "^0.7.0",
"@tanstack/react-query": "^5.90.0",
"@tanstack/react-query-devtools": "^5.90.0",
"@tanstack/react-router": "^1.166.7",
"@tanstack/react-router-devtools": "^1.166.7",
"@tanstack/react-router-ssr-query": "^1.166.7",
"@tanstack/react-start": "^1.166.7",
"@tanstack/react-start-devtools": "0.0.1",
Comment thread
coderabbitai[bot] marked this conversation as resolved.
"react": "^19.0.0",
"react-dom": "^19.0.0",
"redaxios": "^0.5.1",
Expand All @@ -32,4 +35,4 @@
"vite": "^7.3.1",
"vite-tsconfig-paths": "^5.1.4"
}
}
}
25 changes: 21 additions & 4 deletions examples/react/start-basic-react-query/src/routes/__root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import {
Scripts,
createRootRouteWithContext,
} from '@tanstack/react-router'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
import { ReactQueryDevtoolsPanel } from '@tanstack/react-query-devtools'
import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools'
import * as React from 'react'
import { TanStackDevtools } from '@tanstack/react-devtools'
import { StartDevtoolsPanel } from '@tanstack/react-start-devtools'
import type { QueryClient } from '@tanstack/react-query'
import { DefaultCatchBoundary } from '~/components/DefaultCatchBoundary'
import { NotFound } from '~/components/NotFound'
Expand Down Expand Up @@ -136,8 +138,23 @@ function RootDocument({ children }: { children: React.ReactNode }) {
</div>
<hr />
{children}
<TanStackRouterDevtools position="bottom-right" />
<ReactQueryDevtools buttonPosition="bottom-left" />
<TanStackDevtools eventBusConfig={{
connectToServerBus: true
}} plugins={[
{
name: 'React Query',
render: () => <ReactQueryDevtoolsPanel />
},
{
name: 'React Router',
render: () => <TanStackRouterDevtoolsPanel />
},
{
name: "TanStack Start",
render: () => <StartDevtoolsPanel />
}
]} />

<Scripts />
</body>
</html>
Expand Down
2 changes: 2 additions & 0 deletions examples/react/start-basic-react-query/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ import { tanstackStart } from '@tanstack/react-start/plugin/vite'
import { defineConfig } from 'vite'
import tsConfigPaths from 'vite-tsconfig-paths'
import viteReact from '@vitejs/plugin-react'
import { devtools } from '@tanstack/devtools-vite'
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
server: {
port: 3000,
},
plugins: [
devtools(),
tailwindcss(),
tsConfigPaths({
projects: ['./tsconfig.json'],
Expand Down
52 changes: 52 additions & 0 deletions examples/react/start-devtools-showcase/src/start.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { createStart, createMiddleware } from '@tanstack/react-start'

export const requestLoggingMiddleware = createMiddleware().server(
async ({ next, pathname }) => {
const start = performance.now()
console.log(`[request] → ${pathname}`)

const result = await next({
context: {
requestStartTime: start,
requestPathname: pathname,
},
})

const duration = performance.now() - start
console.log(`[request] ← ${pathname} (${duration.toFixed(1)}ms)`)

return result
},
)

export const rateLimitMiddleware = createMiddleware().server(
async ({ next }) => {
return next({
context: {
rateLimited: false,
},
})
},
)

export const globalFunctionMiddleware = createMiddleware({
type: 'function',
}).server(async ({ next }) => {
const start = performance.now()

const result = await next({
context: {
globalFnMiddlewareApplied: true,
},
})

const duration = performance.now() - start
console.log(`[global-fn-middleware] executed in ${duration.toFixed(1)}ms`)

return result
})

export const startInstance = createStart(() => ({
requestMiddleware: [requestLoggingMiddleware, rateLimitMiddleware],
functionMiddleware: [globalFunctionMiddleware],
}))
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@
"@tanstack/vue-start-client": "workspace:*",
"@tanstack/vue-start-server": "workspace:*",
"@tanstack/start-plugin-core": "workspace:*",
"@tanstack/start-devtools": "workspace:*",
"@tanstack/react-start-devtools": "workspace:*",
"@tanstack/solid-start-devtools": "workspace:*",
"@tanstack/start-client-core": "workspace:*",
"@tanstack/start-server-core": "workspace:*",
"@tanstack/start-storage-context": "workspace:*",
Expand All @@ -135,4 +138,4 @@
"@tanstack/nitro-v2-vite-plugin": "workspace:*"
}
}
}
}
32 changes: 32 additions & 0 deletions packages/react-start-devtools/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// @ts-check

import pluginReact from '@eslint-react/eslint-plugin'
import pluginReactCompiler from 'eslint-plugin-react-compiler'
import pluginReactHooks from 'eslint-plugin-react-hooks'
import rootConfig from '../../eslint.config.js'

export default [
...rootConfig,
{
files: ['**/*.{ts,tsx}'],
...pluginReact.configs.recommended,
},
{
plugins: {
'react-hooks': pluginReactHooks,
'react-compiler': pluginReactCompiler,
},
rules: {
'@eslint-react/dom/no-missing-button-type': 'off',
'react-compiler/react-compiler': 'error',
'react-hooks/exhaustive-deps': 'error',
'react-hooks/rules-of-hooks': 'error',
},
},
{
files: ['**/__tests__/**'],
rules: {
// 'react-compiler/react-compiler': 'off',
},
},
]
70 changes: 70 additions & 0 deletions packages/react-start-devtools/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"name": "@tanstack/react-start-devtools",
"version": "0.0.1",
"description": "React adapter for devtools for Start.",
"author": "Tanner Linsley",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/TanStack/router.git",
"directory": "packages/react-start-devtools"
},
Comment thread
AlemTuzlak marked this conversation as resolved.
"homepage": "https://tanstack.com/start",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
},
"keywords": [],
"type": "module",
"types": "dist/esm/index.d.ts",
"module": "dist/esm/index.js",
"exports": {
".": {
"import": {
"types": "./dist/esm/index.d.ts",
"default": "./dist/esm/index.js"
}
},
"./production": {
"import": {
"types": "./dist/esm/production.d.ts",
"default": "./dist/esm/production.js"
}
},
"./package.json": "./package.json"
},
"sideEffects": false,
"engines": {
"node": ">=18"
},
"files": [
"dist/",
"src"
],
"scripts": {
"clean": "rimraf ./build ./dist",
"lint:fix": "eslint ./src --fix",
"test:eslint": "eslint ./src",
"test:lib": "vitest",
"test:lib:dev": "pnpm test:lib --watch",
"test:types": "tsc",
"test:build": "publint --strict",
"build": "vite build"
},
"peerDependencies": {
"@types/react": ">=16.8",
"@types/react-dom": ">=16.8",
"react": ">=16.8",
"react-dom": ">=16.8"
},
"dependencies": {
"@tanstack/devtools-utils": "^0.0.3",
"@tanstack/start-devtools": "workspace:*"
},
"devDependencies": {
"@eslint-react/eslint-plugin": "^1.53.1",
"@vitejs/plugin-react": "^5.0.2",
"eslint-plugin-react-compiler": "19.1.0-rc.2",
"eslint-plugin-react-hooks": "^5.2.0"
}
}
10 changes: 10 additions & 0 deletions packages/react-start-devtools/src/ReactStartDevtools.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

import { createReactPanel } from '@tanstack/devtools-utils/react'
import { StartDevtoolsCore } from "@tanstack/start-devtools"
import type { DevtoolsPanelProps } from '@tanstack/devtools-utils/react';

export interface StartDevtoolsReactInit extends DevtoolsPanelProps { }

const [StartDevtoolsPanel, StartDevtoolsPanelNoOp] = createReactPanel(StartDevtoolsCore)

export { StartDevtoolsPanel, StartDevtoolsPanelNoOp }
16 changes: 16 additions & 0 deletions packages/react-start-devtools/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use client'

import * as Devtools from './ReactStartDevtools'
import * as plugin from './plugin'

export const StartDevtoolsPanel =
process.env.NODE_ENV !== 'development'
? Devtools.StartDevtoolsPanelNoOp
: Devtools.StartDevtoolsPanel

export const startDevtoolsPlugin =
process.env.NODE_ENV !== 'development'
? plugin.startDevtoolsNoOpPlugin
: plugin.startDevtoolsPlugin

export type { StartDevtoolsReactInit } from './ReactStartDevtools'
6 changes: 6 additions & 0 deletions packages/react-start-devtools/src/plugin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { createReactPlugin } from '@tanstack/devtools-utils/react'
import { StartDevtoolsPanel } from './ReactStartDevtools'

const [startDevtoolsPlugin, startDevtoolsNoOpPlugin] = createReactPlugin("TanStack Start", StartDevtoolsPanel)

export { startDevtoolsPlugin, startDevtoolsNoOpPlugin }
7 changes: 7 additions & 0 deletions packages/react-start-devtools/src/production.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use client'

export { StartDevtoolsPanel } from './ReactStartDevtools'

export type { StartDevtoolsReactInit } from './ReactStartDevtools'

export { startDevtoolsPlugin } from './plugin'
7 changes: 7 additions & 0 deletions packages/react-start-devtools/tests/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { describe, expect, it } from 'vitest'

describe('test suite', () => {
it('should work', () => {
expect(true).toBe(true)
})
})
1 change: 1 addition & 0 deletions packages/react-start-devtools/tests/test-setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '@testing-library/jest-dom/vitest'
4 changes: 4 additions & 0 deletions packages/react-start-devtools/tsconfig.docs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "./tsconfig.json",
"include": ["tests", "src"]
}
7 changes: 7 additions & 0 deletions packages/react-start-devtools/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.json",
"include": ["src", "eslint.config.js", "vite.config.ts", "tests"],
"compilerOptions": {
"jsx": "react"
}
}
25 changes: 25 additions & 0 deletions packages/react-start-devtools/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { defineConfig, mergeConfig } from 'vitest/config'
import { tanstackViteConfig } from '@tanstack/config/vite'
import react from '@vitejs/plugin-react'
import packageJson from './package.json'

const config = defineConfig({
plugins: [react()],
test: {
name: packageJson.name,
dir: './',
watch: false,
environment: 'jsdom',
setupFiles: ['./tests/test-setup.ts'],
globals: true,
},
})

export default mergeConfig(
config,
tanstackViteConfig({
entry: ['./src/index.ts', './src/production.ts'],
srcDir: './src',
cjs: false,
}),
)
10 changes: 10 additions & 0 deletions packages/solid-start-devtools/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// @ts-check

import rootConfig from '../../eslint.config.js'

export default [
...rootConfig,
{
rules: {},
},
]
Loading
Loading