-
Notifications
You must be signed in to change notification settings - Fork 743
Description
👋 everyone
We are building a podcast analytics platform using:
- Deno 2.x
- Fresh 2.x (with Vite integration)
- MongoDB via jsr:@db/mongo@^0.34.0
We are new to this whole ecosystem, but we have really enjoyed the experience so far 🫶
But now, we are stuck on this issue:
Project Structure
deno.json (relevant parts):
{
"imports": {
"mongodb-deno": "jsr:@db/mongo@^0.34.0",
"fresh": "jsr:@fresh/core@^2.2.0",
"@fresh/plugin-vite": "jsr:@fresh/plugin-vite@^1.0.8",
// ... other imports
}
}
vite.config.ts:
import { defineConfig } from "vite";
import { fresh } from "@fresh/plugin-vite";
export default defineConfig({
plugins: [fresh()],
ssr: {
external: ["echarts", "mongodb-deno"],
}
});
util/db.ts (database connection):
import { Database, MongoClient } from "mongodb-deno";
let client: MongoClient | null = null;
export async function getDb(): Promise<Database> {
if (!client) {
client = new MongoClient();
await client.connect(MONGODB_URI);
}
return client.database(MONGODB_DB);
}
routes/index.tsx (imports and uses db.ts):
import { define } from "@/utils.ts";
import { getDb } from "@/util/db.ts";
export const handler = define.handlers({
async GET(ctx) {
const db = await getDb();
// ... fetch data and render
},
});
The Problem
Build works fine:
deno task build ✅ Succeeds
Dev server starts, but fails when accessing any route:
deno task dev
When accessing http://localhost:5173/:
Error: Cannot find module 'mongodb-deno' imported from '/Users/.../util/db.ts'
at fetchModule (/Users/.../npm/registry.npmjs.org/vite/7.3.0/dist/node/chunks/config.js:33979:34)
What we've Tried
- Adding mongodb-deno to ssr.external in vite.config.ts
- Result: Still tries to load it
- Using direct JSR imports instead of import map alias:
import { Database, MongoClient } from "jsr:@db/mongo@^0.34.0";
- Result: Error: Failed to load url jsr:@db/mongo@^0.34.0 ... Does the file exist?
- Creating a shim file and using Vite alias:
resolve: {
alias: {
"mongodb-deno": resolve("./util/mongodb-deno-shim.ts"),
},
}
- Result: Same error, Vite still can't load JSR imports
- Custom Vite plugin to mark JSR imports as external:
{
name: "jsr-external",
resolveId(id) {
if (id.startsWith("jsr:")) {
return { id, external: true };
}
},
}
- Result: Breaks Fresh's own JSR dependencies
The Core Issue (As far as we understand)
Vite's SSR module runner in dev mode tries to process mongodb-deno even though it's marked as external. It cannot resolve:
- The Deno import map alias (mongodb-deno → jsr:@db/mongo)
- Direct JSR package URLs (jsr:@db/mongo@^0.34.0)
The build works because it only bundles client code and keeps server code external. But in dev mode, when a route handler imports util/db.ts, Vite's SSR tries to process it and fails.
Questions we are facing:
- What's the recommended way to use JSR packages (especially database drivers) in Fresh 2.x routes?
- Should server-only imports like MongoDB drivers be handled differently in Fresh 2.x + Vite?
- Is there a Vite config or Fresh plugin option we're missing that would allow Deno to handle its own import resolution during SSR?
- Are there any working examples of Fresh 2.x projects using MongoDB or other JSR database drivers?
Additional Context
- Only fails during deno task dev when accessing routes
- We also had to work around a broken transitive dependency (@lucsoft/web-bson) which we fixed with an import map override
🙏 Any guidance would be greatly appreciated! Thank you!