Skip to main content

Node.js SDK

Learn with a sample​

Use the Samples catalog to choose a framework and see its current status. Each runnable sample starts with its README, then follows the same learning path: src/catalog.js (keys and filter inputs) → src/app.js (request context and route checks) → test/http.test.js (enabled/disabled and isolation evidence).

Adapter helpers and the core client have different signatures; use the core client for an explicit per-check override or entity.

Use @ops-ai/toggly-node-core for server-side, local evaluation of feature flags. Framework adapters add request-scoped context and route gates.

Quick reference

Grab the printable Node.js cheat sheet (download PDF) — init, evaluation, entity context, Express / Fastify / Hono / Koa adapters. NestJS has a dedicated sheet.

  • Core: @ops-ai/toggly-node-core
  • Adapters: @ops-ai/toggly-express, @ops-ai/toggly-fastify, @ops-ai/toggly-hono, @ops-ai/toggly-koa
  • Runtime: Node.js 18+

Packages​

PackageRole
@ops-ai/toggly-node-coreClient, local eval, cache, signed defs, WebSocket sync
@ops-ai/toggly-expressExpress middleware, featureGate, identity extractors
@ops-ai/toggly-fastifyFastify plugin + preHandler gates
@ops-ai/toggly-honoHono middleware + gates
@ops-ai/toggly-koaKoa middleware + gates

Installation​

npm install @ops-ai/toggly-node-core

Quick start​

import { createTogglyClient } from '@ops-ai/toggly-node-core'

const client = createTogglyClient({
appKey: process.env.TOGGLY_APP_KEY!,
environment: 'Production',
})
await client.init()

if (await client.isFeatureOn('MyFeature')) {
// enabled
}

With user context​

Adapters: configure ambient EvalContext once with getIdentity / getGroups / getClaims on middleware, then call req.toggly.isFeatureOn('X') (or the Fastify / Hono / Koa equivalent) with no args — see Express (same pattern on Fastify / Hono / Koa).

Core / overrides: pass an EvaluationContext per call:

import type { EvaluationContext } from '@ops-ai/toggly-node-core'

const context: EvaluationContext = {
identity: 'user-123',
groups: ['beta', 'premium'],
claims: { role: 'admin' },
traits: { plan: 'enterprise', country: 'US' },
}

if (await client.isFeatureOn('premium-feature', context)) {
// targeting matched for this user
}

See Configuration.

Entity context​

Trusted server apps evaluate full definitions and can register context schemas for the dashboard (same model as .NET entity context). See Entity & page context.

User EvaluationContext (identity / groups / claims / traits / request) stays user — do not put page-entity attributes there. Pass the domain object per check as the third argument (optional kind as the fourth).

interface Order {
id: string
status: string
total: number
}

client.registerContext(
'Order',
(order: Order) => ({
kind: 'Order',
key: String(order.id),
attributes: { Status: order.status, Total: order.total },
}),
{
keyProperty: 'id',
properties: [
{ name: 'Status', type: 'string' },
{ name: 'Total', type: 'number' },
],
},
)

const order: Order = { id: 'ORD-42', status: 'Paid', total: 199 }

if (await client.isFeatureOn('ExpressCheckout', undefined, order, 'Order')) {
// user rules AND entity rules passed for this order instance
}

registerContext maps domain objects locally and registers entity schemas with Toggly on startup (registerContextsOnStartup, default true). Client browsers never perform this registration.

Without a registered mapper / known kind, entity rules fail closed.

You can also pass a ready TogglyEntityContext ({ kind, key, attributes }) as the third argument without a mapper.

Reliability​

The Node core SDK follows the server-side reliability contract:

  • verifySignatures — verify definitions using the exact signed defs payload
  • onError — callback for fetch, cache, and signature failures
  • clearCache() — clear persisted feature/JWKS caches
  • WebSocket signing-key-updated — clear JWKS and refresh definitions
  • Definitions revision via ETag / X-Definitions-Revision
import { createTogglyClient } from '@ops-ai/toggly-node-core'

const client = createTogglyClient({
appKey: process.env.TOGGLY_APP_KEY!,
environment: 'Production',
verifySignatures: true,
enableStreaming: true,
onError: (error, context) => {
console.error('Toggly:', context, error)
},
})

await client.clearCache()

Details: Configuration · Client-side WebSocket sync (shared protocol).

Next steps​