npm-tanstack--react-start

Description
Modern full-stack React framework with SSR, streaming, server functions, and API routes powered by TanStack Router and Vite.
Author
tessl
Last updated

How to use

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

isomorphic-functions.md docs/

1
# Isomorphic Functions
2
3
Isomorphic functions allow you to create functions with different implementations for client and server environments. This enables code that adapts to its execution context, providing optimal behavior on both sides of your application.
4
5
## Capabilities
6
7
### Create Isomorphic Function
8
9
Creates a function that can have different implementations on the client and server, with implementations defaulting to no-op functions when not provided.
10
11
```typescript { .api }
12
/**
13
* Creates an isomorphic function with different client/server implementations
14
* @returns IsomorphicFnBase for chaining client/server implementations
15
*/
16
function createIsomorphicFn(): IsomorphicFnBase;
17
18
interface IsomorphicFnBase {
19
/** Define the server-side implementation */
20
server<TArgs extends Array<any>, TServer>(
21
serverImpl: (...args: TArgs) => TServer
22
): ServerOnlyFn<TArgs, TServer>;
23
24
/** Define the client-side implementation */
25
client<TArgs extends Array<any>, TClient>(
26
clientImpl: (...args: TArgs) => TClient
27
): ClientOnlyFn<TArgs, TClient>;
28
}
29
```
30
31
**Usage Examples:**
32
33
```typescript
34
import { createIsomorphicFn } from "@tanstack/react-start";
35
36
// Logging function with different implementations
37
const log = createIsomorphicFn()
38
.server((message: string) => {
39
// Server-side: log to console with timestamp
40
console.log(`[${new Date().toISOString()}] ${message}`);
41
})
42
.client((message: string) => {
43
// Client-side: log to browser console
44
console.log(`[CLIENT] ${message}`);
45
});
46
47
// Storage function with different backends
48
const getItem = createIsomorphicFn()
49
.server((key: string) => {
50
// Server-side: use environment variables or file system
51
return process.env[key] || null;
52
})
53
.client((key: string) => {
54
// Client-side: use localStorage
55
return localStorage.getItem(key);
56
});
57
```
58
59
### Create Server-Only Function
60
61
Creates a function that only executes on the server, with the option to add a client-side implementation later.
62
63
```typescript { .api }
64
/**
65
* Creates a server-only function with optional client implementation
66
* @param serverImpl - The server-side implementation
67
* @returns ServerOnlyFn that can be extended with client implementation
68
*/
69
function createServerOnlyFn<TArgs extends Array<any>, TServer>(
70
serverImpl: (...args: TArgs) => TServer
71
): ServerOnlyFn<TArgs, TServer>;
72
73
interface ServerOnlyFn<TArgs extends Array<any>, TServer>
74
extends IsomorphicFn<TArgs, TServer> {
75
/** Add a client-side implementation */
76
client<TClient>(
77
clientImpl: (...args: TArgs) => TClient
78
): IsomorphicFn<TArgs, TServer, TClient>;
79
}
80
```
81
82
**Usage Examples:**
83
84
```typescript
85
import { createServerOnlyFn } from "@tanstack/react-start";
86
87
// Database access function (server-only by default)
88
const getUser = createServerOnlyFn((id: string) => {
89
// Server-side: access database
90
return db.user.findUnique({ where: { id } });
91
});
92
93
// Add client-side fallback
94
const getUserWithFallback = createServerOnlyFn((id: string) => {
95
return db.user.findUnique({ where: { id } });
96
}).client((id: string) => {
97
// Client-side: fetch from API
98
return fetch(`/api/users/${id}`).then(r => r.json());
99
});
100
```
101
102
### Create Client-Only Function
103
104
Creates a function that only executes on the client, with the option to add a server-side implementation later.
105
106
```typescript { .api }
107
/**
108
* Creates a client-only function with optional server implementation
109
* @param clientImpl - The client-side implementation
110
* @returns ClientOnlyFn that can be extended with server implementation
111
*/
112
function createClientOnlyFn<TArgs extends Array<any>, TClient>(
113
clientImpl: (...args: TArgs) => TClient
114
): ClientOnlyFn<TArgs, TClient>;
115
116
interface ClientOnlyFn<TArgs extends Array<any>, TClient>
117
extends IsomorphicFn<TArgs, undefined, TClient> {
118
/** Add a server-side implementation */
119
server<TServer>(
120
serverImpl: (...args: TArgs) => TServer
121
): IsomorphicFn<TArgs, TServer, TClient>;
122
}
123
```
124
125
**Usage Examples:**
126
127
```typescript
128
import { createClientOnlyFn } from "@tanstack/react-start";
129
130
// Analytics tracking function (client-only by default)
131
const trackEvent = createClientOnlyFn((event: string, data: any) => {
132
// Client-side: send to analytics service
133
analytics.track(event, data);
134
});
135
136
// Add server-side implementation for SSR contexts
137
const trackEventWithServer = createClientOnlyFn((event: string, data: any) => {
138
analytics.track(event, data);
139
}).server((event: string, data: any) => {
140
// Server-side: log for debugging or send to server analytics
141
console.log(`[ANALYTICS] ${event}:`, data);
142
});
143
```
144
145
## Advanced Usage Patterns
146
147
### Environment Detection
148
149
Isomorphic functions automatically detect their execution environment and call the appropriate implementation:
150
151
```typescript
152
import { createIsomorphicFn } from "@tanstack/react-start";
153
154
const getCurrentUrl = createIsomorphicFn()
155
.server(() => {
156
// Server-side: construct URL from request
157
return `${process.env.BASE_URL}/current-page`;
158
})
159
.client(() => {
160
// Client-side: use window.location
161
return window.location.href;
162
});
163
164
// This will call the appropriate implementation based on context
165
const url = getCurrentUrl();
166
```
167
168
### Shared Logic with Environment-Specific Details
169
170
```typescript
171
import { createIsomorphicFn } from "@tanstack/react-start";
172
173
const formatDate = createIsomorphicFn()
174
.server((date: Date) => {
175
// Server-side: use server timezone
176
return date.toLocaleString('en-US', {
177
timeZone: process.env.SERVER_TIMEZONE || 'UTC'
178
});
179
})
180
.client((date: Date) => {
181
// Client-side: use user's timezone
182
return date.toLocaleString();
183
});
184
```
185
186
## Types
187
188
```typescript { .api }
189
// Base isomorphic function type
190
interface IsomorphicFn<
191
TArgs extends Array<any> = [],
192
TServer = undefined,
193
TClient = undefined
194
> {
195
(...args: TArgs): TServer | TClient;
196
}
197
198
// Server-only function with optional client extension
199
interface ServerOnlyFn<TArgs extends Array<any>, TServer>
200
extends IsomorphicFn<TArgs, TServer> {
201
client<TClient>(
202
clientImpl: (...args: TArgs) => TClient
203
): IsomorphicFn<TArgs, TServer, TClient>;
204
}
205
206
// Client-only function with optional server extension
207
interface ClientOnlyFn<TArgs extends Array<any>, TClient>
208
extends IsomorphicFn<TArgs, undefined, TClient> {
209
server<TServer>(
210
serverImpl: (...args: TArgs) => TServer
211
): IsomorphicFn<TArgs, TServer, TClient>;
212
}
213
214
// Base interface for creating isomorphic functions
215
interface IsomorphicFnBase extends IsomorphicFn {
216
server<TArgs extends Array<any>, TServer>(
217
serverImpl: (...args: TArgs) => TServer
218
): ServerOnlyFn<TArgs, TServer>;
219
220
client<TArgs extends Array<any>, TClient>(
221
clientImpl: (...args: TArgs) => TClient
222
): ClientOnlyFn<TArgs, TClient>;
223
}
224
```