@tanstack-router-testing/react-start-testing
v0.4.0
Published
Upstream-shaped test helpers for @tanstack/react-start: direct server function tests, mocks, env control, and Vitest wiring.
Maintainers
Readme
tanstack-router-testing
Unit testing utilities for TanStack Router and TanStack Start.
Quick start
pnpm add -D @tanstack-router-testing/react-router-testing @tanstack-router-testing/react-start-testingConfigure Vitest with the Start shim:
// vitest.config.ts
import { tanstackStartTesting } from '@tanstack-router-testing/react-start-testing/vite';
import { defineConfig } from 'vitest/config';
export default defineConfig({
plugins: [tanstackStartTesting()],
test: { environment: 'jsdom' },
});Write your first test — import a single route file, pass it to the harness, and assert:
// posts.$postId.test.tsx
import { render } from '@testing-library/react';
import { describe, expect, it } from 'vitest';
import { createRouterHarness } from '@tanstack-router-testing/react-router-testing';
import { Route } from './routes/posts.$postId';
describe('post route', () => {
it('loads and renders a post', async () => {
const harness = createRouterHarness({
route: Route,
params: { postId: '42' }, // fully typed from route path
loaderData: { id: '42', title: 'Hello' }, // skip the real loader
});
await harness.load();
const { findByText } = render(<harness.TestRouterProvider />);
await expect(findByText('Hello')).resolves.toBeTruthy();
harness.cleanup();
});
});Or use a full route tree for integration-level tests:
import { createRouterHarness } from '@tanstack-router-testing/react-router-testing';
import { routeTree } from './routeTree.gen';
const harness = createRouterHarness({ routeTree, initialEntries: ['/posts/7'] });
await harness.load();
expect(harness.getLoaderData('/posts/$postId')).toBeDefined();
harness.cleanup();Packages
| Package | Purpose |
| --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| react-router-testing | createRouterHarness (file route or full tree), createTestRouter, SSR harness |
| react-start-testing | mockServerFn, mockMiddleware, createStartTestRuntime, RSC runtime, Vite plugin |
| router-testing-core | Internal registry/env runtime (transitive dependency) |
| react-start-testing-storybook | Storybook decorator for Start stories |
All packages are scoped under @tanstack-router-testing/.
Design principles
- Real router, not route stubs. Tests exercise
createRouter, route trees, memory history, loaders, guards, params, search, and redirects through the router itself. - Production-shaped Start calls. Server functions are called as
await fn({ data })— the harness supplies mocks and leaves the call shape alone. - Upstream-mergeable shape. Public exports are shaped for future first-party subpaths (
@tanstack/react-router/testing).
Documentation
- Getting Started
- API Reference
- Guides: Loaders | Guards & Redirects | Server Functions | Middleware | SSR | RSC | Query Integration
- Example Tests
Running tests
pnpm run build # build all packages
pnpm test:unit:core # fast core + integration tests
pnpm test:types # type-level assertions
pnpm test:unit:vendored # 110 vendored TanStack app smoke tests
pnpm run lint:check # oxlint + oxfmtContributing
This project aims to become an upstream contribution to tanstack/router. Feedback, issues, and PRs welcome.
