Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
305 changes: 305 additions & 0 deletions EXPERIMENTAL_FEATURES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,305 @@
# MongoDB Node.js Driver - Experimental Features

This report documents all experimental features in the MongoDB Node.js Driver. The driver contains **34 experimental annotations** across 8 major feature categories.

> [!WARNING]
> Experimental features may change in any release, including patches and minors, and are not covered by the driver's semver guarantees. Updates can change runtime behavior or break TypeScript compilation, and may require source changes before you can upgrade.

---

## Summary

| Feature | Description | Introduced in |
|---------|-------------|---------------|
| [Runtime Adapters](#runtime-adapters) | Custom runtime module implementations | v7.2.0 |
| [Queryable Encryption Text Search](#queryable-encryption-text-search) | Text search on encrypted fields | v6.19.0 |
| [AbortSignal Support](#abortsignal-support) | Cancel operations using `AbortController` | v6.13.0 |
| [Explicit Resource Management](#explicit-resource-management) | Automatic cleanup using `Symbol.asyncDispose` | v6.9.0 |
| [Timeout Management](#timeout-management) | Control operation timeouts with `timeoutMS` | v6.6.0 |
| [Client-Side Encryption Key Management](#client-side-encryption-key-management) | Custom key material and rewrap APIs | v6.0.0 |
| [Strict TypeScript Types](#strict-typescript-types) | Enhanced type safety for filters and updates | v5.0.0 |
| [Encrypted Fields](#encrypted-fields) | Schema for encrypted collections | v4.6.0 |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of these features have been experimental for a while. It would be nice to explain what's happening with some of these "older" features: will we remove the experimental label? If so, when? And how do we pick which features will be experimental vs "core"?


---

## Feature Descriptions
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, these features should be ordered the same as the table above.


### Runtime Adapters

**Description**: Allows providing custom implementations of Node.js runtime modules to the driver. This is useful both for customizing how the driver uses standard modules within a Node.js runtime (for example, supplying a custom DNS resolver) and for running the driver in non-Node.js JavaScript environments.

**Types**:

#### `RuntimeAdapters`
**Source**: [src/runtime_adapters.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/runtime_adapters.ts)

Interface for providing custom runtime module implementations.

#### `OsAdapter`
**Source**: [src/runtime_adapters.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/runtime_adapters.ts)

Represents the required functionality from the Node.js `os` module.

Comment thread
RaschidJFR marked this conversation as resolved.
**Available On**:
- `MongoClientOptions.runtimeAdapters` - [src/mongo_client.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/mongo_client.ts)

**Example**:
```typescript
// Provide custom OS module implementation
const client = new MongoClient(url, {
runtimeAdapters: {
os: {
release: () => 'custom-release',
platform: () => 'linux',
arch: () => 'x64',
type: () => 'Linux'
}
}
});
```

---

### Queryable Encryption Text Search

> [!NOTE]
> This feature is a Public Technical Preview

**Option**: `textOptions`
**Type**: `TextQueryOptions`
**Location**: `ClientEncryptionEncryptOptions`
**Source**:
- Option in `ClientEncryptionEncryptOptions` - [src/client-side-encryption/client_encryption.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/client-side-encryption/client_encryption.ts)
- Interface `TextQueryOptions` - [src/client-side-encryption/client_encryption.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/client-side-encryption/client_encryption.ts)

**Description**: Options for Queryable Encryption fields supporting text queries. Only valid when the encryption algorithm is set to `TextPreview`.

**Example**:
```typescript
const encrypted = await encryption.encrypt(value, {
algorithm: 'TextPreview',
keyId: dataKeyId,
textOptions: {
// Text search configuration options
}
});
```

---

### AbortSignal Support
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mention the introduced-in version somewhere in this section.


**Type**: `Abortable`
**Source**: [src/mongo_types.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/mongo_types.ts)

**Description**: Allows using `AbortController` to abort asynchronous operations. The `signal.reason` value is used as the error thrown.

**Example**:
```typescript
const controller = new AbortController();
const { signal } = controller;

// Abort operation after 5 seconds
setTimeout(() => controller.abort(new Error('Operation timeout')), 5000);

await collection.find({}, { signal }).toArray();
```

> [!WARNING]
> If an abort signal aborts an operation while the driver is writing to the underlying socket or reading the response from the server, the socket will be closed. If signals are aborted at a high rate during socket read/writes, this can lead to a high rate of connection reestablishment — programmatically aborting hundreds of operations can empty the driver's connection pool.
>
> `AbortSignal` is best suited for human-interactive interruption (e.g., Ctrl-C) where the cancellation frequency is reasonably low. Mitigation of this limitation is tracked in [NODE-6062](https://jira.mongodb.org/browse/NODE-6062) (`timeoutMS` expiration has the same limitation).

---

### Explicit Resource Management

> [!WARNING]
> Experimental until [TC39](https://github.com/tc39/proposal-explicit-resource-management) proposal completion

**Description**: Native support for JavaScript's explicit resource management using `Symbol.asyncDispose`. This feature enables automatic cleanup of resources using the `await using` syntax.

**Available On**:
- `MongoClient` - [src/mongo_client.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/mongo_client.ts)
- `ClientSession` - [src/sessions.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/sessions.ts)
- `ChangeStream` - [src/change_stream.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/change_stream.ts)
- All cursor types (`AbstractCursor`, `FindCursor`, `AggregationCursor`, etc.) - [src/cursor/abstract_cursor.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/cursor/abstract_cursor.ts)

**Example**:
```typescript
// Automatic cleanup when scope exits
await using client = new MongoClient(url);
await using session = client.startSession();
// No need to call client.close() or session.endSession()
```

---

### Timeout Management

**Option**: `timeoutMS`

**Description**: Specifies the time (in milliseconds) an operation will run until it throws a timeout error. `timeoutMS` can be configured at the client, database, collection, session, transaction, and per-operation levels, with narrower scopes overriding broader ones.

See [Limit Server Execution Time (CSOT) — MongoDB Node.js Driver Docs](https://www.mongodb.com/docs/drivers/node/current/connect/connection-options/csot/) for the full inheritance/override rules, cursor-specific behavior, Client Encryption interactions, and code examples.

#### Cursor Timeout Modes

> [!NOTE]
> This configures how the CSOT `timeoutMS` above is applied to cursors.

**Type**: `CursorTimeoutMode`
**Source**:
- Constant definition - [src/cursor/abstract_cursor.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/cursor/abstract_cursor.ts)
- Type definition - [src/cursor/abstract_cursor.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/cursor/abstract_cursor.ts)
- Option in `AbstractCursorOptions` - [src/cursor/abstract_cursor.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/cursor/abstract_cursor.ts)
- Option in `RunCursorCommandOptions` - [src/cursor/run_command_cursor.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/cursor/run_command_cursor.ts)

**Values**:
- `'cursorLifetime'` - Timeout applies to the entire cursor lifetime
- `'iteration'` - Timeout applies to each `cursor.next()` call

**Default Behavior**:
- **Non-tailable cursors**: `'cursorLifetime'`
- **Tailable cursors**: `'iteration'` (since tailable cursors can have arbitrarily long lifetimes)

#### GridFS Streams

> [!NOTE]
> Applies the CSOT `timeoutMS` above to GridFS upload and download streams as a per-stream lifetime.

**Options**:
- `timeoutMS` in `GridFSBucketReadStreamOptions` — [src/gridfs/download.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/gridfs/download.ts). Limits the lifetime of a download stream; if any async operation is in progress when the timeout expires, the stream throws a timeout error.
- `timeoutMS` in `GridFSBucketWriteStreamOptions` — [src/gridfs/upload.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/gridfs/upload.ts). Limits the lifetime of an upload stream.

---

### Client-Side Encryption Key Management

**Description**: Experimental APIs for creating and rewrapping CSFLE data keys.

#### Custom Key Material

**Option**: `keyMaterial`
**Type**: `Buffer | Binary`
**Location**: `ClientEncryptionCreateDataKeyProviderOptions`
**Source**: [src/client-side-encryption/client_encryption.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/client-side-encryption/client_encryption.ts)

**Description**: Allows providing custom key material when creating data keys, giving more control over the encryption key generation process.

**Example**:
```typescript
const encryption = new ClientEncryption(client, {
keyVaultNamespace: 'encryption.__keyVault',
kmsProviders: { local: { key: localMasterKey } }
});

const dataKeyId = await encryption.createDataKey('local', {
keyMaterial: customKeyBuffer // Experimental option
});
```

#### RewrapManyDataKey API

**Interfaces**:
- `ClientEncryptionRewrapManyDataKeyProviderOptions` - [src/client-side-encryption/client_encryption.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/client-side-encryption/client_encryption.ts)
- `ClientEncryptionRewrapManyDataKeyResult` - [src/client-side-encryption/client_encryption.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/client-side-encryption/client_encryption.ts)

**Description**: Experimental API for rewrapping multiple data keys in a single operation, useful for key rotation scenarios.

**Interface Definition**:
```typescript
interface ClientEncryptionRewrapManyDataKeyProviderOptions {
provider: ClientEncryptionDataKeyProvider;
masterKey?: AWSEncryptionKeyOptions | AzureEncryptionKeyOptions |
GCPEncryptionKeyOptions | KMIPEncryptionKeyOptions | undefined;
}

interface ClientEncryptionRewrapManyDataKeyResult {
/** The result of rewrapping data keys. If unset, no keys matched the filter. */
bulkWriteResult?: BulkWriteResult;
}
```

---

### Strict TypeScript Types

**Description**: Provides stricter type checking for MongoDB operations with better TypeScript inference for nested paths and type safety.

**Types**:

#### `StrictFilter<TSchema>`
**Source**: [src/mongo_types.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/mongo_types.ts)

Provides strict type checking for filter predicates with proper nested path support.

#### `StrictMatchKeysAndValues<TSchema>`
**Source**: [src/mongo_types.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/mongo_types.ts)

Ensures type-safe matching of keys and values in update operations.

#### `StrictUpdateFilter<TSchema>`
**Source**: [src/mongo_types.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/mongo_types.ts)

Provides strict typing for update operators (`$set`, `$inc`, `$push`, etc.).

**Example**:
```typescript
interface User {
name: string;
age: number;
address: {
city: string;
zip: number;
};
}

const collection: Collection<User> = db.collection('users');

// Type-safe filter with nested paths
const filter: StrictFilter<User> = {
'address.city': 'New York' // ✓ Valid
// 'address.city': 123 // ✗ Compile error: number not assignable to string
};

// Type-safe update
const update: StrictUpdateFilter<User> = {
$set: { age: 30 }, // ✓ Valid
// $set: { age: 'thirty' } // ✗ Compile error
};
```

---

### Encrypted Fields

**Option**: `encryptedFields`
**Type**: `Document`

**Available On**:
- `CreateCollectionOptions` - [src/operations/create_collection.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/operations/create_collection.ts)
- `DropCollectionOptions` - [src/operations/drop.ts](https://github.com/mongodb/node-mongodb-native/blob/main/src/operations/drop.ts)

**Description**: Specifies the schema for encrypted fields in a collection, used with Queryable Encryption.

**Example**:
```typescript
// Create collection with encrypted fields
await db.createCollection('users', {
encryptedFields: {
fields: [
{
path: 'ssn',
bsonType: 'string',
keyId: dataKeyId
}
]
}
});

// Drop collection with encrypted fields
await db.dropCollection('users', {
encryptedFields: encryptedFieldsConfig
});
```
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,14 @@ Nightly versions are published regardless of testing outcome.
This means there could be semantic breakages or partially implemented features.
The nightly build is not suitable for production use.

## Experimental Features

The MongoDB Node.js driver offers cutting-edge experimental features that give you early access to new capabilities and APIs. These features are marked with `@experimental` tags and are great for exploring new functionality and providing [feedback](#support--feedback).

Experimental features are not subject to [semantic versioning](https://semver.org/) rules, so breaking changes or removal may occur in any future release. The use of these features is not recommended for production environments.

Explore the full list of experimental features, complete with descriptions and usage examples, in [EXPERIMENTAL_FEATURES.md](https://github.com/mongodb/node-mongodb-native/blob/HEAD/EXPERIMENTAL_FEATURES.md).

## Next Steps

- [MongoDB Documentation](https://www.mongodb.com/docs/manual/)
Expand Down
7 changes: 7 additions & 0 deletions etc/notes/releasing.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ The MongoDB driver can now generate a cup of joe.

1. On slack notify `#node-driver-docs`, `#nodejs-devtools`, and `#mongoose` that we intend to publish a release.
- You may skip this step if you are releasing a package other than the driver.
1. **If there are new or changed experimental features**, update `EXPERIMENTAL_FEATURES.md`
- Update the version number in the document header
- Update the count of experimental annotations (grep for `@experimental` in `src/`)
- Add descriptions for any new `@experimental` features
- Remove or update entries for features that are no longer experimental
- Ensure all source file references omit line numbers (links should point to files, not specific lines)
- Commit and push these changes to the release branch before running release notes
1. Comment "`run release_notes`" on the release PR.
- This will kick off the action that reads the notes from each PR going into the release.
- Double check the result looks logically organized
Expand Down
Loading