Skip to content

TypeScript SDK

The official TypeScript SDK is published as @vaylix/client. The current SDK line is 0.4.x and is compatible with the Vaylix server 0.8.x line.

Use it when Vaylix is part of an application codebase and you need direct transport access rather than the interactive CLI.

The SDK is:

  • a Node.js client
  • Node.js >= 20.19.0
  • direct TCP/TLS transport, not a wrapper around the Rust CLI
  • zstd compression via a native Node binding with prebuilt binaries
  • factory-led public API with createClient() and createPool()
  • aligned with the current VTP2 transport, structured EXEC results, binary-safe values, version-based CAS, and the HA cluster command surface used by the server 0.8.x line
Terminal window
npm install @vaylix/client

Pin the current release explicitly when reproducibility matters:

Terminal window
npm install @vaylix/client@0.4.0

Runtime assumptions:

  • Node.js only
  • Node >= 20.19.0
  • no browser or Deno support

Use the SDK for:

  • backend services
  • worker processes
  • scripts and automation
  • application-side transaction handling
  • programmatic metrics/info access

Use the Rust client binary when you want:

  • interactive manual inspection
  • shell-driven operator workflows
  • local debugging against a live node
import { createClient } from '@vaylix/client';
const client = createClient({
url: 'vaylix://vaylix:vaylix@127.0.0.1:9173',
});
await client.connect();
try {
await client.set('app:greeting', 'hello');
console.log(await client.get('app:greeting'));
} finally {
await client.close();
}

Vaylix 0.8.0 stores values as opaque bytes. The SDK keeps UTF-8 string methods for convenience and exposes explicit byte APIs for binary-safe flows:

const bytes = Buffer.from([0x00, 0xff, 0x61]);
await client.setBytes('blob:1', bytes);
console.log(await client.getBytes('blob:1'));
await client.set('profile:json', '{"ok":true}');
await client.set('profile:json', '{"ok":false}', { ifVersion: 1n });

Use:

  • get() / set() / mget() / mset() for UTF-8 text ergonomics
  • getBytes() / setBytes() / mgetBytes() / msetBytes() for exact byte payloads
  • ifVersion for SET ... IF VERSION <version> compare-and-set writes

If no explicit url is provided, the SDK reads process.env.DATABASE_URL.

Example:

DATABASE_URL=vaylix://vaylix:vaylix@127.0.0.1:9173

The SDK does not load .env files automatically. That remains the application’s responsibility.

import { createPool } from '@vaylix/client';
const pool = createPool({
url: 'vaylix://vaylix:vaylix@127.0.0.1:9173',
max: 4,
});
await pool.connect();
try {
await pool.set('pool:key', 'value');
console.log(await pool.get('pool:key'));
} finally {
await pool.close();
}

The SDK exposes the server 0.8.x operational inspection surface directly:

const health = await client.health();
const cluster = await client.showCluster();
const replication = await client.showReplication();

These commands return deterministic Record<string, string> maps so application code can reason about:

  • readiness and maintenance state
  • current cluster role
  • current term and leader hint
  • quorum and write acknowledgement mode
  • follower phase and lag
  • leader identity and local applied sequence

The SDK also exposes leader-only operational commands:

await client.clusterJoin('node-2', '10.0.0.12:9173');
await client.clusterRemove('node-2');
await client.promoteFollower();
await client.pauseReplication();
await client.resumeReplication();

Those are for controlled administrative workflows. They are not ordinary application commands. In the current 0.8.x server line, writes on non-leaders are rejected with typed server errors, while default reads should be sent to the leader unless the application explicitly accepts stale follower reads.

Transactions are explicit:

const tx = await client.transaction();
tx.set('tx:key', 'alpha');
tx.get('tx:key');
tx.exists('tx:key');
const result = await tx.exec();

Example EXEC result:

[
{ status: 'OK' },
{ status: 'OK', value: 'alpha', valueBytes: Buffer.from('alpha') },
{ status: 'OK', boolean: true },
]

The structured EXEC transport payload in server 0.3.0 is what makes this result shape reliable. In 0.8.0, the typed payload also preserves exact byte values through fields such as valueBytes.

The SDK exports typed errors such as:

  • ConnectionError
  • TimeoutError
  • ProtocolError
  • AuthenticationError
  • AuthorizationError
  • ReplicationAckTimeoutError
  • ReplicationAckUnavailableError
  • FollowerWriteRejectedError
  • ReplicationPromotionDeniedError
  • RemoteCommandError

Use these to distinguish transport failures from server-side command failures.

The current SDK surface covers:

  • connect / close
  • auth
  • ping
  • get, set, del, exists
  • mget, mset
  • expire, ttl, persist
  • info
  • health
  • showCluster
  • showReplication
  • clusterJoin, clusterRemove
  • promoteFollower, pauseReplication, resumeReplication
  • metrics
  • metricsProm
  • transactions
  • simple pooling

It is still intentionally narrower than the full Rust CLI, but it covers the core application-facing and HA-aware operational surface shipped in the current 0.8.x server line.