@flagify/node
v1.0.5
Published
Official Flagify SDK for feature flag evaluation. TypeScript-first with local caching.
Maintainers
Readme
Overview
@flagify/node is the official Node.js SDK for Flagify. TypeScript-first, with in-memory caching and sub-millisecond flag evaluation.
- TypeScript-first -- Full type safety with generics support
- In-memory cache -- Sub-millisecond evaluations after initial sync
- Stale-while-revalidate -- Serves cached values while refreshing in the background
- Lightweight -- Zero runtime dependencies (except
dotenv) - Isomorphic -- ESM and CommonJS output
Table of contents
- Installation
- Quick start
- Configuration
- API reference
- How it works
- Environment variables
- Contributing
- License
Installation
# pnpm
pnpm add @flagify/node
# npm
npm install @flagify/node
# yarn
yarn add @flagify/nodeQuick start
import { Flagify } from '@flagify/node'
const flagify = new Flagify({
projectKey: 'proj_xxx',
publicKey: 'pk_xxx',
})
// Boolean flag
if (flagify.isEnabled('new-checkout')) {
showNewCheckout()
}
// Typed value
const limit = flagify.getValue<number>('rate-limit')Configuration
import { Flagify } from '@flagify/node'
const flagify = new Flagify({
// Required
projectKey: 'proj_xxx',
publicKey: 'pk_xxx',
// Optional -- server-side only, never expose in client bundles
secretKey: 'sk_xxx',
options: {
// Custom API endpoint (defaults to https://api.flagify.dev)
apiUrl: 'https://api.flagify.dev',
// Cache TTL in ms (default: 5 minutes)
staleTimeMs: 300_000,
// Real-time updates via SSE (coming soon)
realtime: false,
// User context for targeting rules
user: {
id: 'user_123',
email: '[email protected]',
role: 'admin',
group: 'engineering',
geolocation: {
country: 'US',
region: 'CA',
city: 'San Francisco',
},
// Custom attributes
plan: 'enterprise',
companySize: 50,
},
},
})Configuration options
| Option | Type | Required | Default | Description |
|--------|------|----------|---------|-------------|
| projectKey | string | Yes | -- | Project identifier from your Flagify workspace |
| publicKey | string | Yes | -- | Client-safe publishable API key |
| secretKey | string | No | -- | Server-side secret key |
| options.apiUrl | string | No | https://api.flagify.dev | Custom API base URL |
| options.staleTimeMs | number | No | 300000 | Cache staleness threshold in ms |
| options.realtime | boolean | No | false | Enable real-time SSE updates |
| options.pollIntervalMs | number | No | -- | Polling interval in ms for periodic flag sync |
| options.user | FlagifyUser | No | -- | User context for targeting |
API reference
new Flagify(config: FlagifyOptions)
Creates a new Flagify client. Immediately fetches all flags and populates the local cache.
const flagify = new Flagify({
projectKey: 'proj_xxx',
publicKey: 'pk_xxx',
})flagify.isEnabled(flagKey: string): boolean
Evaluates a boolean feature flag.
Returns false when:
- The flag does not exist
- The flag is disabled
- The flag type is not
boolean
if (flagify.isEnabled('dark-mode')) {
applyDarkTheme()
}flagify.getValue<T>(flagKey: string, fallback: T): T
Returns the resolved value of a feature flag with a typed fallback.
// String variant
const variant = flagify.getValue<string>('checkout-flow', 'control')
// Number
const limit = flagify.getValue<number>('rate-limit', 100)
// JSON object
const config = flagify.getValue<{ maxRetries: number; timeout: number }>('api-config', {
maxRetries: 3,
timeout: 5000,
})flagify.getVariant(flagKey: string, fallback: string): string
Returns the string variant of a multivariate flag. Returns the variant with the highest weight, or the fallback if the flag has no variants or is disabled.
const variant = flagify.getVariant('checkout-flow', 'control')flagify.evaluate(flagKey: string, user: FlagifyUser): Promise<EvaluateResult>
Server-side evaluation with user targeting. Calls the Flagify API with user context for targeting rules.
const result = await flagify.evaluate('premium-feature', {
id: 'user_123',
email: '[email protected]',
role: 'admin',
})
// result: { key: 'premium-feature', value: true, reason: 'targeting_rule' }flagify.ready(): Promise<void>
Resolves when the initial flag sync is complete. Useful in server startup sequences.
const flagify = new Flagify({ projectKey: 'proj_xxx', publicKey: 'pk_xxx' })
await flagify.ready()flagify.destroy(): void
Disconnects the realtime listener, stops polling, and cleans up resources.
flagify.destroy()flagify.onFlagChange
Callback invoked when a flag changes via SSE or background refetch.
flagify.onFlagChange = (event) => {
console.log(`Flag ${event.flagKey} was ${event.action}`)
}How it works
Init Evaluate Stale?
---- -------- ------
GET /v1/flags --> Read from cache --> Background refetch
Cache all flags Sub-ms response GET /v1/flags/:key
Return stale value immediately- On initialization, the client syncs all flags from
GET /v1/flags - All evaluations read from the in-memory
Mapcache -- sub-millisecond - When a flag exceeds
staleTimeMs, the stale value is returned immediately while a backgroundGET /v1/flags/:keyrefreshes the cache - If the API is unreachable, the client falls back to cached defaults
Environment variables
| Variable | Description |
|----------|-------------|
| FLAGIFY_API_URL | Override the default API base URL |
Types
All types are exported for convenience:
import type {
FlagifyOptions,
FlagifyUser,
FlagifyFlag,
IFlagifyClient,
EvaluateResult,
FlagChangeEvent,
RealtimeEvents,
RealtimeListener,
} from '@flagify/node'Contributing
We welcome contributions. Please open an issue first to discuss what you'd like to change.
# Clone
git clone https://github.com/flagifyhq/javascript.git
cd javascript
# Install
pnpm install
# Development
pnpm run dev
# Build
pnpm run buildLicense
MIT -- see LICENSE for details.
