or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdisomorphic-functions.mdmiddleware.mdrequest-response.mdrpc-system.mdserver-functions.mdserver-utilities.mdssr-components.mdvite-plugin.md

isomorphic-functions.mddocs/

0

# Isomorphic Functions

1

2

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.

3

4

## Capabilities

5

6

### Create Isomorphic Function

7

8

Creates a function that can have different implementations on the client and server, with implementations defaulting to no-op functions when not provided.

9

10

```typescript { .api }

11

/**

12

* Creates an isomorphic function with different client/server implementations

13

* @returns IsomorphicFnBase for chaining client/server implementations

14

*/

15

function createIsomorphicFn(): IsomorphicFnBase;

16

17

interface IsomorphicFnBase {

18

/** Define the server-side implementation */

19

server<TArgs extends Array<any>, TServer>(

20

serverImpl: (...args: TArgs) => TServer

21

): ServerOnlyFn<TArgs, TServer>;

22

23

/** Define the client-side implementation */

24

client<TArgs extends Array<any>, TClient>(

25

clientImpl: (...args: TArgs) => TClient

26

): ClientOnlyFn<TArgs, TClient>;

27

}

28

```

29

30

**Usage Examples:**

31

32

```typescript

33

import { createIsomorphicFn } from "@tanstack/react-start";

34

35

// Logging function with different implementations

36

const log = createIsomorphicFn()

37

.server((message: string) => {

38

// Server-side: log to console with timestamp

39

console.log(`[${new Date().toISOString()}] ${message}`);

40

})

41

.client((message: string) => {

42

// Client-side: log to browser console

43

console.log(`[CLIENT] ${message}`);

44

});

45

46

// Storage function with different backends

47

const getItem = createIsomorphicFn()

48

.server((key: string) => {

49

// Server-side: use environment variables or file system

50

return process.env[key] || null;

51

})

52

.client((key: string) => {

53

// Client-side: use localStorage

54

return localStorage.getItem(key);

55

});

56

```

57

58

### Create Server-Only Function

59

60

Creates a function that only executes on the server, with the option to add a client-side implementation later.

61

62

```typescript { .api }

63

/**

64

* Creates a server-only function with optional client implementation

65

* @param serverImpl - The server-side implementation

66

* @returns ServerOnlyFn that can be extended with client implementation

67

*/

68

function createServerOnlyFn<TArgs extends Array<any>, TServer>(

69

serverImpl: (...args: TArgs) => TServer

70

): ServerOnlyFn<TArgs, TServer>;

71

72

interface ServerOnlyFn<TArgs extends Array<any>, TServer>

73

extends IsomorphicFn<TArgs, TServer> {

74

/** Add a client-side implementation */

75

client<TClient>(

76

clientImpl: (...args: TArgs) => TClient

77

): IsomorphicFn<TArgs, TServer, TClient>;

78

}

79

```

80

81

**Usage Examples:**

82

83

```typescript

84

import { createServerOnlyFn } from "@tanstack/react-start";

85

86

// Database access function (server-only by default)

87

const getUser = createServerOnlyFn((id: string) => {

88

// Server-side: access database

89

return db.user.findUnique({ where: { id } });

90

});

91

92

// Add client-side fallback

93

const getUserWithFallback = createServerOnlyFn((id: string) => {

94

return db.user.findUnique({ where: { id } });

95

}).client((id: string) => {

96

// Client-side: fetch from API

97

return fetch(`/api/users/${id}`).then(r => r.json());

98

});

99

```

100

101

### Create Client-Only Function

102

103

Creates a function that only executes on the client, with the option to add a server-side implementation later.

104

105

```typescript { .api }

106

/**

107

* Creates a client-only function with optional server implementation

108

* @param clientImpl - The client-side implementation

109

* @returns ClientOnlyFn that can be extended with server implementation

110

*/

111

function createClientOnlyFn<TArgs extends Array<any>, TClient>(

112

clientImpl: (...args: TArgs) => TClient

113

): ClientOnlyFn<TArgs, TClient>;

114

115

interface ClientOnlyFn<TArgs extends Array<any>, TClient>

116

extends IsomorphicFn<TArgs, undefined, TClient> {

117

/** Add a server-side implementation */

118

server<TServer>(

119

serverImpl: (...args: TArgs) => TServer

120

): IsomorphicFn<TArgs, TServer, TClient>;

121

}

122

```

123

124

**Usage Examples:**

125

126

```typescript

127

import { createClientOnlyFn } from "@tanstack/react-start";

128

129

// Analytics tracking function (client-only by default)

130

const trackEvent = createClientOnlyFn((event: string, data: any) => {

131

// Client-side: send to analytics service

132

analytics.track(event, data);

133

});

134

135

// Add server-side implementation for SSR contexts

136

const trackEventWithServer = createClientOnlyFn((event: string, data: any) => {

137

analytics.track(event, data);

138

}).server((event: string, data: any) => {

139

// Server-side: log for debugging or send to server analytics

140

console.log(`[ANALYTICS] ${event}:`, data);

141

});

142

```

143

144

## Advanced Usage Patterns

145

146

### Environment Detection

147

148

Isomorphic functions automatically detect their execution environment and call the appropriate implementation:

149

150

```typescript

151

import { createIsomorphicFn } from "@tanstack/react-start";

152

153

const getCurrentUrl = createIsomorphicFn()

154

.server(() => {

155

// Server-side: construct URL from request

156

return `${process.env.BASE_URL}/current-page`;

157

})

158

.client(() => {

159

// Client-side: use window.location

160

return window.location.href;

161

});

162

163

// This will call the appropriate implementation based on context

164

const url = getCurrentUrl();

165

```

166

167

### Shared Logic with Environment-Specific Details

168

169

```typescript

170

import { createIsomorphicFn } from "@tanstack/react-start";

171

172

const formatDate = createIsomorphicFn()

173

.server((date: Date) => {

174

// Server-side: use server timezone

175

return date.toLocaleString('en-US', {

176

timeZone: process.env.SERVER_TIMEZONE || 'UTC'

177

});

178

})

179

.client((date: Date) => {

180

// Client-side: use user's timezone

181

return date.toLocaleString();

182

});

183

```

184

185

## Types

186

187

```typescript { .api }

188

// Base isomorphic function type

189

interface IsomorphicFn<

190

TArgs extends Array<any> = [],

191

TServer = undefined,

192

TClient = undefined

193

> {

194

(...args: TArgs): TServer | TClient;

195

}

196

197

// Server-only function with optional client extension

198

interface ServerOnlyFn<TArgs extends Array<any>, TServer>

199

extends IsomorphicFn<TArgs, TServer> {

200

client<TClient>(

201

clientImpl: (...args: TArgs) => TClient

202

): IsomorphicFn<TArgs, TServer, TClient>;

203

}

204

205

// Client-only function with optional server extension

206

interface ClientOnlyFn<TArgs extends Array<any>, TClient>

207

extends IsomorphicFn<TArgs, undefined, TClient> {

208

server<TServer>(

209

serverImpl: (...args: TArgs) => TServer

210

): IsomorphicFn<TArgs, TServer, TClient>;

211

}

212

213

// Base interface for creating isomorphic functions

214

interface IsomorphicFnBase extends IsomorphicFn {

215

server<TArgs extends Array<any>, TServer>(

216

serverImpl: (...args: TArgs) => TServer

217

): ServerOnlyFn<TArgs, TServer>;

218

219

client<TArgs extends Array<any>, TClient>(

220

clientImpl: (...args: TArgs) => TClient

221

): ClientOnlyFn<TArgs, TClient>;

222

}

223

```