TanStack Start on Easel
Deploy full-stack TanStack Start applications to Easel with SSR, streaming, server functions, and Nitro.
At a glance
| Support level | Production-ready |
| Rendering | Static, SSR, streaming, selective SSR, and SPA mode |
| Server runtime | Node.js |
| Deployment integration | Nitro |
| Adapter required | Yes |
| Automatic detection | Yes |
| Most recently tested with | TanStack Start RC |
Deploy a TanStack Start application
TanStack Start applications use Nitro to produce the server entry and static assets Easel deploys.
Install Nitro:
Add the Nitro Vite plugin after tanstackStart() and before the React plugin:
Do not manually configure a Nitro deployment preset for Easel. During the platform build, Easel selects the hosting output it expects.
Connect the project’s Git repository to Easel or deploy it with the CLI:
Easel detects TanStack Start, installs dependencies, runs the production build, and deploys the generated client and server output.
The default build command is:
You can override the install command, build command, root directory, Node.js version, and environment variables in your project settings.
Why run TanStack Start on Easel?
TanStack Start keeps routing, data loading, and server boundaries inside the application while allowing the deployment target to remain portable.
Easel preserves that model. Your application uses standard TanStack Start and Nitro integrations rather than an Easel-specific framework fork.
A TanStack Start deployment includes:
- Immutable client assets served through the Easel CDN
- Regional functions for server rendering and server-side code
- Streaming responses from routes and server functions
- Type-safe server functions callable from loaders and components
- Server routes for external HTTP endpoints
- Middleware for authentication, context, logging, and request policy
- Preview deployments for every branch and pull request
- Built-in logs, metrics, traces, WAF, and attack protection
You can inspect function execution, request routing, cache behavior, and resource usage from the Easel dashboard.
What Easel deploys
The Nitro build produces a client application and a server entry that implements TanStack Start’s request handling.
Easel maps that output to platform resources:
| Application output | Easel resource |
|---|---|
| JavaScript, CSS, fonts, and public files | CDN assets |
| Prerendered pages | CDN assets |
| Server-rendered routes | Easel Functions |
| Route loaders requiring server execution | Easel Functions |
| Server functions | Application server function |
| Server routes | Function-backed HTTP routes |
| Start middleware | Application server function |
| Streaming responses | Function response stream |
| Application telemetry | Easel observability pipeline |
Static files are deployed immutably to the CDN. Requests requiring TanStack Start’s server runtime are forwarded to the generated server entry.
Server functions are part of the application’s server bundle. They are not deployed as individually configurable Easel Functions unless the build output explicitly separates them.
Supported features
| Feature | Support | Notes |
|---|---|---|
| File-based routing | Supported | Routes generated by TanStack Router are included in the application build |
| Full-document SSR | Supported | Routes render in Easel Functions |
| Streaming SSR | Supported | HTML is forwarded as the framework produces it |
| Client-side navigation | Supported | Client assets and route manifests are served through the CDN |
| Route loaders | Supported | Loaders run in the environment selected by the route |
beforeLoad | Supported | Runs as part of TanStack Router’s route lifecycle |
| Server functions | Supported | Includes validated, type-safe calls from client and server code |
| Streaming server functions | Supported | Includes ReadableStream and async-generator responses |
| Server routes | Supported | Expose external HTTP endpoints from the Start application |
| Middleware | Supported | Includes request, function, and server-route middleware |
| Selective SSR | Supported | Routes can opt into full, data-only, or client-only rendering |
| SPA mode | Supported | The application server provides the required document fallback |
| Static prerendering | Supported with setup | Routes configured for prerendering are emitted as static output |
| Incremental Static Regeneration | Experimental | Depends on the framework and Nitro output used by the application |
| Redirects and headers | Supported | Return them through standard framework response APIs |
| Cookies and sessions | Supported | Standard request and response cookie behavior is preserved |
| Environment variables | Supported | Server variables remain outside the client bundle unless explicitly exposed |
| Request cancellation | Supported | Long-running server work can observe the request’s AbortSignal |
| Early Hints | Runtime-dependent | Verify behavior in a preview deployment |
| OpenTelemetry | Supported | Standard Node.js instrumentation can export through Easel |
| WebSockets | Not supported | Function requests use HTTP request-response semantics |
| Durable background jobs | Not supported | Use a dedicated queue or background-work service |
TanStack Start and nitro/vite are evolving rapidly. Experimental framework behavior should be validated in a preview deployment before it is promoted to production.
Rendering
TanStack Start allows each route to select how much work happens on the server.
Full SSR
Full SSR sends both the route’s data and rendered markup from the server.
The initial request runs through the TanStack Start server entry in an Easel Function. The generated HTML can begin streaming while the route completes its work.
The browser hydrates the returned document and handles later navigations through TanStack Router.
Data-only SSR
A route can run its loader on the server without rendering its component markup there:
The server returns the route data required by the client, while the component itself renders in the browser.
Client-only rendering
Disable server rendering for a route when it depends entirely on browser APIs or should only render after hydration:
The route remains part of the TanStack Start application, but its component does not render during the server response.
Streaming
Easel forwards response chunks as TanStack Start produces them rather than waiting for the entire document to finish rendering.
This allows the initial document shell and completed route regions to reach the browser while slower data is still resolving.
Streaming remains subject to the function’s maximum execution duration. A disconnected client can also cancel request-bound work when the application observes the request’s abort signal.
Server functions
Server functions define server-only logic that can be imported and called from loaders, components, hooks, and other server functions.
Call the function from application code:
TanStack Start converts client-side calls into HTTP requests and dispatches them to the corresponding server implementation.
The server handler can access:
- Databases and private services
- Server-only environment variables
- Request headers and cookies
- Authentication context
- The request’s cancellation signal
- Node.js runtime APIs supported by Easel Functions
Server function identifiers and dispatch behavior are generated by TanStack Start during the production build.
Keep server-only code isolated
Use .server.ts files for implementation details that must never enter a client bundle:
Import the server-only helper inside the server function handler:
TanStack Start’s build-time environment separation prevents server implementation code from being included in the browser bundle.
Streaming from server functions
Server functions can return streaming data using a ReadableStream or async generator.
Easel keeps the HTTP response open and forwards chunks as the server function yields them.
The invocation remains active and billable until the stream closes, the client disconnects, or the function reaches its execution limit.
For durable work that must continue after a disconnect or survive function termination, submit the job to a queue and stream or poll its persisted state separately.
Server routes
Use server routes for endpoints intended to be called outside the TanStack Start application.
Server routes can return:
- JSON responses
- HTML
- Redirects
- Custom headers and status codes
ReadableStreamresponses- Server-Sent Events
Server routes and server functions are both handled by the generated Start server entry, but they serve different purposes:
| Primitive | Intended use |
|---|---|
| Server function | Type-safe calls made by your TanStack Start application |
| Server route | Public or externally called HTTP endpoint |
Use a server route for webhooks, public APIs, health checks, file responses, and integrations that do not call through the generated Start client.
Middleware
TanStack Start middleware can add shared request behavior without duplicating it across routes or server functions.
Common uses include:
- Authentication and authorization
- Request context
- Logging
- Rate-limit metadata
- Security policy
- Response headers
- Error handling
This middleware runs inside the TanStack Start application function. It should not be confused with Easel’s CDN or WAF request pipeline.
Use Easel security rules for infrastructure-level filtering and TanStack Start middleware for application-level behavior.
Static prerendering
TanStack Start can prerender selected routes during the production build.
Prerendered HTML and its associated client assets are deployed to the Easel CDN. Requests for those pages do not need to invoke the application function unless the route later requires dynamic behavior.
Use prerendering for content that can be generated without request-specific data, such as:
- Marketing pages
- Documentation
- Blog posts
- Public product pages
- Terms and policy pages
The precise configuration depends on the TanStack Start version used by the project. Easel deploys the static output generated by Start and Nitro rather than discovering routes independently.
When adding or changing prerender configuration, verify the generated routes in a preview deployment.
Caching
TanStack Start does not impose one universal application-cache model. Caching behavior can come from:
- Browser cache headers
- Easel’s CDN
- Application-level caches
- Nitro caching utilities
- Database or external cache services
- Prerendered output
- Experimental ISR support
CDN caching
Set standard cache headers on server-route responses:
Shared-cache directives allow eligible responses to be cached by Easel’s CDN.
Do not publicly cache responses containing user-specific or authenticated data.
Server function caching
Server functions may set response headers through TanStack Start’s server request utilities.
Server functions are frequently user-specific. Cache them publicly only when their output is safe to share across callers.
Nitro storage and caching
Nitro provides storage and caching abstractions, but their durability depends on the configured storage driver.
Do not rely on in-memory or local-filesystem storage to persist across Easel Function instances. Configure an external durable driver when cached data must be shared between instances or survive instance replacement.
Environment variables
Configure environment variables in the Easel dashboard or CLI.
Server-only variables can be accessed in server functions, server routes, middleware, and route loaders that execute on the server:
Only expose a value to browser code when it is intentionally public. Vite statically replaces client-visible variables during the build:
Any value available through import.meta.env in client code should be treated as public.
Changing a build-time client variable requires a new deployment. Use separate values for production, preview, and development environments when necessary.
OpenTelemetry
TanStack Start applications running in Easel Functions can use standard Node.js OpenTelemetry instrumentation.
Instrument:
- Server-rendered requests
- Route loaders
- Server functions
- Server routes
- Database queries
- External API requests
- Application-defined operations
Easel can collect application spans alongside function metrics, request logs, and platform traces.
See OpenTelemetry for how Easel collects application spans into request Traces.
Project configuration
Easel detects conventional TanStack Start settings automatically:
| Setting | Default |
|---|---|
| Install command | Detected from the package manager |
| Build command | Package script or vite build |
| Development command | Package script or vite dev |
| Client output | Detected from the Nitro build |
| Server output | Detected from the Nitro build |
| Node.js version | Project or platform default |
For monorepos, set the project root to the directory containing the TanStack Start application’s package.json and vite.config.
Do not manually set a different Nitro preset or NITRO_PRESET for the Easel production build. Overriding the preset may produce a server shape that Easel cannot deploy.
Local development
Continue using TanStack Start’s normal Vite development server:
The Nitro plugin integrates the application server into the Vite development environment.
Local development is best for application logic, routes, loaders, server functions, and middleware. Use an Easel preview deployment to validate platform-specific behavior, including:
- Production bundling
- Function execution
- CDN caching
- Streaming through the production request path
- Environment variables
- Function duration and resource limits
- WAF and security rules
- Production observability
A preview deployment follows the same deployment path as production and receives its own immutable URL.
Known limitations
Nitro integration maturity
The nitro/vite integration uses Vite’s environment APIs and remains under active development.
TanStack Start, Nitro, or Vite updates can change the generated server output. Review framework release notes and create a preview deployment before upgrading production dependencies.
Pin framework and Nitro versions when deployment stability is more important than receiving updates immediately.
WebSockets
TanStack Start applications deployed to Easel Functions cannot accept long-lived WebSocket connections.
Use an external WebSocket provider or a persistent service for bidirectional connections.
Streaming HTTP responses and Server-Sent Events are separate from WebSockets and can operate within the function’s execution limits.
Local filesystem
Function filesystems are ephemeral. Files written during one invocation are not guaranteed to exist in later invocations or on another instance.
Use object storage, a database, or another durable service for persistent data.
In-memory state
Global variables and in-memory caches may survive across requests handled by the same warm instance, but they are not shared across instances and can disappear at any time.
Do not use process memory as the source of truth for sessions, locks, queues, rate limits, or application data.
Background work
Work started during a request is not guaranteed to continue after the function invocation ends.
Use a durable queue or background-work service for jobs that require retries, exceed request duration limits, or must survive process termination.
Incremental Static Regeneration
TanStack Start and Nitro’s incremental regeneration capabilities are evolving. Treat ISR behavior as experimental unless the specific route configuration has been verified against the framework and Nitro versions used by the project.
For predictable static output, use build-time prerendering. For dynamic responses, use explicit cache headers or an application cache.
Troubleshooting
The build does not produce a server entry
Confirm that Nitro is installed:
Then confirm that nitro() appears in vite.config.ts after tanstackStart():
A standard TanStack Start client build without a compatible server output does not contain the production entry Easel expects.
Easel cannot deploy the generated output
Remove any manually configured Nitro preset or NITRO_PRESET environment variable.
Easel selects its supported hosting output during the platform build. A manually selected Node, Bun, or provider-specific preset may produce a different directory structure or server interface.
A server function is unavailable
Confirm that the function is created with createServerFn and exported from a module included in the production build.
Keep server-only implementation details in .server.ts modules and import them from inside the server handler.
Server-only code appears in the client build
Move private implementation code into a .server.ts file. Do not export secrets or database clients from modules that can run in the browser.
Also verify that environment-variable names intended for the server are not exposed through Vite’s public client-variable prefix.
A route works locally but fails after deployment
Create a preview deployment and inspect the build and function logs.
Common causes include:
- Missing production environment variables
- Case-sensitive file paths
- Native dependencies unavailable for the selected runtime
- Reliance on the local filesystem
- A manually selected Nitro preset
- Code that assumes one long-lived server process
- Browser-only APIs executing during SSR
A stream is interrupted
Confirm that the application closes the stream normally and handles client cancellation.
Long-running streams remain subject to the function’s maximum duration. Use a durable job model when the underlying operation may outlive the request.
Cached data is shared between users
Do not mark authenticated or personalized responses as public.
Use private or no-store for user-specific responses, and include appropriate Vary headers where cache behavior depends on request headers.
Compatibility policy
Easel tests its TanStack Start integration against representative applications covering:
- Full-document SSR
- Streaming
- Route loaders
- Server functions
- Streaming server functions
- Server routes
- Middleware
- Selective SSR
- SPA mode
- Static assets
- Static prerendering
- Environment variables
- Production Nitro output
Stable framework releases may work beyond the version listed at the top of this page, but the listed version is the most recently verified baseline.
Because TanStack Start and nitro/vite are under active development, deploy dependency upgrades to a preview environment before promoting them to production.
Next.js
Deploy App Router and Pages Router applications to Easel with support for server rendering, streaming, Server Actions, route handlers, middleware, image optimization, and framework-native caching.
Nuxt
Deploy Nuxt applications to Easel with SSR, streaming, API routes, hybrid rendering, and Nitro-powered caching.