diff --git a/.changeset/tiny-gifts-wash.md b/.changeset/tiny-gifts-wash.md
new file mode 100644
index 0000000000..7b0a67767e
--- /dev/null
+++ b/.changeset/tiny-gifts-wash.md
@@ -0,0 +1,5 @@
+---
+"react-router": patch
+---
+
+Update `ServerBuild` type to ensure compatibility with TypeScript's `exactOptionalPropertyTypes` option
diff --git a/contributors.yml b/contributors.yml
index dd0d8c165f..4cb0e8c96a 100644
--- a/contributors.yml
+++ b/contributors.yml
@@ -303,6 +303,7 @@
 - SkayuX
 - skratchdot
 - smithki
+- smorimoto
 - soartec-lab
 - sorokya
 - sorrycc
diff --git a/integration/typegen-test.ts b/integration/typegen-test.ts
index 1460c528ab..1115315c93 100644
--- a/integration/typegen-test.ts
+++ b/integration/typegen-test.ts
@@ -490,6 +490,30 @@ test.describe("typegen", () => {
       expect(proc.status).toBe(0);
     });
 
+    test("works with tsconfig 'exactOptionalPropertyTypes' set to 'true'", async () => {
+      const cwd = await createProject({
+        "vite.config.ts": viteConfig,
+        "app/routes.ts": tsx`
+          import { type RouteConfig } from "@react-router/dev/routes";
+          export default [] satisfies RouteConfig;
+        `,
+        "app/handler.ts": tsx`
+          import { createRequestHandler } from "react-router";
+          import * as serverBuild from "virtual:react-router/server-build";
+          export default createRequestHandler(serverBuild);
+        `,
+      });
+
+      const tsconfig = await fse.readJson(path.join(cwd, "tsconfig.json"));
+      tsconfig.compilerOptions.exactOptionalPropertyTypes = true;
+      await fse.writeJson(path.join(cwd, "tsconfig.json"), tsconfig);
+
+      const proc = typecheck(cwd);
+      expect(proc.stdout.toString()).toBe("");
+      expect(proc.stderr.toString()).toBe("");
+      expect(proc.status).toBe(0);
+    });
+
     test("dynamic import matches 'createRequestHandler' function argument type", async () => {
       const cwd = await createProject({
         "vite.config.ts": viteConfig,
diff --git a/packages/react-router-dev/typegen/index.ts b/packages/react-router-dev/typegen/index.ts
index 342f27f808..5db028c324 100644
--- a/packages/react-router-dev/typegen/index.ts
+++ b/packages/react-router-dev/typegen/index.ts
@@ -152,7 +152,7 @@ function register(ctx: Context) {
 
 const virtual = ts`
   declare module "virtual:react-router/server-build" {
-    import { ServerBuild } from "react-router";
+    import type { ServerBuild } from "react-router";    import { ServerBuild } from "react-router";
     export const assets: ServerBuild["assets"];
     export const assetsBuildDirectory: ServerBuild["assetsBuildDirectory"];
     export const basename: ServerBuild["basename"];
diff --git a/packages/react-router/lib/server-runtime/build.ts b/packages/react-router/lib/server-runtime/build.ts
index 1fd78abdb7..9502fd4150 100644
--- a/packages/react-router/lib/server-runtime/build.ts
+++ b/packages/react-router/lib/server-runtime/build.ts
@@ -24,14 +24,20 @@ export interface ServerBuild {
   };
   routes: ServerRouteManifest;
   assets: AssetsManifest;
-  basename?: string;
+  // `| undefined` is required to ensure compatibility with TypeScript's
+  // `exactOptionalPropertyTypes` option
+  basename?: string | undefined;
   publicPath: string;
   assetsBuildDirectory: string;
   future: FutureConfig;
   ssr: boolean;
-  unstable_getCriticalCss?: (args: {
-    pathname: string;
-  }) => OptionalCriticalCss | Promise<OptionalCriticalCss>;
+  unstable_getCriticalCss?:
+    | ((args: {
+        pathname: string;
+      }) => OptionalCriticalCss | Promise<OptionalCriticalCss>)
+    // `| undefined` is required to ensure compatibility with TypeScript's
+    // `exactOptionalPropertyTypes` option
+    | undefined;
   /**
    * @deprecated This is now done via a custom header during prerendering
    */