nanvc is a lightweight TypeScript client for the HashiCorp Vault HTTP API.
It is built for Node.js applications that need typed Vault access without a large framework around secrets, auth, or infrastructure automation.
Use it for typed KV v1/KV v2 secret workflows, AppRole authentication, response wrapping, system policy helpers, database secrets, optional request logging, and raw Vault API calls when you need an escape hatch.
Full documentation: zailic.github.io/nanvc
- Typed Vault client for TypeScript: exported request and response types for the v2 client surface.
- KV shortcuts that feel like the Vault CLI:
read,write,delete, andlistsupport KV v1 by default and KV v2 with{ engineVersion: 2 }. - Focused high-level APIs: helpers for AppRole, KV v1, KV v2, system policies, response wrapping, and database secrets.
- Raw API escape hatch:
RawVaultClientlets you call unsupported Vault endpoints without leaving the same client setup. - Result-based error handling: use tuple-style results or
.unwrap(),.unwrapOr(), and related helpers. - Production-friendly basics: ESM, Node.js
>=20, optional TLS/mTLS, and opt-in request lifecycle logs.
npm install nanvcimport { VaultClientV2 } from 'nanvc';
const vault = new VaultClientV2();
await vault.write('secret/apps/demo', { password: 's3cr3t' }).unwrap();
const secret = await vault.read<{ password: string }>('secret/apps/demo').unwrap();await vault.write('secret-v2', 'apps/demo', { apiKey: 'dev-key' }, { engineVersion: 2 }).unwrap();
const value = await vault.read<{ apiKey: string }>('secret-v2', 'apps/demo', { engineVersion: 2 }).unwrap();For the full versioned KV workflow, including patch, metadata, history, soft-delete, undelete, destroy, automatic deletion, and CAS examples, see the versioned KV guide.
const login = await vault.auth
.loginWithAppRole({
role_id: process.env.VAULT_ROLE_ID,
secret_id: process.env.VAULT_SECRET_ID,
})
.unwrap();See the runnable VaultClientV2 AppRole example.
const wrapped = await vault.sys.wrapping.wrap({ role_id: '...', secret_id: '...' }, '5m').unwrap();
const unwrapped = await vault.sys.wrapping.unwrap(wrapped.wrap_info.token).unwrap();See the request wrapping example.
await vault.secret.db
.configureConnection('database', 'postgres', {
plugin_name: 'postgresql-database-plugin',
connection_url: 'postgresql://{{username}}:{{password}}@localhost/postgres',
allowed_roles: ['readonly'],
})
.unwrap();
const creds = await vault.secret.db.generateCredentials('database', 'readonly').unwrap();VaultClientV2 and RawVaultClient return a promise-like Result<T>.
You can use tuple-style handling:
const [secret, error] = await vault.read<{ password: string }>('secret/apps/demo');
if (error) {
console.error(error.message);
} else {
console.log(secret.password);
}Or use helpers:
const secret = await vault.read<{ password: string }>('secret/apps/demo').unwrap();
const fallback = await vault.read('secret/missing').unwrapOr({ password: 'fallback' });Read more in the error handling guide.
When a high-level helper does not cover an endpoint yet, call Vault directly:
const info = await vault.raw.get('/sys/host-info').unwrap();See the VaultClientV2 API reference for the full typed surface.
Logging is disabled by default. Enable request lifecycle logs with:
NANVC_LOG_LEVEL=debug node app.jsSupported levels are error, warn, info, and debug.
Logs include method, URL, status, and duration, but never tokens or request/response bodies.
New development is focused on VaultClientV2, the typed client built on RawVaultClient.
The original VaultClient remains available for compatibility and for optional mTLS support.
Original client documentation:
CommonJS consumers can load this ESM-only package with dynamic import():
const { VaultClientV2 } = await import('nanvc');- Node.js
>=20 - ESM project or dynamic
import()from CommonJS
MIT