You're looking at RavenDB Node.js Embedded Server release. It lets you to spin-up RavenDB server locally in no-time using friendly API.
RavenDB is a NoSQL database that fuses extreme performance with ease-of-use, offering above the roof developer experience. Learn more at https://ravendb.net or visit our GitHub repository.
npm install ravendb-embeddedpnpm add ravendb-embeddedyarn add ravendb-embedded ravendbThe ravendb client is a peer
dependency — npm and pnpm install it automatically. Yarn does not.
No further setup is required: on the first startServer() call the package
downloads the RavenDB server binaries for your platform automatically
and caches them per version, as long as
licensing.eulaAccepted = true is set. Download progress is printed to stderr
so the first run never looks like a hang — inject a logger to redirect or
silence it. Subsequent starts reuse the cache and make no network calls.
See Server download details for cache location,
version pinning, opt-out and manual installation.
Check the runtime prerequisites in our docs. In short:
- When only
Raven.Server.dllis present (no native executable), a .NET runtime matchingserverOptions.frameworkVersionmust be installed. - Extraction uses the system
tar(ships with Windows 10+, Linux and macOS); without it, install the server manually (see below).
import { embeddedServer, ServerOptions } from "ravendb-embedded";
const options = new ServerOptions({
licensing: { eulaAccepted: true }
});
await embeddedServer.startServer(options);
const store = await embeddedServer.getDocumentStore("Embedded");
const session = store.openSession();
// Your code here
await embeddedServer.dispose();embeddedServer is a shared singleton.
Instantiate new EmbeddedServer() for isolated servers (e.g. tests).
Runnable samples live in examples/.
EULA semantics:
licensing.eulaAcceptedgates the automatic binaries download and is forwarded to the server as--License.Eula.Accepted— enforcement of the flag itself is up to the server. A manual install inserverDirectoryis run as-is.
Options are snapshotted:
startServer()takes a copy of theServerOptionsobject. The caller's object is never mutated (the resolved download directory and server URL stay internal — usegetServerUri()), and editing it after the call has no effect on the running server.
Start semantics:
startServer()awaits the full server startup, so configuration errors surface immediately at the call site.
startServer() also accepts an AbortSignal to cancel a startup in flight —
the spawned process is torn down immediately:
await embeddedServer.startServer(options, AbortSignal.timeout(30_000));The server watches its parent process (--Embedded.ParentProcessId) and exits
when it dies — that safety net is always on. For a graceful shutdown when the
host receives SIGINT/SIGTERM (Ctrl-C, kill, container stop), opt in:
options.installSignalHandlers = true;On a signal the server is disposed first; the signal is then re-raised only
when your app has no handler of its own, so the process still exits with the
conventional exit code — apps with their own handlers keep full control.
beforeExit also disposes the server. This is opt-in because it changes
process-global signal behavior.
class Category {
public id?: string;
public name?: string;
}
class Product {
public id?: string;
public name?: string;
public category?: string;
public unitsInStock?: number;
}
const session = store.openSession(); // Open a session on the 'Embedded' database
const category = new Category();
category.name = "Database Category";
await session.store(category); // Assign an 'Id' and collection (Categories)
// and start tracking an entity
const product = new Product();
product.name = "RavenDB Database";
product.category = category.id;
product.unitsInStock = 10;
await session.store(product); // Assign an 'Id' and collection (Products)
// and start tracking an entity
await session.saveChanges(); // Send to the Server
// one request processed in one transactionconst session = store.openSession(); // Open a session on the 'Embedded' database
const productNames = await session
.query<Product>({ collection: "Products" }) // Query for Products
.whereGreaterThan("unitsInStock", 5) // Filter
.skip(0).take(10) // Page
.selectFields<string>("name") // Project
.all(); // Materialize queryThe server certificate must be a PKCS#12 (PFX) file — RavenDB loads
Security.Certificate.Path with the .NET certificate loader, which does not
parse PEM (a PEM file fails at startup with "Unable to find the private key
in the provided certificate"). Node in turn cannot parse PKCS#12, so the
thumbprint cannot be computed here — pass it explicitly:
options.secured("/path/to/cert.pfx", "password", "<server cert thumbprint>");
// Self-signed certificate: pass its PEM as the CA bundle so the client trusts it:
options.secured("/path/to/cert.pfx", "password", "<thumbprint>", "/path/to/cert.pem");Convert a PEM certificate + key to PFX and compute the thumbprint with:
openssl pkcs12 -export -out cert.pfx -inkey key.pem -in cert.pem -passout pass:password
openssl x509 -in cert.pem -fingerprint -sha1 -noout # strip the colons(or in PowerShell: (Get-PfxCertificate cert.pfx).Thumbprint; from Node, with
a PEM copy of the certificate:
new crypto.X509Certificate(pem).fingerprint.replace(/:/g, "")).
The certificate must carry keyUsage=digitalSignature and
extendedKeyUsage=serverAuth (RavenDB validates both); add clientAuth when
the same certificate is used as the client certificate — which is exactly what
secured() does: the PFX also authenticates the document stores.
When the server certificate lives in a vault or HSM instead of a file, let the
server obtain it by running an external program
(--Security.Certificate.Load.Exec):
options.securedWithExec(
"vault-cli", // program the server runs
"get --cert ravendb-server", // its arguments (raw string)
"<server cert thumbprint>", // required — the cert is loaded by the server
"/path/to/client-cert.pem", // client certificate for document stores
undefined, // client certificate password, if any
"/path/to/ca.pem" // CA bundle the client should trust
);The client certificate's thumbprint is registered as the server admin
certificate. For a PEM client certificate it is computed automatically; for
PFX the serverCertThumbprint value is used as a fallback (correct when the
same certificate secures the server and authenticates the client).
The ravendb Node client exposes no certificate-validation hook (its auth
options are only type/certificate/password/ca), so pinning the server
certificate by thumbprint is not available in this package. Trust the
server through the ca option instead: for a self-signed server certificate,
its own PEM is the CA — pass it as caCertificatePath (shown above). The
serverCertThumbprint parameters exist for the PFX fallback described above.
Silent by default, with one exception: automatic server download progress goes
to stderr, so a ~350 MB first-run download never looks like a hang. Inject any
logger implementing debug/info/warn to redirect everything — or
noopLogger for full silence:
import type { Logger } from "ravendb-embedded";
options.logger = {
debug: message => console.debug(message),
info: message => console.info(message),
warn: (message, error) => console.warn(message, error)
};Log points: server start (PID), graceful shutdown, kill fallback, document store creation, database-already-exists — plus download progress.
-
Cache location:
%LOCALAPPDATA%\ravendb-embedded\{version}-{platform}on Windows,$XDG_CACHE_HOME/ravendb-embedded/{version}-{platform}(default~/.cache/ravendb-embedded/...) elsewhere. Override withserverOptions.downloadCacheDirectoryorRAVENDB_EMBEDDED_CACHE_DIR. -
Version:
serverOptions.serverVersionorRAVENDB_EMBEDDED_SERVER_VERSION. The default is pinned to the server release this package version was built and tested against (exported asDEFAULT_SERVER_VERSION; the package version tracks it), so builds are deterministic. Set"latest"to opt into the current stable release instead — it resolves once and then stays pinned in the cache (latest-*.versionmarker), so later runs are offline and deterministic; delete the marker to move. -
Opt out: set
serverOptions.downloadServer = falseorRAVENDB_EMBEDDED_SKIP_DOWNLOAD=1. -
Manual installation always wins: extract the distribution from https://ravendb.net/download into
./RavenDBServer(or any directory passed viaserverOptions.serverDirectory) — the zip can be extracted as-is, its nestedServer/subdirectory is detected automatically. When binaries are present, the network is never touched. A customserverDirectoryis treated as user-managed and is never downloaded into. -
Pre-warm the cache (Docker images, CI):
pnpm ravendb install # pinned default version (the release this package was tested against) pnpm ravendb install 7.2.4 # specific version (or "latest") pnpm ravendb install 7.2.4 --dir /path/to/cache
(
npx ravendb install .../yarn ravendb install ...work the same way.) -
Integrity: downloads run over HTTPS and are verified against the response
Content-Length(truncated downloads are rejected). RavenDB does not publish a checksum manifest for its distributions yet, so a stronger check is not possible. -
Clear the cache (old versions accumulate, one distribution per version+platform):
pnpm ravendb clear-cache --keep 7.2.5 --dir /path/to/cache
The command asks for confirmation before removing anything; pass
--yesto skip the prompt (required in non-interactive sessions such as CI). Or from code:ServerDownloader.clearCache({ keepVersions: ["7.2.5"] }).
- Embedded Server Guide - https://ravendb.net/articles/building-a-beer-vending-machine-program-with-ravendb-embedded-server 🛣️
- Documentation - https://ravendb.net/docs/article-page/server/embedded 🎒
- Code Samples - https://demo.ravendb.net/ 🧑💻
- RavenDB's Discord - https://discord.gg/ravendb 🍻
- Articles & guides - https://ravendb.net/articles 📰
- YouTube - https://www.youtube.com/@ravendb_net 🍿
- Blog - https://ayende.com/blog/ 🧑💻
npm run test:unit— no server needednpm run test:integration— requires binaries in./RavenDBServer; the secured scenario additionally requiresopensslon PATH (skipped otherwise); the download scenario is opt-in viaRAVENDB_EMBEDDED_TEST_DOWNLOAD=1(fetches a full ~350 MB distribution)
- Submit an issue - https://github.com/ravendb/ravendb/issues
- GitHub Discussions - https://github.com/ravendb/ravendb/discussions
- Contributing rules - https://github.com/ravendb/ravendb/blob/v7.2/CONTRIBUTING.md