Skip to content

JavaScript / TypeScript SDK

The @bella-baxter/sdk package works in Node.js and supports all major frameworks.

Installation

sh
npm install @bella-baxter/sdk
sh
pnpm add @bella-baxter/sdk
sh
yarn add @bella-baxter/sdk

Quick Start

typescript
import { createBaxterClient } from '@bella-baxter/sdk'

const client = await createBaxterClient({
  baxterUrl: process.env.BELLA_BAXTER_URL!,
  apiKey: process.env.BELLA_BAXTER_API_KEY!,
})

const secrets = await client.getAllSecrets()
console.log(secrets.DATABASE_URL)

Framework Integrations

All samples are available on GitHub — each one shows a teaser pattern below.

Express

typescript
// Load secrets before creating the app
const secrets = await client.getAllSecrets()
const app = express()
app.get('/health', (req, res) => res.json({ db: secrets.DATABASE_URL }))

Full Express sample

NestJS

typescript
// In your AppModule bootstrap
const secrets = await client.getAllSecrets()
Object.entries(secrets).forEach(([k, v]) => process.env[k] = v)

Full NestJS sample

Next.js

typescript
// next.config.js — load secrets before Next starts
import { loadSecretsToEnv } from '@bella-baxter/sdk'
await loadSecretsToEnv()

Full Next.js sample

Fastify

typescript
await fastify.register(bellaPlugin)
fastify.get('/db', (req, reply) => reply.send({ url: fastify.secrets.DATABASE_URL }))

Full Fastify sample

Zero-Knowledge Encryption (ZKE)

By default the SDK generates a fresh P-256 keypair for every secrets request (ephemeral E2EE over TLS). With ZKE you supply a persistent device key — the server can then audit which device fetched each secret and the SDK caches the wrapped DEK to reduce round-trips.

Generate your device key once:

sh
bella auth setup   # stores key in OS keychain and prints the PEM

Use it in your app:

typescript
import { createBaxterClient } from '@bella-baxter/sdk'

const client = await createBaxterClient({
  baxterUrl: process.env.BELLA_BAXTER_URL!,
  apiKey: process.env.BELLA_BAXTER_API_KEY!,
  // Optional — reads BELLA_BAXTER_PRIVATE_KEY env var automatically
  privateKey: process.env.BELLA_BAXTER_PRIVATE_KEY,
  onWrappedDekReceived(project, env, wrappedDek, leaseExpires) {
    // Optional: cache the wrapped DEK for faster re-auth
    console.log(`DEK for ${project}/${env} expires ${leaseExpires}`)
  },
})

Or via environment variable (recommended):

sh
export BELLA_BAXTER_PRIVATE_KEY="$(cat ~/.bella/device-key.pem)"

The SDK auto-reads BELLA_BAXTER_PRIVATE_KEY — no code change needed. If the variable is not set the SDK falls back to ephemeral E2EE, so this is fully backward-compatible.

Typed Secrets

sh
bella secrets generate typescript

Generates a secrets.ts file with typed properties. No more process.env.MY_SECRET as string.

All Samples

SamplePatternLink
01-dotenv-filebella pull → read .envGitHub
02-process-injectbella run -- node index.jsGitHub
03-expressSDK in Express middlewareGitHub
04-nestjsSDK in NestJS bootstrapGitHub
05-nextjsSDK in next.config.jsGitHub
06-fastifySDK as Fastify pluginGitHub
07-adonisjsSDK in AdonisJS providerGitHub

Released under the ELv2 License.