Node.js Integration
Rift provides official Node.js bindings via the @rift-vs/rift npm package. This package is a drop-in replacement for Mountebank’s Node.js API, making migration seamless.
Installation
npm install @rift-vs/rift
The package automatically downloads the appropriate rift-http-proxy binary for your platform during installation.
Supported Platforms
| Platform | Architecture |
|---|---|
| macOS | x64, arm64 |
| Linux | x64, arm64 |
| Windows | x64 |
Basic Usage
import rift from '@rift-vs/rift';
// Start a Rift server
const server = await rift.create({
port: 2525,
loglevel: 'info',
});
console.log(`Rift server running on ${server.host}:${server.port}`);
// Create an imposter via REST API
await fetch('http://localhost:2525/imposters', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
port: 4545,
protocol: 'http',
stubs: [{
predicates: [{ equals: { path: '/api/users' } }],
responses: [{
is: {
statusCode: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify([{ id: 1, name: 'Alice' }])
}
}]
}]
})
});
// Test your mock
const response = await fetch('http://localhost:4545/api/users');
console.log(await response.json()); // [{ id: 1, name: 'Alice' }]
// Clean up when done
await server.close();
Migration from Mountebank
Migrating from Mountebank is straightforward - just change the import:
Before (Mountebank):
import mb from 'mountebank';
const server = await mb.create({
port: 2525,
loglevel: 'debug',
allowInjection: true,
});
After (Rift):
import rift from '@rift-vs/rift';
const server = await rift.create({
port: 2525,
loglevel: 'debug',
allowInjection: true,
});
All your existing imposter configurations and test code work without changes.
TypeScript Support
Full TypeScript definitions are included:
import rift, { CreateOptions, RiftServer } from '@rift-vs/rift';
const options: CreateOptions = {
port: 2525,
loglevel: 'debug',
};
const server: RiftServer = await rift.create(options);
// Type-safe properties
console.log(server.port); // number
console.log(server.host); // string
await server.close();
API Reference
create(options?: CreateOptions): Promise<RiftServer>
Creates and starts a new Rift server instance.
CreateOptions
| Option | Type | Default | Description |
|---|---|---|---|
port | number | 2525 | Admin API port |
host | string | 'localhost' | Bind address |
loglevel | string | 'info' | Log level: debug, info, warn, error |
logfile | string | - | Path to log file |
ipWhitelist | string[] | - | Allowed IP addresses |
allowInjection | boolean | false | Enable script injection |
RiftServer
| Property/Method | Type | Description |
|---|---|---|
port | number | Port the server is listening on |
host | string | Host the server is bound to |
close() | Promise<void> | Gracefully shutdown the server |
Events
The server emits the following events:
exit- Emitted when the server process exitserror- Emitted on server errorsstdout- Emitted with stdout datastderr- Emitted with stderr data
Testing Example with Jest
import rift from '@rift-vs/rift';
describe('API Tests', () => {
let server;
beforeAll(async () => {
server = await rift.create({ port: 2525 });
// Create test imposters
await fetch('http://localhost:2525/imposters', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
port: 4545,
protocol: 'http',
stubs: [{
predicates: [{ equals: { method: 'GET', path: '/health' } }],
responses: [{ is: { statusCode: 200, body: { status: 'ok' } } }]
}]
})
});
});
afterAll(async () => {
await server.close();
});
test('health check returns ok', async () => {
const response = await fetch('http://localhost:4545/health');
const data = await response.json();
expect(data.status).toBe('ok');
});
});
Environment Variables
| Variable | Description |
|---|---|
RIFT_BINARY_PATH | Path to the rift-http-proxy binary |
RIFT_VERSION | Version to download (default: latest) |
RIFT_DOWNLOAD_URL | Custom download URL for binary |
RIFT_SKIP_BINARY_DOWNLOAD | Skip binary download during install |
Manual Binary Installation
If automatic download doesn’t work (e.g., behind a firewall), install the binary manually:
- Download from GitHub Releases
- Set the
RIFT_BINARY_PATHenvironment variable:
export RIFT_BINARY_PATH=/path/to/rift-http-proxy
npm install @rift-vs/rift
Local Development & Testing
This section explains how to build and test Rift and the npm package locally before publishing.
1. Build Rift Binary
First, build the Rift binary from source:
# Clone the repository
git clone https://github.com/EtaCassiopeia/rift.git
cd rift
# Build the release binary
cargo build --release
# The binary is at: ./target/release/rift-http-proxy
2. Build the npm Package
cd packages/rift-node
# Install dependencies (skip binary download since we'll use local)
RIFT_SKIP_BINARY_DOWNLOAD=1 npm install
# Build TypeScript
npm run build
3. Test Locally with npm pack
This method creates a tarball that simulates a published package:
# Create the package tarball
cd packages/rift-node
npm pack
# Creates: rift-vs-rift-0.1.0.tgz
# In a test directory, install the tarball
mkdir /tmp/test-rift && cd /tmp/test-rift
npm init -y
npm install /path/to/rift/packages/rift-node/rift-vs-rift-0.1.0.tgz
4. Alternative: Test with npm link
For active development, npm link is faster:
# Link the package globally
cd packages/rift-node
npm link
# In your test directory, use the linked package
cd /tmp/test-rift
npm init -y
npm link @rift-vs/rift
5. Create a Test Script
Create test.mjs in your test directory:
import rift from '@rift-vs/rift';
async function main() {
console.log('Starting Rift server...');
const server = await rift.create({
port: 2525,
loglevel: 'info',
});
console.log(`Server running on ${server.host}:${server.port}`);
// Create a test imposter
const createResponse = await fetch('http://localhost:2525/imposters', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
port: 4545,
protocol: 'http',
stubs: [{
predicates: [{ equals: { path: '/test' } }],
responses: [{ is: { statusCode: 200, body: 'Hello from Rift!' } }]
}]
})
});
console.log('Imposter created:', createResponse.status);
// Test the imposter
const testResponse = await fetch('http://localhost:4545/test');
const body = await testResponse.text();
console.log('Response:', body);
// Verify
if (body === 'Hello from Rift!') {
console.log('✓ Test passed!');
} else {
console.error('✗ Test failed!');
process.exit(1);
}
// Cleanup
await server.close();
console.log('Server stopped');
}
main().catch(err => {
console.error('Error:', err);
process.exit(1);
});
6. Run the Test
# Set the path to your locally built binary
export RIFT_BINARY_PATH=/path/to/rift/target/release/rift-http-proxy
# Run the test
node test.mjs
Expected output:
Starting Rift server...
Server running on localhost:2525
Imposter created: 201
Response: Hello from Rift!
✓ Test passed!
Server stopped
Complete Local Test Script
For convenience, here’s a script that does everything:
#!/bin/bash
set -e
RIFT_DIR="/path/to/rift"
TEST_DIR="/tmp/test-rift-local"
# Build Rift
echo "Building Rift..."
cd "$RIFT_DIR"
cargo build --release
# Build npm package
echo "Building npm package..."
cd "$RIFT_DIR/packages/rift-node"
RIFT_SKIP_BINARY_DOWNLOAD=1 npm install
npm run build
npm pack
# Setup test directory
echo "Setting up test..."
rm -rf "$TEST_DIR"
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"
npm init -y
npm install "$RIFT_DIR/packages/rift-node"/*.tgz
# Create test file
cat > test.mjs << 'EOF'
import rift from '@rift-vs/rift';
const server = await rift.create({ port: 2525 });
console.log('Server started on port', server.port);
await fetch('http://localhost:2525/imposters', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
port: 4545,
protocol: 'http',
stubs: [{
predicates: [{ equals: { path: '/hello' } }],
responses: [{ is: { statusCode: 200, body: 'Hello!' } }]
}]
})
});
const res = await fetch('http://localhost:4545/hello');
const text = await res.text();
if (text === 'Hello!') {
console.log('✓ Test passed!');
} else {
console.error('✗ Test failed:', text);
process.exit(1);
}
await server.close();
EOF
# Run test
echo "Running test..."
export RIFT_BINARY_PATH="$RIFT_DIR/target/release/rift-http-proxy"
node test.mjs
echo "Done!"
Utility Functions
findBinary(): Promise<string>
Locates the rift-http-proxy binary. Searches in order:
RIFT_BINARY_PATHenvironment variable- Package’s
binaries/directory - System PATH
downloadBinary(version?: string): Promise<string>
Downloads the Rift binary for the current platform.
getBinaryVersion(): Promise<string | null>
Returns the installed binary version, or null if not found.
Requirements
- Node.js 18.0.0 or later
- One of the supported platforms (see above)