Elysia and Bun serverless function fails with exit status 1 on Vercel

Problem

I am deploying a Bun + Elysia API to Vercel. The build succeeds, but every request returns a 500: FUNCTION_INVOCATION_FAILED error. Locally, the application runs perfectly with bun run src/server.ts.

Current Behavior

When accessing the deployment, the function crashes immediately:

Error: FUNCTION_INVOCATION_FAILED

Runtime Logs:

ResolveMessage {} Bun process exited with exit status: 1.
The logs above can help with debugging the issue.

Note

This is similar to a previous topic I created, but I am now using Bun and Elysia as my backend with path aliases and React for four routes.

Previous topic: Vercel Bun runtime crashes..

What I’ve Tried

  1. Confirmed entry point is a default export with no .listen() call.
  2. Verified the app runs perfectly locally using bun dev.
  3. vercel.json matches the official Elysia Vercel template.
  4. Attempted troubleshooting with AI (ChatGPT/Claude), but suggested solutions did not resolve the crash.

Questions

  1. How can I extract the actual crash error or stack trace from Vercel’s Bun runtime?
  2. Are there known incompatibilities with using path aliases and React in a backend Bun Elysia serverless environment?

Environment

  • Framework: Elysia ^1.4.22
  • Runtime: Bun 1.x (via vercel.json)
  • Plugins: @elysiajs/cors, @elysiajs/static, @elysiajs/openapi
  • Entry point: src/index.ts (default export of Elysia app)

Configuration

package.json

{
  "name": "****",
  "version": "0.0.0",
  "scripts": {
    "dev": "bun --hot src/server.ts",
    "build": "echo 'Build skipped: Bun runs TS/TSX directly'",
    "lint": "eslint . --cache --cache-location .eslintcache",
    "db:test": "bun scripts/db-select-test.ts",
    "token:getexpat": "bun scripts/get-token-expiry.ts"
  },
  "dependencies": {
    "@elysiajs/cors": "^1.4.1",
    "@elysiajs/jwt": "^1.4.0",
    "@elysiajs/openapi": "^1.4.14",
    "@elysiajs/static": "^1.4.7",
    "elysia": "^1.4.22",
    "lucide-react": "^0.564.0",
    "mssql": "^12.2.0",
    "react": "^19.2.4",
    "react-dom": "^19.2.4",
    "ws": "^8.19.0",
    "zod": "^4.3.5"
  },
  "devDependencies": {
    "@types/bun": "1.3.1",
    "@types/mssql": "^9.1.8",
    "@types/react": "^19.2.9",
    "@types/react-dom": "^19.2.3",
    "@types/ws": "^8.18.1",
    "typescript": "5.8.3"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "rootDir": "./src",
    "jsx": "react-jsx",
    "jsxImportSource": "react",
    "strict": true,
    "skipLibCheck": true,
    "allowImportingTsExtensions": false,
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"],
      "@@/*": ["./*"]
    }
  },
  "include": ["src"],
  "exclude": ["node_modules"]
}

vercel.json

{
  "bunVersion": "1.x"
}

Source Code

src/index.ts

import { ALLOWED_ORIGINS } from "@/lib/constants";
import { MyError, errors } from "@/lib/errors";
import { serverGate } from "@/middleware/server-gate";
import aboutRouter from "@/routes/about";
import healthzRouter from "@/routes/healthz";
import homeRouter from "@/routes/home";
import loginRouter from "@/routes/login";
import v1Router from "@/routes/v1/v1.router";
import { cors } from "@elysiajs/cors";
import { openapi } from "@elysiajs/openapi";
import { staticPlugin } from "@elysiajs/static";
import { Elysia } from "elysia";
import { ZodError } from "zod";

const app = new Elysia()
  .error({
    MyError,
  })
  .use(
    openapi({
      path: "/openapi",
      documentation: {
        info: {
          title: "API",
          version: "v1"
        }
      }
    })
  )
  .onError(({ error, status, code }) => {
    // Error handling logic
  });

app.use(cors({ /* ... */ }));
app.use(staticPlugin({ assets: "public", prefix: "/" }));
app.use(loginRouter);
app.use(homeRouter);
app.use(aboutRouter);
app.use(healthzRouter);
app.use(v1Router);

export default app;

src/routes/login.ts

import { Login } from "@/components/Login";
import { getAzureSQLDbPool } from "@/lib/db";
import { loginSchema } from "@/schemas/login";
import { Elysia } from "elysia";
import React from "react";
import { renderToReadableStream } from "react-dom/server.browser";
import z from "zod";

const router = new Elysia({ prefix: "/login" })

router.get("", async () => {
    const html = React.createElement(Login, { title: `Login | Record log API` });
    const stream = await renderToReadableStream(html);
    return new Response(stream, {
        headers: { "Content-Type": "text/html" }
    });
});

export default router;

src/components/Login.tsx

import { Lock, User } from "lucide-react";

type Props = {
  title: string;
};

export function Login({ title }: Props): React.ReactElement {
  return (
    <html lang="en">
      <head>
        <meta charSet="UTF-8" />
        <title>{title}</title>
      </head>
      <body>
        <div className="login-container">
          <form method="POST">
            <input name="username" placeholder="Username" required />
            <input name="password" type="password" placeholder="Password" required />
            <button type="submit">Sign In</button>
          </form>
        </div>
      </body>
    </html>
  );
}

using path alias make this error

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