or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cookie-session.mdglobal-polyfills.mdindex.mdserver-runtime.mdsession-storage.mdstream-utilities.mdupload-handling.md

server-runtime.mddocs/

0

# Server Runtime API

1

2

Complete re-export of @remix-run/server-runtime providing unified access to all Remix server functionality including request handling, response utilities, data fetching, and error handling.

3

4

## Capabilities

5

6

### Request Handler

7

8

Creates a request handler for processing Remix application requests.

9

10

```typescript { .api }

11

/**

12

* Creates a request handler for a Remix application

13

* @param build - The server build configuration

14

* @returns RequestHandler function for processing requests

15

*/

16

function createRequestHandler(build: ServerBuild): RequestHandler;

17

18

interface RequestHandler {

19

(request: Request, loadContext?: AppLoadContext): Promise<Response>;

20

}

21

```

22

23

**Usage Examples:**

24

25

```typescript

26

import { createRequestHandler } from "@remix-run/node";

27

import * as build from "./build/index.js";

28

29

// Create request handler

30

const handleRequest = createRequestHandler(build);

31

32

// Use with Express

33

app.all("*", async (req, res) => {

34

const request = new Request(`http://localhost:3000${req.url}`, {

35

method: req.method,

36

headers: req.headers,

37

body: req.method !== "GET" && req.method !== "HEAD" ? req.body : undefined

38

});

39

40

const response = await handleRequest(request);

41

42

res.status(response.status);

43

response.headers.forEach((value, name) => {

44

res.header(name, value);

45

});

46

47

if (response.body) {

48

response.body.pipeTo(new WritableStream({

49

write(chunk) {

50

res.write(chunk);

51

},

52

close() {

53

res.end();

54

}

55

}));

56

} else {

57

res.end();

58

}

59

});

60

```

61

62

### Response Utilities

63

64

Utilities for creating various types of responses in Remix applications.

65

66

```typescript { .api }

67

/**

68

* Creates a JSON response with proper headers

69

* @param object - The object to serialize as JSON

70

* @param init - Optional response initialization options

71

* @returns TypedResponse with JSON content

72

*/

73

function json<T>(object: T, init?: ResponseInit): TypedResponse<T>;

74

75

/**

76

* Creates a deferred response for streaming data

77

* @param object - Object containing promises to be resolved

78

* @param init - Optional response initialization options

79

* @returns TypedDeferredData for streaming

80

*/

81

function defer<T>(object: T, init?: ResponseInit): TypedDeferredData<T>;

82

83

/**

84

* Creates a redirect response

85

* @param url - The URL to redirect to

86

* @param init - Status code (302) or ResponseInit object

87

* @returns Redirect response

88

*/

89

function redirect(url: string, init?: number | ResponseInit): Response;

90

91

/**

92

* Creates a document redirect response

93

* @param url - The URL to redirect to

94

* @param init - Status code or ResponseInit object

95

* @returns Document redirect response

96

*/

97

function redirectDocument(url: string, init?: number | ResponseInit): Response;

98

99

/**

100

* Creates a replace response (replaces current history entry)

101

* @param url - The URL to replace with

102

* @param init - Status code or ResponseInit object

103

* @returns Replace response

104

*/

105

function replace(url: string, init?: number | ResponseInit): Response;

106

107

/**

108

* Creates a data response (legacy utility)

109

* @param object - The data to include in the response

110

* @param init - Optional response initialization options

111

* @returns Response with data

112

*/

113

function data<T>(object: T, init?: ResponseInit): Response;

114

```

115

116

**Usage Examples:**

117

118

```typescript

119

import { json, defer, redirect, data } from "@remix-run/node";

120

121

// JSON response

122

export async function loader({ params }: LoaderFunctionArgs) {

123

const user = await getUserById(params.userId);

124

125

if (!user) {

126

return json({ error: "User not found" }, { status: 404 });

127

}

128

129

return json({ user });

130

}

131

132

// Deferred response for streaming

133

export async function loader({ params }: LoaderFunctionArgs) {

134

// Fast data

135

const user = await getUserById(params.userId);

136

137

// Slow data (streamed later)

138

const postsPromise = getPostsByUserId(params.userId);

139

const commentsPromise = getCommentsByUserId(params.userId);

140

141

return defer({

142

user, // Available immediately

143

posts: postsPromise, // Streamed when ready

144

comments: commentsPromise // Streamed when ready

145

});

146

}

147

148

// Redirect responses

149

export async function action({ request }: ActionFunctionArgs) {

150

const formData = await request.formData();

151

const intent = formData.get("intent");

152

153

if (intent === "delete") {

154

await deleteUser(String(formData.get("userId")));

155

return redirect("/users");

156

}

157

158

if (intent === "update") {

159

await updateUser(String(formData.get("userId")), formData);

160

return redirectDocument(`/users/${formData.get("userId")}`);

161

}

162

163

return redirect("/");

164

}

165

```

166

167

### Session and Cookie Utilities

168

169

Utilities for working with sessions and cookies.

170

171

```typescript { .api }

172

/**

173

* Creates a new session instance

174

* @param initialData - Optional initial session data

175

* @param id - Optional session ID

176

* @returns New session instance

177

*/

178

function createSession<Data = SessionData, FlashData = Data>(

179

initialData?: Partial<Data>,

180

id?: string

181

): Session<Data, FlashData>;

182

183

/**

184

* Type guard to check if an object is a Cookie

185

* @param object - Object to check

186

* @returns True if object is a Cookie

187

*/

188

function isCookie(object: any): object is Cookie;

189

190

/**

191

* Type guard to check if an object is a Session

192

* @param object - Object to check

193

* @returns True if object is a Session

194

*/

195

function isSession(object: any): object is Session;

196

```

197

198

### Upload Handling Utilities

199

200

Utilities for handling file uploads in Remix applications.

201

202

```typescript { .api }

203

/**

204

* Composes multiple upload handlers into a single handler

205

* @param handlers - Array of upload handlers to compose

206

* @returns Composed upload handler

207

*/

208

function unstable_composeUploadHandlers(

209

...handlers: UploadHandler[]

210

): UploadHandler;

211

212

/**

213

* Creates a memory-based upload handler

214

* @param options - Configuration options for memory upload handler

215

* @returns UploadHandler that stores files in memory

216

*/

217

function unstable_createMemoryUploadHandler(

218

options?: MemoryUploadHandlerOptions

219

): UploadHandler;

220

221

/**

222

* Parses multipart form data using specified upload handlers

223

* @param request - The request containing multipart form data

224

* @param uploadHandler - Handler for processing uploaded files

225

* @returns Promise resolving to FormData with processed uploads

226

*/

227

function unstable_parseMultipartFormData(

228

request: Request,

229

uploadHandler: UploadHandler

230

): Promise<FormData>;

231

```

232

233

**Usage Examples:**

234

235

```typescript

236

import {

237

unstable_composeUploadHandlers,

238

unstable_createMemoryUploadHandler,

239

unstable_parseMultipartFormData,

240

unstable_createFileUploadHandler

241

} from "@remix-run/node";

242

243

// Compose multiple upload handlers

244

const uploadHandler = unstable_composeUploadHandlers(

245

// Try file handler first for large files

246

unstable_createFileUploadHandler({

247

directory: "/tmp/uploads",

248

filter: ({ filename, contentType }) => {

249

return filename && contentType.startsWith("image/");

250

}

251

}),

252

// Fall back to memory handler for small files

253

unstable_createMemoryUploadHandler({

254

maxPartSize: 100000 // 100KB

255

})

256

);

257

258

// Use in action

259

export async function action({ request }: ActionFunctionArgs) {

260

const formData = await unstable_parseMultipartFormData(

261

request,

262

uploadHandler

263

);

264

265

const avatar = formData.get("avatar") as File;

266

const document = formData.get("document") as File;

267

268

return json({

269

avatar: avatar?.name,

270

document: document?.name

271

});

272

}

273

```

274

275

### Development Utilities

276

277

Utilities for development and debugging in Remix applications.

278

279

```typescript { .api }

280

/**

281

* Broadcasts a development ready signal

282

* @param build - The server build

283

* @param options - Optional broadcast options

284

*/

285

function broadcastDevReady(build: ServerBuild, options?: any): void;

286

287

/**

288

* Logs a development ready message

289

* @param build - The server build

290

*/

291

function logDevReady(build: ServerBuild): void;

292

```

293

294

## Type Definitions

295

296

The server runtime provides comprehensive TypeScript types for all Remix server functionality:

297

298

```typescript { .api }

299

// Core function types

300

type ActionFunction<Context = AppLoadContext> = (

301

args: ActionFunctionArgs<Context>

302

) => Promise<Response> | Response | Promise<any> | any;

303

304

type LoaderFunction<Context = AppLoadContext> = (

305

args: LoaderFunctionArgs<Context>

306

) => Promise<Response> | Response | Promise<any> | any;

307

308

interface ActionFunctionArgs<Context = AppLoadContext> {

309

request: Request;

310

params: Params;

311

context: Context;

312

}

313

314

interface LoaderFunctionArgs<Context = AppLoadContext> {

315

request: Request;

316

params: Params;

317

context: Context;

318

}

319

320

// Response types

321

interface TypedResponse<T = unknown> extends Response {

322

json(): Promise<T>;

323

}

324

325

interface TypedDeferredData<T = Record<string, unknown>> {

326

data: T;

327

init?: ResponseInit;

328

}

329

330

// Error handling

331

interface ErrorResponse {

332

status: number;

333

statusText: string;

334

data: any;

335

}

336

337

// Meta and headers functions

338

type MetaFunction<

339

Loader extends LoaderFunction | unknown = unknown,

340

ParentsLoaders extends Record<string, LoaderFunction> = {}

341

> = (args: MetaArgs<Loader, ParentsLoaders>) => MetaDescriptor[];

342

343

type HeadersFunction = (args: HeadersArgs) => Headers | HeadersInit;

344

345

type LinksFunction = () => LinkDescriptor[];

346

347

// Session and cookie types

348

interface SessionData {

349

[key: string]: any;

350

}

351

352

interface Cookie {

353

readonly name: string;

354

readonly isSigned: boolean;

355

readonly expires?: Date;

356

parse(cookieHeader?: string | null): Promise<any>;

357

serialize(value: any): Promise<string>;

358

}

359

360

// Upload handler types

361

type UploadHandler = (args: UploadHandlerPart) => Promise<File | string | null | undefined>;

362

363

interface UploadHandlerPart {

364

name: string;

365

filename?: string;

366

contentType: string;

367

data: AsyncIterable<Uint8Array>;

368

}

369

```

370

371

**Error Classes:**

372

373

```typescript { .api }

374

/**

375

* Error thrown when upload part size exceeds the configured limit

376

*/

377

class MaxPartSizeExceededError extends Error {

378

constructor(field: string, maxPartSize: number);

379

}

380

```

381

382

This comprehensive server runtime API provides all the tools needed to build full-featured Remix applications with proper error handling, data loading, form processing, file uploads, and session management.