Migrate Next.js to TanStack Start: Boost Performance & AI Friendliness
Discover why migrating from Next.js to TanStack Start significantly improves build times, enhances UI reactivity, and offers superior AI-friendliness for development. Learn the key benefits and code examples.
Introduction
Migrating a web platform from Next.js to TanStack Start offers substantial improvements in build times, leading to faster deployments and urgent bug fixes. This transition also significantly enhances user experience through improved UI reactivity and makes the codebase more accessible and efficient for AI-driven development.
Configuration Checklist
| Element | Version / Link |
|---|---|
| Language / Runtime | TypeScript, JavaScript, Node.js |
| Main library | TanStack Start (React Router) |
| Required APIs | Custom backend APIs (e.g., for user data, school administration) |
| Keys / credentials needed | API keys for external services (e.g., payment gateways), database credentials |
Comparison Tables

Build Time: Faster Deployments
| Metric | Next.js (Legacy) | TanStack Start |
|---|---|---|
| Average Build Time | ~3 minutes 30 seconds | ~1 minute 20 seconds |
| Minimum Build Time | 3 minutes 17 seconds | 1 minute 09 seconds |
| Maximum Build Time | 3 minutes 47 seconds | 1 minute 35 seconds |
| Improvement | - | ~2 minutes 20 seconds (approx. 3x faster) |
Reactivity: A Smoother User Experience

| Metric | Next.js (Legacy) | TanStack Start |
|---|---|---|
| Page Load Behavior | Loaders, then placeholders, then content | Instantaneous display, no loaders |
| Navigation Responsiveness | Noticeable delay with intermediate states | Instantaneous, direct content display |
| User Satisfaction | Lower due to perceived slowness | Higher due to immediate feedback |
AI Friendliness: Declarative Code for Smarter AI

| Feature | Next.js (Legacy) | TanStack Start |
|---|---|---|
| Age & Documentation | Mature, well-documented | Newer, evolving |
| API Stability | Frequent changes (pages/, app/, server components, API routes, server actions/functions, middleware/proxy, use cache) | Stable, declarative |
| Code Structure | Implicit, often requires scrolling to understand component type (server/client) | Explicit, declarative routes, loaders, and server functions |
| AI Comprehension | AI struggles with frequent changes and implicit patterns, leading to errors | AI easily understands explicit declarations, leading to more accurate and efficient code generation |
| Web Standards | Can deviate from standard web logic due to framework-specific abstractions | Adheres closely to web standards, promoting logical and predictable code |
| Flexibility | Less flexible due to opinionated structure and frequent breaking changes | More flexible, allowing custom structures while maintaining clarity |
Step-by-Step Guide
Defining a Route with Pending Component and Metadata
TanStack Start emphasizes explicit route definitions, including pending components for loading states and metadata for SEO, all within a single, clear object. This declarative approach makes the application's structure immediately understandable.
// src/routes/account/change-email.tsx
import { createFileRoute } from '@tanstack/react-router';
import { AccountCardSkeleton } from '~/routes/__route-skeletons'; // Skeleton component for loading state
import { getStartMetadata } from '~/routes/__metadata'; // Utility for metadata
// Define the route explicitly
export const Route = createFileRoute('/account/change-email')({
// pendingComponent is displayed while data is being fetched
pendingComponent: AccountCardSkeleton,
// head defines metadata for the page, crucial for SEO
head: () => ({
title: 'Change email - CodeLyne',
url: '/account/change-email'
}),
// component is the main content of the route once data is loaded
component: ChangeEmailRoute
});
// The actual route component (simplified for example)
function ChangeEmailRoute() {
// ... component logic ...
return (<div>Change Email Form</div>);
}
Creating a Server Function with Input Validation and Middleware
TanStack Start provides a robust way to define server functions, integrating input validation and middleware directly into the function definition. This ensures type safety, data integrity, and proper authorization for server-side operations.
// src/routes/admin/editor.functions.ts
import { createServerFn } from '@tanstack/react-start/server';
import { z } from 'zod'; // Zod for schema validation
import { schoolRoleFromInputMiddleware } from '~/server/middleware/school-role-from-input.middleware';
import { Prisma } from '@prisma/client'; // Prisma for database operations
// Define the input schema for the server function
const adminLessonInput = z.object({
schoolId: z.string().min(1),
lessonId: z.string().min(1).optional(),
title: z.string().min(1)
});
// Export the server function with its configuration
export const getAdminLessonEditorData = createServerFn({
method: 'GET' // Specify the HTTP method
})
// Input validation using Zod schema
.inputValidator(adminLessonInput)
// Middleware for role-based access control
.middleware(schoolRoleFromInputMiddleware('EDITOR'))
// The main handler function for the server action
.handler(async ({ data, context }) => {
// Access user context from middleware
const user = context.user;
// Fetch current school data
const currentSchool = await prisma.school.findFirst({
where: {
id: data.schoolId,
teamMembers: {
some: { userId: user.id }
}
},
select: adminSchoolSelect(user.id) // Select specific fields
});
// Authorization check
if (!currentSchool || !isEditorRole(currentSchool.teamMembers[0]?.roles)) {
throw new ZodRouteError('Unauthorized', 403);
}
// Fetch lesson data
const lesson = await prisma.lesson.findFirst({
where: {
id: data.lessonId,
section: { schoolId: data.schoolId }
},
select: { title: true, description: true, contentDraft: true, commentEnabled: true, schoolId: true, sectionId: true, updatedAt: true, createdAt: true, state: true, productReviewRequired: true, products: { select: { id: true, title: true, imageUrl: true, schoolId: true } } }
});
// Return processed data
return { lesson, sections: [], school: currentSchool };
});
⚠️ Common Mistakes & Pitfalls
- Next.js Abstraction Overload: Next.js's frequent changes and introduction of new concepts (e.g.,
pages/vs.app/directory, server components vs. client components, server actions vs. server functions, middleware vs. proxy,use cache) create a complex and often confusing mental model. This makes it difficult for developers, and especially AI, to understand the application's flow and generate correct code without extensive context. - AI Laziness in Next.js: Due to the implicit nature and frequent changes in Next.js, AI models often struggle to produce accurate and complete features in a single attempt. This leads to iterative debugging and manual fixes, increasing development time and token costs for AI-assisted coding.
- Lack of Declarative Structure: Next.js's less declarative approach means that critical aspects like routing, data loading, and server-side logic are not always explicitly defined in a single, easily parsable block. This ambiguity hinders AI's ability to infer intent and generate robust code, requiring more human intervention.
Glossary
- Declarative Programming: A programming paradigm that expresses the logic of a computation without describing its control flow, focusing on what the program should accomplish rather than how.
- Pending Component: A UI component displayed by TanStack Start while a route's data is being fetched, providing immediate visual feedback to the user during loading states.
- Server Function: A server-side function in TanStack Start that can be directly called from client components, often including built-in features like input validation and middleware for secure and type-safe data handling.
Key Takeaways
- TanStack Start significantly reduces application build times, leading to faster deployments and quicker resolution of production issues.
- The framework enhances UI reactivity by eliminating unnecessary loading states and placeholders, providing an instantaneous and smoother user experience.
- TanStack Start's declarative nature makes the codebase highly AI-friendly, allowing AI models to better understand the application's intent and generate more accurate code.
- The framework adheres to web standards and promotes a logical code structure, which is beneficial for both human developers and AI agents.
- Explicit route definitions, integrated middleware, and type-safe data handling contribute to a cleaner, more maintainable, and predictable codebase.
- Migrating to TanStack Start can be a complex process, but tools like Apex with custom skills can automate parts of the migration, though human oversight is still crucial.
- NowStack, a platform built on TanStack Start, Convex, and Better Auth, aims to provide an ideal stack for developers and AI agents, leveraging these benefits.
Resources
- TanStack Start Official Documentation: https://tanstack.com/start/latest/docs/framework/react/guide/overview
- TanStack Router File-Based Routing: https://tanstack.com/router/latest/docs/framework/react/routing/file-based-routing
- TanStack Start Server Functions: https://tanstack.com/start/latest/docs/framework/react/guide/server-functions
- NowStack (Speaker's platform): https://codelynx.dev/nowstack/waitlist?utm_campaign=manual-cta-link
- Excalidraw (Whiteboard tool used in video): https://excalidraw.com/