Node.js
The Supaship JavaScript SDK provides server-side feature flag evaluation for Node.js applications and APIs. This enables you to control backend features, API behavior, and server-side logic without redeploying code.
This guide covers Node.js server-side usage. For browser-based usage, see the JavaScript code examples.
Requirements
- Node.js 16+ with ES6+ support
- A Server API Key for the environment you’re targeting (use server keys for backend applications)
- Supaship project with at least one feature flag created
Installation
pnpm add @supashiphq/sdk-javascript
Quick Start
Basic Usage
This example shows how to get a feature flag with a fallback value in a Node.js environment.
fallback
- The value to return if the feature flag is not found or targeting is not enabled.
import { SupaClient } from '@supashiphq/sdk-javascript'
const client = new SupaClient({
apiKey: YOUR_PROJECT_API_KEY, // Server API Key, found in your project settings
environment: 'production', // Environment slug
context: {
userID: '123', // User identifier (ex: userID, username, email, etc.), required for percentage rollouts
email: '[email protected]',
serverVersion: '2.1.0',
},
})
// Get a single feature flag with fallback
const isEnabled = await client.getFeature('new-api-endpoint', {
fallback: false,
})
if (isEnabled) {
console.log('New API endpoint is enabled!')
} else {
console.log('Using legacy API endpoint')
}
With Context Override
This example shows how to get a feature flag with a context override for server-side evaluation.
fallback
- The value to return if the feature flag is not found.context
- The context to use for the specific feature flag evaluation.
import { SupaClient } from '@supashiphq/sdk-javascript'
const client = new SupaClient({
apiKey: YOUR_PROJECT_API_KEY, // Server API Key, found in your project settings
environment: 'production', // Environment slug
context: {
userID: '123', // User identifier (ex: userID, username, email, etc.), required for percentage rollouts
email: '[email protected]',
},
})
// Get a feature flag with context override
const featureEnabled = await client.getFeature('premium-api-features', {
fallback: false,
context: { plan: 'enterprise', region: 'us-east-1' },
})
console.log('Premium API features enabled:', featureEnabled)
API Reference
Constructor
const client = new SupaClient(config)
Parameters:
config
(object) - Configuration object
Config Options:
apiKey
(string) - Your Supaship server API keyenvironment
(string) - The environment slug (e.g., ‘production’, ‘staging’, ‘development’)context
(object, optional) - Default user context for all requestsnetworkConfig
(object, optional) - Network settings including endpoints, retry configurations, timeout, and custom fetch functions
Methods
getFeature(featureKey, options)
Gets single feature flag value. Returns a boolean or object if the flag is a JSON type.
// Basic usage with fallback
const isEnabled = await client.getFeature('new-feature', { fallback: false })
// isEnabled is a boolean (true or false)
// With context override
const value = await client.getFeature('feature-name', {
fallback: false,
context: { plan: 'premium' },
})
// JSON configuration
const config = await client.getFeature('api-config', {
fallback: { timeout: 5000, retries: 3, endpoint: '/api/v1' },
})
// config is an object
getFeatures(features, options)
Get multiple feature flags at once. Returns an object with the feature flag names as keys and the flag values as values.
// Get multiple features
const features = await client.getFeatures({
features: {
'new-api-endpoint': false, // fallback is false
'rate-limiting': { limit: 100, window: 3600 }, // fallback object
},
context: {
userID: '456', // Override default context for this request
},
})
console.log(features)
// { 'new-api-endpoint': true, 'rate-limiting': { limit: 1000, window: 3600 } }
setContext(context)
Update the default context for all subsequent requests. This context is used for all feature flag evaluations unless overridden by the context
parameter in the getFeature
or getFeatures
methods.
This is helpful when the context data is not available at the time of client initialization, and you need to wait for async data to be available before evaluating feature flags.
const client = new SupaClient({
apiKey: YOUR_PROJECT_API_KEY, // Server API Key, found in your project settings
environment: 'production', // Environment slug
context: {}, // Empty context
})
const context = await apiCallToGetContext()
// Updates the default context for all subsequent requests
client.setContext(context)
// All subsequent getFeature calls will use the updated context
const isEnabled = await client.getFeature('new-api-endpoint', {
fallback: false,
})
getContext()
Get the current default context. Returns an object with the current context data.
const context = client.getContext()
console.log('Current context:', context)
Usage Examples
Express.js Middleware
Integrate feature flags into your Express.js application:
import express from 'express'
import { SupaClient } from '@supashiphq/sdk-javascript'
const app = express()
const client = new SupaClient({
apiKey: process.env.SUPASHIP_API_KEY,
environment: process.env.ENVIRONMENT || 'production',
})
// Middleware to add feature flags to requests
app.use(async (req, res, next) => {
const context = {
userID: req.user?.id,
email: req.user?.email,
userAgent: req.get('User-Agent'),
}
req.features = await client.getFeatures({
features: {
'new-api-endpoint': false,
'advanced-analytics': false,
'beta-features': false,
},
context,
})
next()
})
app.get('/api/data', async (req, res) => {
if (req.features['new-api-endpoint']) {
// New implementation
res.json({ data: 'enhanced-data', version: 'v2' })
} else {
// Legacy implementation
res.json({ data: 'basic-data', version: 'v1' })
}
})
app.listen(3000, () => {
console.log('Server running on port 3000')
})
TypeScript with Fastify
Use with Fastify and TypeScript for type-safe feature flag integration:
import Fastify, { FastifyRequest, FastifyReply } from 'fastify'
import { SupaClient } from '@supashiphq/sdk-javascript'
interface UserContext {
userID?: string
email?: string
plan: 'free' | 'pro' | 'enterprise'
}
const fastify = Fastify({ logger: true })
const client = new SupaClient({
apiKey: process.env.SUPASHIP_API_KEY,
environment: process.env.ENVIRONMENT || 'production',
})
// Declare feature flags interface
declare module 'fastify' {
interface FastifyRequest {
features: {
'new-api-endpoint': boolean
'premium-support': boolean
'advanced-metrics': boolean
}
}
}
// Plugin to add feature flags
fastify.addHook(
'preHandler',
async (request: FastifyRequest, reply: FastifyReply) => {
const context: UserContext = {
userID: request.user?.id,
email: request.user?.email,
plan: request.user?.plan || 'free',
}
request.features = await client.getFeatures({
features: {
'new-api-endpoint': false,
'premium-support': false,
'advanced-metrics': false,
},
context,
})
},
)
fastify.get('/api/dashboard', async (request, reply) => {
const data: any = { dashboard: 'basic' }
if (request.features['new-api-endpoint']) {
data.enhanced = true
data.charts = ['revenue', 'users', 'engagement']
}
if (request.features['advanced-metrics']) {
data.metrics = { realtime: true, historical: true }
}
return data
})
fastify.listen({ port: 3000 }, err => {
if (err) throw err
console.log('Server running on port 3000')
})
Next.js API Routes
Server-side rendering and API route integration:
// pages/api/features.js
import { SupaClient } from '@supashiphq/sdk-javascript'
const client = new SupaClient({
apiKey: process.env.SUPASHIP_API_KEY,
environment: process.env.ENVIRONMENT || 'production',
})
export default async function handler(req, res) {
const { userId, email } = req.query
const features = await client.getFeatures({
features: {
'new-dashboard': false,
'premium-features': false,
},
context: {
userID: userId,
email,
},
})
res.json(features)
}
// pages/index.js
export async function getServerSideProps(context) {
const user = getUserFromContext(context)
// Pre-fetch feature flags on server
const features = await fetch(
`/api/features?${new URLSearchParams({
userId: user.id,
email: user.email,
})}`,
).then(res => res.json())
return {
props: {
user,
features,
},
}
}
Serverless Functions (Vercel/Netlify)
// api/check-feature.js
import { SupaClient } from '@supashiphq/sdk-javascript'
const client = new SupaClient({
apiKey: process.env.SUPASHIP_API_KEY,
environment: process.env.ENVIRONMENT || 'production',
})
export default async function handler(req, res) {
const { userID, feature } = req.query
try {
const isEnabled = await client.getFeature(feature, {
fallback: false,
context: { userID },
})
res.json({ feature, enabled: isEnabled })
} catch (error) {
console.error('Feature flag error:', error)
res.status(500).json({ error: 'Failed to get feature flag' })
}
}