npm-tanstack--react-start

Description
SSR, Streaming, Server Functions, API Routes, bundling and more powered by TanStack Router and Vite. Ready to deploy to your favorite hosting provider.
Author
tessl
Last updated

How to use

npx @tessl/cli registry install tessl/npm-tanstack--react-start@1.131.0

server-functions.md docs/

1
# Server Functions
2
3
Type-safe server function system enabling seamless RPC-style communication between client and server code with middleware support, validation, automatic serialization, and full TypeScript integration throughout the stack.
4
5
## Capabilities
6
7
### Server Function Creation
8
9
Core functionality for creating server functions that can be called from client-side code with full type safety.
10
11
```typescript { .api }
12
/**
13
* Creates a server function with optional validation and middleware
14
* @param options - Optional configuration for method, validation, and middleware
15
* @returns Server function builder for chaining configuration
16
*/
17
function createServerFn<TValidator = undefined, TMiddleware = []>(
18
options?: ServerFnBaseOptions<TValidator, TMiddleware>
19
): ServerFnBuilder<TValidator, TMiddleware>;
20
21
interface ServerFnBuilder<TValidator, TMiddleware> {
22
/** Configure HTTP method for the server function (default: POST) */
23
method<TMethod extends Method>(method: TMethod): ServerFnBuilder<TValidator, TMiddleware>;
24
25
/** Add input validation to the server function */
26
validator<V>(validator: V): ServerFnBuilder<V, TMiddleware>;
27
28
/** Add middleware to the server function */
29
middleware<M extends AnyFunctionMiddleware>(
30
middleware: M
31
): ServerFnBuilder<TValidator, [...TMiddleware, M]>;
32
33
/** Define the handler function that runs on the server */
34
handler<THandlerFn extends Function>(
35
handlerFn: THandlerFn
36
): CompiledFetcherFn<THandlerFn>;
37
}
38
39
interface ServerFnBaseOptions<TValidator, TMiddleware> {
40
method?: Method;
41
validator?: TValidator;
42
middleware?: TMiddleware;
43
}
44
45
type Method = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
46
47
interface CompiledFetcherFn<THandlerFn> extends Function {
48
(...args: Parameters<THandlerFn>): Promise<ReturnType<THandlerFn>>;
49
url: string;
50
functionId: string;
51
}
52
```
53
54
**Usage Examples:**
55
56
```typescript
57
import { createServerFn } from '@tanstack/react-start';
58
import { z } from 'zod';
59
60
// Simple server function
61
const getUsers = createServerFn()
62
.handler(async () => {
63
return await database.users.findMany();
64
});
65
66
// Server function with validation
67
const createUser = createServerFn()
68
.validator(z.object({
69
name: z.string().min(1),
70
email: z.string().email(),
71
}))
72
.handler(async (input) => {
73
// input is fully typed based on validator
74
return await database.users.create({ data: input });
75
});
76
77
// Server function with middleware
78
const authMiddleware = createMiddleware({
79
server: async ({ context, next }) => {
80
const auth = await validateAuth(context.request);
81
return next({ context: { ...context, user: auth.user } });
82
},
83
});
84
85
const deleteUser = createServerFn()
86
.middleware(authMiddleware)
87
.handler(async (userId: string, { context }) => {
88
// context.user is available from middleware
89
return await database.users.delete({
90
where: { id: userId, ownerId: context.user.id }
91
});
92
});
93
```
94
95
### Isomorphic Functions
96
97
Functions that can execute different logic on client and server environments.
98
99
```typescript { .api }
100
/**
101
* Creates a function that runs different implementations on client vs server
102
* @param clientFn - Function implementation for client-side execution
103
* @param serverFn - Function implementation for server-side execution
104
* @returns Isomorphic function that automatically chooses correct implementation
105
*/
106
function createIsomorphicFn<TArgs extends Array<any>, TReturn>(
107
clientFn: (...args: TArgs) => TReturn,
108
serverFn: (...args: TArgs) => TReturn
109
): IsomorphicFn<TArgs, TReturn>;
110
111
interface IsomorphicFn<TArgs extends Array<any>, TReturn> {
112
(...args: TArgs): TReturn;
113
}
114
115
interface IsomorphicFnBase<TArgs extends Array<any>, TReturn> {
116
clientFn: (...args: TArgs) => TReturn;
117
serverFn: (...args: TArgs) => TReturn;
118
}
119
```
120
121
**Usage Example:**
122
123
```typescript
124
import { createIsomorphicFn } from '@tanstack/react-start';
125
126
const getEnvironment = createIsomorphicFn(
127
// Client implementation
128
() => ({
129
platform: 'browser',
130
userAgent: navigator.userAgent,
131
url: window.location.href,
132
}),
133
// Server implementation
134
() => ({
135
platform: 'node',
136
version: process.version,
137
env: process.env.NODE_ENV,
138
})
139
);
140
141
console.log(getEnvironment()); // Different output on client vs server
142
```
143
144
### Middleware System
145
146
Comprehensive middleware system for server functions with validation, context passing, and lifecycle hooks.
147
148
```typescript { .api }
149
/**
150
* Creates middleware for server functions with optional validation and lifecycle hooks
151
* @param options - Middleware configuration with client, server, and after hooks
152
* @returns Configured middleware function
153
*/
154
function createMiddleware<TOptions extends FunctionMiddlewareOptions>(
155
options: TOptions
156
): FunctionMiddlewareWithTypes<TOptions>;
157
158
interface FunctionMiddlewareOptions {
159
/** Validation schema for middleware inputs */
160
validator?: any;
161
162
/** Server-side middleware function */
163
server?: FunctionMiddlewareServer;
164
165
/** Client-side middleware function */
166
client?: FunctionMiddlewareClient;
167
168
/** After middleware hook for cleanup or additional processing */
169
after?: FunctionMiddlewareAfterServer | FunctionMiddlewareAfterClient;
170
}
171
172
interface FunctionMiddlewareServer<TValidator = any, TContext = any> {
173
(options: FunctionMiddlewareServerFnOptions<TValidator, TContext>):
174
Promise<FunctionMiddlewareServerFnResult<any, TContext>>;
175
}
176
177
interface FunctionMiddlewareClient<TValidator = any, TContext = any> {
178
(options: FunctionMiddlewareClientFnOptions<TValidator, TContext>):
179
Promise<FunctionMiddlewareClientFnResult<any, TContext>>;
180
}
181
182
interface FunctionMiddlewareAfterServer<TValidator = any, TContext = any> {
183
(options: FunctionMiddlewareServerFnOptions<TValidator, TContext>):
184
Promise<void> | void;
185
}
186
187
interface FunctionMiddlewareAfterClient<TValidator = any, TContext = any> {
188
(options: FunctionMiddlewareClientFnOptions<TValidator, TContext>):
189
Promise<void> | void;
190
}
191
```
192
193
**Usage Examples:**
194
195
```typescript
196
import { createMiddleware, createServerFn } from '@tanstack/react-start';
197
198
// Authentication middleware
199
const authMiddleware = createMiddleware({
200
server: async ({ context, next }) => {
201
const token = context.request.headers.get('Authorization');
202
if (!token) throw new Error('Authentication required');
203
204
const user = await validateToken(token);
205
return next({ context: { ...context, user } });
206
},
207
});
208
209
// Logging middleware
210
const loggingMiddleware = createMiddleware({
211
server: async ({ context, next }) => {
212
console.log(`Server function called: ${context.request.url}`);
213
const start = Date.now();
214
215
const result = await next();
216
217
console.log(`Server function completed in ${Date.now() - start}ms`);
218
return result;
219
},
220
});
221
222
// Using middleware in server functions
223
const protectedFunction = createServerFn()
224
.middleware(authMiddleware)
225
.middleware(loggingMiddleware)
226
.handler(async (data: any, { context }) => {
227
// context.user is available from authMiddleware
228
return await processDataForUser(data, context.user);
229
});
230
```
231
232
### Global Middleware
233
234
System for registering middleware that applies to all server functions.
235
236
```typescript { .api }
237
/**
238
* Registers middleware globally for all server functions
239
* @param middleware - Middleware function to apply globally
240
*/
241
function registerGlobalMiddleware(middleware: AnyFunctionMiddleware): void;
242
243
/** Global middleware registry containing all registered global middleware */
244
const globalMiddleware: Array<AnyFunctionMiddleware>;
245
246
type AnyFunctionMiddleware = FunctionMiddleware<any, any, any>;
247
248
interface FunctionMiddleware<TValidator, TContext, TResult> {
249
validator?: TValidator;
250
server?: FunctionMiddlewareServer<TValidator, TContext>;
251
client?: FunctionMiddlewareClient<TValidator, TResult>;
252
after?: FunctionMiddlewareAfterValidator<TValidator, TContext>;
253
}
254
```
255
256
### Server Function Runtime (Client)
257
258
Client-side runtime for making RPC calls to server functions.
259
260
```typescript { .api }
261
/**
262
* Creates client-side RPC function for calling server functions
263
* @param functionId - Unique identifier for the server function
264
* @param serverBase - Base URL for server function endpoints
265
* @returns Client-side function that calls the server function
266
*/
267
function createClientRpc(functionId: string, serverBase: string): ClientRpcFunction;
268
269
interface ClientRpcFunction {
270
(...args: Array<any>): Promise<any>;
271
url: string;
272
functionId: string;
273
}
274
```
275
276
### Server Function Runtime (Server)
277
278
Server-side runtime for handling server function calls.
279
280
```typescript { .api }
281
/**
282
* Creates server-side RPC handler for processing server function calls
283
* @param functionId - Unique identifier for the server function
284
* @param serverBase - Base URL for server function endpoints
285
* @param splitImportFn - Dynamic import function for loading server function code
286
* @returns Server-side function handler
287
*/
288
function createServerRpc(
289
functionId: string,
290
serverBase: string,
291
splitImportFn: () => Promise<any>
292
): ServerRpcFunction;
293
294
interface ServerRpcFunction {
295
(...args: Array<any>): Promise<any>;
296
url: string;
297
functionId: string;
298
}
299
```
300
301
### Server Function Utilities
302
303
Utility functions for server function processing, middleware execution, and data handling.
304
305
```typescript { .api }
306
/**
307
* Applies middleware to a server function execution chain
308
* @param middlewares - Array of middleware functions to apply
309
* @param context - Execution context
310
* @returns Processed result with middleware applied
311
*/
312
function applyMiddleware<TContext, TResult>(
313
middlewares: Array<AnyFunctionMiddleware>,
314
context: TContext
315
): Promise<TResult>;
316
317
/**
318
* Executes validation on server function inputs
319
* @param validator - Validation schema or function
320
* @param data - Data to validate
321
* @returns Validated data or throws validation error
322
*/
323
function execValidator<TValidator, TData>(
324
validator: TValidator,
325
data: TData
326
): TData;
327
328
/**
329
* Converts server function base configuration to middleware
330
* @param options - Server function base options
331
* @returns Middleware function
332
*/
333
function serverFnBaseToMiddleware<TOptions extends ServerFnBaseOptions<any, any>>(
334
options: TOptions
335
): AnyFunctionMiddleware;
336
337
/**
338
* Extracts form data context from request
339
* @param request - HTTP request containing form data
340
* @returns Extracted form data and metadata
341
*/
342
function extractFormDataContext(request: Request): Promise<{
343
data: FormData;
344
contentType: string;
345
}>;
346
347
/**
348
* Flattens nested middleware arrays into a single array
349
* @param middlewares - Nested middleware arrays
350
* @returns Flattened middleware array
351
*/
352
function flattenMiddlewares(
353
middlewares: Array<AnyFunctionMiddleware | Array<AnyFunctionMiddleware>>
354
): Array<AnyFunctionMiddleware>;
355
356
/**
357
* Static cache for server function results
358
* @param key - Cache key
359
* @param value - Value to cache (optional, retrieves if not provided)
360
* @returns Cached value or undefined
361
*/
362
function serverFnStaticCache<T>(key: string, value?: T): T | undefined;
363
364
/**
365
* Executes middleware with proper error handling and context passing
366
* @param middleware - Middleware function to execute
367
* @param context - Execution context
368
* @returns Promise resolving to middleware result
369
*/
370
function executeMiddleware<TContext, TResult>(
371
middleware: AnyFunctionMiddleware,
372
context: TContext
373
): Promise<TResult>;
374
```
375
376
### Response Utilities
377
378
Utilities for creating and handling server function responses.
379
380
```typescript { .api }
381
/**
382
* Creates a JSON response with proper headers
383
* @param data - Data to serialize as JSON
384
* @param init - Optional response initialization options
385
* @returns Response object with JSON content
386
*/
387
function json<T = any>(data: T, init?: ResponseInit): JsonResponse<T>;
388
389
interface JsonResponse<T = any> extends Response {
390
json(): Promise<T>;
391
}
392
393
type ServerFnResponseType = Response | any;
394
```
395
396
## Core Types
397
398
```typescript { .api }
399
interface ServerFn<TValidator = any, TMiddleware = any, THandler = any> {
400
validator?: TValidator;
401
middleware?: TMiddleware;
402
handler: THandler;
403
method: Method;
404
url: string;
405
functionId: string;
406
}
407
408
interface ServerFnCtx {
409
request: Request;
410
params: Record<string, string>;
411
data: FormData | any;
412
}
413
414
interface ServerFnType<TInput = any, TOutput = any> {
415
input: TInput;
416
output: TOutput;
417
}
418
419
interface MiddlewareFn<TContext = any, TResult = any> {
420
(context: TContext): Promise<TResult> | TResult;
421
}
422
423
interface ServerFnMiddlewareOptions<TValidator, TContext> {
424
validator: TValidator;
425
context: TContext;
426
request: Request;
427
next: NextFn;
428
}
429
430
interface ServerFnMiddlewareResult<TResult, TContext> {
431
result: TResult;
432
context: TContext;
433
}
434
435
interface NextFn {
436
(context?: any): Promise<any>;
437
}
438
439
interface StaticCachedResult<T> {
440
value: T;
441
timestamp: number;
442
key: string;
443
}
444
445
// Fetcher types
446
interface Fetcher<TData = any, TError = any> {
447
data?: TData;
448
error?: TError;
449
isLoading: boolean;
450
isFetching: boolean;
451
isSuccess: boolean;
452
isError: boolean;
453
}
454
455
interface OptionalFetcher<TData, TError> extends Fetcher<TData, TError> {
456
data?: TData;
457
}
458
459
interface RequiredFetcher<TData, TError> extends Fetcher<TData, TError> {
460
data: TData;
461
}
462
463
interface FetcherData<T = any> {
464
data: T;
465
error?: Error;
466
isLoading: boolean;
467
}
468
469
interface FetcherBaseOptions {
470
retry?: number;
471
retryDelayMs?: number;
472
timeout?: number;
473
}
474
475
interface CompiledFetcherFnOptions extends FetcherBaseOptions {
476
method?: Method;
477
headers?: HeadersInit;
478
}
479
480
// Middleware types
481
interface FunctionMiddlewareWithTypes<TOptions> {
482
validator: TOptions extends { validator: infer V } ? V : undefined;
483
server: TOptions extends { server: infer S } ? S : undefined;
484
client: TOptions extends { client: infer C } ? C : undefined;
485
after: TOptions extends { after: infer A } ? A : undefined;
486
}
487
488
interface FunctionMiddlewareValidator<TInput = any, TOutput = any> {
489
(input: TInput): TOutput | Promise<TOutput>;
490
}
491
492
interface FunctionMiddlewareServerFnOptions<TValidator, TContext> {
493
validator: TValidator;
494
context: TContext;
495
request: Request;
496
data: any;
497
next: FunctionMiddlewareServerNextFn;
498
}
499
500
interface FunctionMiddlewareServerFnResult<TResult, TContext> {
501
result: TResult;
502
context: TContext;
503
}
504
505
interface FunctionMiddlewareServerNextFn {
506
(context?: any): Promise<any>;
507
}
508
509
interface FunctionMiddlewareClientFnOptions<TValidator, TContext> {
510
validator: TValidator;
511
context: TContext;
512
next: FunctionMiddlewareClientNextFn;
513
}
514
515
interface FunctionMiddlewareClientFnResult<TResult, TContext> {
516
result: TResult;
517
context: TContext;
518
}
519
520
interface FunctionMiddlewareClientNextFn {
521
(): Promise<any>;
522
}
523
524
interface FunctionClientResultWithContext<TResult, TContext> {
525
result: TResult;
526
context: TContext;
527
}
528
529
interface FunctionServerResultWithContext<TResult, TContext> {
530
result: TResult;
531
context: TContext;
532
}
533
534
interface FunctionMiddlewareAfterValidator<TValidator, TContext> {
535
(options: FunctionMiddlewareServerFnOptions<TValidator, TContext>): void | Promise<void>;
536
}
537
538
interface FunctionMiddlewareClientFn<TValidator, TContext, TResult> {
539
(options: FunctionMiddlewareClientFnOptions<TValidator, TContext>):
540
Promise<FunctionMiddlewareClientFnResult<TResult, TContext>>;
541
}
542
543
// Type utility types
544
type IntersectAllValidatorInputs<T extends Array<any>> =
545
T extends [infer Head, ...infer Tail]
546
? (Head extends { validator: { input: infer Input } } ? Input : {}) &
547
IntersectAllValidatorInputs<Tail>
548
: {};
549
550
type IntersectAllValidatorOutputs<T extends Array<any>> =
551
T extends [infer Head, ...infer Tail]
552
? (Head extends { validator: { output: infer Output } } ? Output : {}) &
553
IntersectAllValidatorOutputs<Tail>
554
: {};
555
556
type AssignAllClientContextBeforeNext<T extends Array<any>> =
557
T extends [infer Head, ...infer Tail]
558
? (Head extends { client: { context: infer Context } } ? Context : {}) &
559
AssignAllClientContextBeforeNext<Tail>
560
: {};
561
562
type AssignAllMiddleware<T extends Array<any>> =
563
T extends [infer Head, ...infer Tail]
564
? Head & AssignAllMiddleware<Tail>
565
: {};
566
567
type AssignAllServerContext<T extends Array<any>> =
568
T extends [infer Head, ...infer Tail]
569
? (Head extends { server: { context: infer Context } } ? Context : {}) &
570
AssignAllServerContext<Tail>
571
: {};
572
573
interface FunctionMiddlewareServerFn<TInput, TOutput, TContext> {
574
(input: TInput, context: TContext): Promise<TOutput>;
575
}
576
577
interface AnyRequestMiddleware {
578
(request: Request): Promise<Request> | Request;
579
}
580
```
581
582
### Advanced Server Function Utilities
583
584
Core server function fetching utility used internally for RPC communication. Useful for advanced users who need custom server function handling.
585
586
```typescript { .api }
587
/**
588
* Core server function fetcher that handles HTTP requests for server functions
589
* Used internally by the RPC system, but can be used for custom implementations
590
* @param url - The server function endpoint URL
591
* @param args - Arguments to pass to the server function
592
* @param handler - HTTP handler function for making the actual request
593
* @returns Promise resolving to the server function result
594
*/
595
function serverFnFetcher(
596
url: string,
597
args: Array<any>,
598
handler: (url: string, requestInit: RequestInit) => Promise<Response>
599
): Promise<any>;
600
```
601
602
**Usage Example:**
603
604
```typescript
605
import { serverFnFetcher } from '@tanstack/react-start/server-functions-client';
606
607
// Custom server function handler
608
const customHandler = async (url: string, requestInit: RequestInit) => {
609
// Add custom headers or logging
610
const customInit = {
611
...requestInit,
612
headers: {
613
...requestInit.headers,
614
'X-Custom-Header': 'my-value',
615
},
616
};
617
618
console.log('Making server function call to:', url);
619
return fetch(url, customInit);
620
};
621
622
// Use the fetcher directly
623
const result = await serverFnFetcher(
624
'/api/my-server-function',
625
[userId, options],
626
customHandler
627
);
628
```
629
```