Connect a MongoDB driver
Nimbus speaks the MongoDB wire protocol natively. In this tutorial you run
a Nimbus server, connect the official Node.js mongodb driver to it,
insert a document, and query it back. No codegen, no schema files — the
stock driver is the client.
Every Nimbus server serves the MongoDB endpoint by default — nimbus start and nimbus dev alike (--no-mongodb switches it off, and
embedders opt in through the API — see
the embedding alternative below). In an app
directory, nimbus dev goes further: when it sees a mongodb dependency
in your package.json, it writes a ready-to-use connection URL to your
app’s .env.local as NIMBUS_MONGODB_URL, so the client below collapses
to new MongoClient(process.env.NIMBUS_MONGODB_URL). The steps below use
nimbus start with explicit credentials — the long-lived server shape.
Everything the driver sees is plain MongoDB.
What you need
Section titled “What you need”- The
nimbusbinary (install). - Node.js 22 or later for the client side.
1. Start the server
Section titled “1. Start the server”The endpoint requires SCRAM-SHA-256 credentials; the password is env-only so it never appears in process listings:
NIMBUS_MONGODB_PASSWORD=app-secret \ nimbus start --mongodb-username app-userThe server logs both listeners — the HTTP API on 127.0.0.1:8080 and the
MongoDB endpoint on 127.0.0.1:27017. If another process already holds
27017, the listener is skipped with a warning — pass --mongodb-port
to pin a different port (a busy explicit port is a hard error instead of
a skip).
Without credential flags, the server still serves the endpoint: it
generates a credential pair on first boot and persists it at
wire-credentials.json (owner-only, 0600) in its data directory.
nimbus dev is the shape that hands those generated credentials to your
app via .env.local.
The MongoDB endpoint always binds to loopback. The server refuses to bind it to a network-reachable address — front it with a TLS-terminating proxy for remote access.
2. Create the client
Section titled “2. Create the client”In a separate directory, set up a Node project with the official driver:
mkdir mongo-client && cd mongo-clientnpm init -ynpm install mongodbCreate index.mjs:
import { MongoClient } from "mongodb";
const client = new MongoClient( "mongodb://app-user:app-secret@127.0.0.1:27017/myapp",);await client.connect();
const messages = client.db("myapp").collection("messages");
await messages.insertOne({ author: "Ada", body: "Hello from Nimbus" });const docs = await messages.find().toArray();console.log(docs);
await client.close();Two parts of that connection string matter:
app-user:app-secretare the SCRAM-SHA-256 credentials the server was started with. Every data operation requires them.- The string names exactly one host. Nimbus is a single endpoint, not a
replica set — never pass a
replicaSetoption. With a single host the driver connects directly; addingdirectConnection=trueis harmless but not required.
3. Run it
Section titled “3. Run it”node index.mjsYou see your document come back, with the _id the server assigned:
[ { _id: ..., author: 'Ada', body: 'Hello from Nimbus' } ]Embedding alternative
Section titled “Embedding alternative”Running Nimbus as a Rust library? Enable the same endpoint with
ServeOptions:
use nimbus_server::{MongoDbAuthConfig, MongoDbConfig, ServeOptions};
let auth = MongoDbAuthConfig::new("app-user".into(), "app-secret".into());let options = ServeOptions::new(engine) .with_mongodb(MongoDbConfig::localhost(27017, auth));What just happened
Section titled “What just happened”- Connecting to the database
myapprouted you to the Nimbus tenantmyapp. The tenant was created automatically on first write — see tenant isolation for the mapping rules. - The collection
messageswas created on first insert. Schema is optional: a collection accepts any document shape. - The write went through the same engine as Nimbus’s HTTP API. A document inserted through the MongoDB driver is immediately visible to every other Nimbus surface in the same tenant, and vice versa.
Next steps
Section titled “Next steps”- Driver examples — CRUD, aggregation, transactions, and other languages.
- Supported drivers — what works beyond Node.js.
- Supported operations — the exact command, filter, and update surface.