Describe the bug
The generated @nuxthub/db/schema entry — documented as the client-safe way to share the DB schema with the Vue app ("Sharing types with Vue") — pulls the postgres driver into the client/browser bundle, so nuxt build fails:
✗ Build failed
RollupError: postgres/src/connection.js (5:9): "performance" is not exported by
"__vite-browser-external", imported by postgres/src/connection.js
5: import { performance } from 'perf_hooks'
Root cause (this is a packaging issue in @nuxthub/core, not user code):
- The generated
@nuxthub/db/package.json has no "sideEffects": false, and postgres isn't side-effect-free, so even a dead postgres import can't be tree-shaken out of a client bundle.
- When any
server/db/schema/** file imports @nuxthub/db (the . entry — the idiomatic, and for auto-generated tables like @onmax/nuxt-better-auth's user, the only way to cross-reference aggregated tables), NuxtHub inlines db.mjs (the postgres client) into the @nuxthub/db/schema bundle. The "client-safe" entry then contains import postgres from "postgres" + bare top-level new Proxy(...) statements that no bundler will drop.
Verify on the generated output:
head -2 node_modules/@nuxthub/db/schema.mjs # import { drizzle } from "drizzle-orm/postgres-js"; import postgres from "postgres"
cat node_modules/@nuxthub/db/package.json # no "sideEffects": false
Steps to reproduce
Minimal reproduction: https://github.com/jd-solanki/reproductions/tree/nuxthub-db-schema-postgres-in-client-bundle--2026-06-24
pnpm install
pnpm build
- Build fails with the
perf_hooks / performance Rollup error above.
The repo contains: a Drizzle DB with the postgres-js driver; server/db/schema/todos.ts that references another table via import { schema } from '@nuxthub/db'; and app/app.vue (client) that does import { todos } from '@nuxthub/db/schema' + createInsertSchema(todos) (drizzle-zod).
Boundary (confirms the cause):
todos.ts imports |
schema.mjs has postgres |
nuxt build |
import { schema } from '@nuxthub/db' |
yes |
❌ fails |
import * as schema from '@nuxthub/db/schema' |
no |
✅ passes |
The second row is a workaround, not a fix — @nuxthub/db is the idiomatic / only way to reference auto-generated tables, and dead db-client code should never be able to break a client build.
Expected behavior
Importing the schema from @nuxthub/db/schema into client code (to derive validation with drizzle-zod, share types, etc.) should not pull the postgres driver into the browser bundle, and nuxt build should succeed.
Suggested fix
- Emit
"sideEffects": false in the generated @nuxthub/db/package.json (src/db/setup.ts).
- Keep the
@nuxthub/db/schema bundle genuinely postgres-free — don't inline db.mjs into it; externalize / tree-shake postgres + drizzle-orm/postgres-js from the schema entry (src/db/lib/build.ts).
Environment
nuxt 4.4.8
@nuxthub/core 0.10.7
drizzle-orm 0.45.2
drizzle-zod 0.8.3
postgres 3.4.9
node v24.13.0
pnpm 11.6.0
Describe the bug
The generated
@nuxthub/db/schemaentry — documented as the client-safe way to share the DB schema with the Vue app ("Sharing types with Vue") — pulls thepostgresdriver into the client/browser bundle, sonuxt buildfails:Root cause (this is a packaging issue in
@nuxthub/core, not user code):@nuxthub/db/package.jsonhas no"sideEffects": false, andpostgresisn't side-effect-free, so even a deadpostgresimport can't be tree-shaken out of a client bundle.server/db/schema/**file imports@nuxthub/db(the.entry — the idiomatic, and for auto-generated tables like@onmax/nuxt-better-auth'suser, the only way to cross-reference aggregated tables), NuxtHub inlinesdb.mjs(the postgres client) into the@nuxthub/db/schemabundle. The "client-safe" entry then containsimport postgres from "postgres"+ bare top-levelnew Proxy(...)statements that no bundler will drop.Verify on the generated output:
Steps to reproduce
Minimal reproduction: https://github.com/jd-solanki/reproductions/tree/nuxthub-db-schema-postgres-in-client-bundle--2026-06-24
pnpm installpnpm buildperf_hooks/performanceRollup error above.The repo contains: a Drizzle DB with the
postgres-jsdriver;server/db/schema/todos.tsthat references another table viaimport { schema } from '@nuxthub/db'; andapp/app.vue(client) that doesimport { todos } from '@nuxthub/db/schema'+createInsertSchema(todos)(drizzle-zod).Boundary (confirms the cause):
todos.tsimportsschema.mjshas postgresnuxt buildimport { schema } from '@nuxthub/db'import * as schema from '@nuxthub/db/schema'The second row is a workaround, not a fix —
@nuxthub/dbis the idiomatic / only way to reference auto-generated tables, and dead db-client code should never be able to break a client build.Expected behavior
Importing the schema from
@nuxthub/db/schemainto client code (to derive validation withdrizzle-zod, share types, etc.) should not pull thepostgresdriver into the browser bundle, andnuxt buildshould succeed.Suggested fix
"sideEffects": falsein the generated@nuxthub/db/package.json(src/db/setup.ts).@nuxthub/db/schemabundle genuinely postgres-free — don't inlinedb.mjsinto it; externalize / tree-shakepostgres+drizzle-orm/postgres-jsfrom the schema entry (src/db/lib/build.ts).Environment