Hono & turborepo - typescript errors in vercel build

Summary

Vercel build issue after tsup completes successfully.

Cannot reproduce with typescript/webpack/tsup/other bundlers - only vercel build.

Expected vs Current

Expected: vercel builds project without any type errors

Current: vercel builds with error:

Error: src/index.ts:77:37 - error TS2339: Property 'body' does not exist on type 'Response'.

77       return c.newResponse(response.body, response);

In addition to response.body, there are also issues with request.headers and a few others from drizzle-orm. Summary of how to bypass the TS errors:

diff --git a/apps/server/src/index.ts b/apps/server/src/index.ts
index 725fd4c..afd9d37 100644
--- a/apps/server/src/index.ts
+++ b/apps/server/src/index.ts
@@ -74,7 +74,7 @@ app.use(
   async (c, next) => {
     const { matched, response } = await api.handler(c.req.raw);
     if (matched) {
-      return c.newResponse(response.body, response);
+      return c.newResponse((response as any).body, response);
     }
 
     await next();
diff --git a/packages/api/src/server/index.ts b/packages/api/src/server/index.ts
index 51c42b7..c65bf3d 100644
--- a/packages/api/src/server/index.ts
+++ b/packages/api/src/server/index.ts
@@ -68,7 +68,7 @@ export const createApi = ({
         context: await createORPCContext({
           db,
           auth,
-          headers: request.headers,
+          headers: (request as any).headers,
         }),
       });
     },
diff --git a/packages/db/src/schemas/posts.ts b/packages/db/src/schemas/posts.ts
index 139baa6..cb9e3f4 100644
--- a/packages/db/src/schemas/posts.ts
+++ b/packages/db/src/schemas/posts.ts
@@ -5,8 +5,8 @@ import { user } from './auth';
 
 export const post = pgTable('post', (t) => ({
   id: t.uuid().primaryKey().defaultRandom(),
-  title: t.varchar({ length: 256 }).notNull(),
-  content: t.text().notNull(),
+  title: t.varchar({ length: 256 }).notNull() as any,
+  content: t.text().notNull() as any,
   createdAt: t
     .timestamp({ mode: 'string', withTimezone: true })
     .notNull()
@@ -22,5 +22,5 @@ export const CreatePostSchema = v.omit(
     title: v.pipe(v.string(), v.minLength(3), v.maxLength(256)),
     content: v.pipe(v.string(), v.minLength(5), v.maxLength(512)),
   }),
-  ['id', 'createdAt', 'createdBy'],
+  ['id', 'createdAt', 'createdBy'] as any,
 );

Reproduction

  1. Fork the rt-stack project from GitHub and connect it to Vercel

  2. Try to deploy “apps/server” (the hono backend server)

  3. Observe the output:

The same issue occurs with vercel build locally.

Other details

Info Description
Source Code https://github.com/nktnet1/rt-stack
Framework Turborepo, Hono, oRPC
Project Settings
  "settings": {
    "createdAt": 1757251260212,
    "framework": "hono",
    "devCommand": null,
    "installCommand": null,
    "buildCommand": null,
    "outputDirectory": null,
    "rootDirectory": "apps/server",
    "directoryListing": false,
    "nodeVersion": "22.x"
  }
    
Everything was left as default, but I've also tried overriding the build command, etc. Issue is, my build command runs to completion, but `vercel build` seems to run something on top afterwards.

Issue reported by another user (NOTE: no new information, just for reference):

I was able to progress through this commit here:

Which has the following diff:

diff --git a/apps/server/tsconfig.json b/apps/server/tsconfig.json
index fd2efae..6fc9d24 100644
--- a/apps/server/tsconfig.json
+++ b/apps/server/tsconfig.json
@@ -2,6 +2,8 @@
   "extends": "@repo/typescript-config/base.json",
   "include": ["src"],
   "compilerOptions": {
+    "module": "es2022",
+    "lib": ["ES2022", "DOM"],
     "types": ["node"],
     "jsxImportSource": "hono/jsx"
   }

The lib: DOM part fixes the response.body and request.headers for vercel build (odd that it’s not reproducible with other tools like tsc/tsup, but somewhat understandable).


The module: es2022 part fixes the drizzle issues with:

Using TypeScript 5.9.2 (local user-provided)
Error: ../../packages/db/src/schemas/posts.ts:22:5 - error TS2322: Type 'SchemaWithPipe<readonly [StringSchema<undefined>, MinLengthAction<string, 3, undefined>, MaxLengthAction<string, 256, undefined>]>' is not assignable to type 'never'.

22     title: v.pipe(v.string(), v.minLength(3), v.maxLength(256)),
       ~~~~~

  ../../packages/db/src/schemas/posts.ts:8:3
    8   title: t.varchar({ length: 256 }).notNull(),
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The expected type comes from property 'title' which is declared here on type 'NoUnknownKeys<BuildRefine<Pick<{ id: PgColumn<{ name: "id"; tableName: "post"; dataType: "string"; columnType: "PgUUID"; data: string; driverParam: string; notNull: true; hasDefault: true; isPrimaryKey: true; isAutoincrement: false; ... 4 more ...; generated: undefined; }, {}, {}>; title: PgColumn<...>; content: PgC...'
../../packages/db/src/schemas/posts.ts:23:5 - error TS2322: Type 'SchemaWithPipe<readonly [StringSchema<undefined>, MinLengthAction<string, 5, undefined>, MaxLengthAction<string, 512, undefined>]>' is not assignable to type 'never'.

23     content: v.pipe(v.string(), v.minLength(5), v.maxLength(512)),
       ~~~~~~~

  ../../packages/db/src/schemas/posts.ts:9:3
    9   content: t.text().notNull(),
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The expected type comes from property 'content' which is declared here on type 'NoUnknownKeys<BuildRefine<Pick<{ id: PgColumn<{ name: "id"; tableName: "post"; dataType: "string"; columnType: "PgUUID"; data: string; driverParam: string; notNull: true; hasDefault: true; isPrimaryKey: true; isAutoincrement: false; ... 4 more ...; generated: undefined; }, {}, {}>; title: PgColumn<...>; content: PgC...'
../../packages/db/src/schemas/posts.ts:25:4 - error TS2322: Type 'string' is not assignable to type 'never'.

25   ['id', 'createdAt', 'createdBy'],

However, this is peculiar, because base.json which we are extending from already has "module": "es2022":

Additionally, even with the tweaks to make the build does succeed, there are still various runtime errors related to internal/workspace packages cannot being found - similar to:

Just tried it myself, but it looks like you made a change that fixed the build error. Is it working for you now?

Hey Amy,

Thank you for responding.


Yes, the tsconfig tweak in my second message made the build error go away - although it doesn’t change the fact that there are inconsistency/issues with vercel build when compared to tsc.

Ideally, they should behave the same way without requiring changes to tsconfig (from my second message).


Additionally, as noted in the third message, even if we make the build/compile errors go away, there are still many runtime errors, mostly concerning “cannot find module” when attempting to import internal/workspace packages (i.e.. @repo/db, @repo/auth, @repo/api from the hono server application).

The zero config setup for hono in a turborepo does not appear to work.

The workaround I’ve implemented for now is using a bundler like tsdown in combination with vercel primitives and prebuilt deployment

I documented my steps here:

Although this means my git repository cannot be linked to my Vercel project for automatic build + git deployment.

1 Like

I faced the exact issue, I believe this is an issue with the Vercel nodejs build script via vercel build. I might have found a hacky workaround.

When importing internal TS modules like “./myfile“, make sure you add a .js extension like import abc from "./myFile.js. This fixed my problem.

1 Like

Thanks for sharing this, Kevin!

@nktnet1 Did you manage to find a solution? Worth trying out Kevin’s suggestion.

I really don’t want to have to modify my tsconfig.json and re-write all the imports for my TypeScript files to have a .js extension just so that I can deploy to Vercel :confused:.

The project was made to also support Docker deployment + deploy to platforms other than Vercel, and using bundlers such as tsdown.

I’m content with using my other workaround for the time being, since it requires no changes to the existing code-base.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.