Skip to content

Hono + Turborepo example is broken for monorepos — missing build step / workspace:* packages not resolved #1213

@stefan-garofalo

Description

@stefan-garofalo

The Hono + Turborepo example in this repo assumes a no-build flow and therefore fails for projects that use local workspace packages (workspace:*). Vercel’s build/deploy environment does not reliably resolve Turborepo workspace packages at deploy time, so deployments of a Hono app inside a monorepo will fail with missing-module / module-not-found errors unless the example includes a build step that produces a self-contained artifact.

What I observed

Why this happens (short)

  • Vercel’s serverless function deployment expects dependencies to be installable/resolvable during the build step. When packages are referenced with workspace:* inside a Turborepo, Vercel’s install/build may not materialize those local packages in the deployed environment unless you explicitly produce a single deployable artifact that bundles the app + local packages.

Workaround / working solution I used

I fixed this in my project by adding a build step that bundles the backend and all local workspace packages into a single CommonJS file using Rspack, and then exposing that bundle via a small Vercel entrypoint. This avoids relying on Vercel to resolve workspace packages at deploy time.

Example of what I added (summary)

  • Build with Rspack to produce a single bundle: apps/backend/dist/index.cjs
  • Mark native modules (e.g. @libsql/client) external in the bundler to avoid runtime/native bundling problems
  • Add a Vercel entrypoint file that re-exports the bundle: apps/backend/api/index.js
  • Add vercel.json with a build and a route pointing to the entrypoint

Short example snippets (adapt to your setup)

rspack config (apps/backend/rspack.config.js)

const path = require('path');

module.exports = {
  mode: 'production',
  target: 'node',
  entry: path.resolve(__dirname, 'src', 'index.ts'),
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index.cjs',
    library: { type: 'commonjs2' }
  },
  resolve: { extensions: ['.ts', '.js', '.json'] },
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: 'ts-loader', // or use swc/esbuild loader
        exclude: /node_modules/
      }
    ]
  },
  // mark native-like modules as external (adjust to your deps)
  externals: {
    '@libsql/client': '@libsql/client'
  }
};

Vercel entrypoint (apps/backend/api/index.js)

// simple wrapper that Vercel uses as the serverless entry
const server = require('../dist/index.cjs');
module.exports = server.default || server;

vercel.json (root)

{
  "version": 2,
  "builds": [
    { "src": "apps/backend/api/index.js", "use": "@vercel/node" }
  ],
  "routes": [
    { "src": "/(.*)", "dest": "/apps/backend/api/index.js" }
  ]
}

Suggested changes for the examples repo

  • Update the Hono + Turborepo example to include a build step that bundles the backend and local workspace packages (provide an example using Rspack or esbuild).
  • Add an example vercel.json and small entrypoint file (apps//api/index.js) showing how to route to the bundled artifact.
  • Update the README documenting:
    • why a build/bundling step is necessary for turborepo monorepos,
    • that the bundle may need to be CommonJS in practice for some native/legacy deps,
    • a minimal recommended workflow (build locally / as part of CI / via Turborepo pipeline) before deploy.
  • Optionally provide multiple bundler examples (rspack, esbuild) or an explanation of when each is appropriate.

References / working example

Offer

I can open a PR against this repo to update the Hono + Turborepo example (add a build step, include an rspack/esbuild example, vercel.json and README notes) and link the working foodwise example as a reference. Let me know if you’d accept that kind of PR and which bundler you’d prefer to include as the canonical example.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions