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/javascript-sdkQuick Start
Basic Usage
This example shows how to get a feature flag with type-safe feature definitions in a Node.js environment.
import { SupaClient, FeaturesWithFallbacks } from '@supashiphq/javascript-sdk'
// Define your features with fallback values
const FEATURE_FLAGS = {
'new-api-endpoint': false,
'rate-limiting': {
maxRequests: 100,
windowMs: 60000,
},
} satisfies FeaturesWithFallbacks
const client = new SupaClient({
apiKey: YOUR_PROJECT_API_KEY, // Server API Key, found in your project settings
environment: 'production', // Environment slug
features: FEATURE_FLAGS,
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 (returns the fallback type)
const isEnabled = await client.getFeature('new-api-endpoint')
// Returns: boolean
if (isEnabled) {
console.log('New API endpoint is enabled!')
} else {
console.log('Using legacy API endpoint')
}
// Get configuration object
const rateLimitConfig = await client.getFeature('rate-limiting')
// Returns: { maxRequests: number, windowMs: number }
console.log('Rate limit:', rateLimitConfig.maxRequests)With Context Override
This example shows how to get a feature flag with a context override for server-side evaluation.
import { SupaClient, FeaturesWithFallbacks } from '@supashiphq/javascript-sdk'
const FEATURE_FLAGS = {
'premium-api-features': false,
'enterprise-analytics': false,
} satisfies FeaturesWithFallbacks
const client = new SupaClient({
apiKey: YOUR_PROJECT_API_KEY, // Server API Key, found in your project settings
environment: 'production', // Environment slug
features: FEATURE_FLAGS,
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', {
context: { plan: 'enterprise', region: 'us-east-1' },
})
console.log('Premium API features enabled:', featureEnabled)API Reference
For complete API documentation, see the Node.js SDK API Reference.
Usage Examples
Express.js Middleware
Integrate feature flags into your Express.js application:
import express from 'express'
import { SupaClient, FeaturesWithFallbacks } from '@supashiphq/javascript-sdk'
const FEATURE_FLAGS = {
'new-api-endpoint': false,
'advanced-analytics': false,
'beta-features': false,
} satisfies FeaturesWithFallbacks
const app = express()
const client = new SupaClient({
apiKey: process.env.SUPASHIP_API_KEY,
environment: process.env.ENVIRONMENT || 'production',
features: FEATURE_FLAGS,
})
// 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(
['new-api-endpoint', 'advanced-analytics', 'beta-features'],
{ 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, FeaturesWithFallbacks } from '@supashiphq/javascript-sdk'
interface UserContext {
userID?: string
email?: string
plan: 'free' | 'pro' | 'enterprise'
}
const FEATURE_FLAGS = {
'new-api-endpoint': false,
'premium-support': false,
'advanced-metrics': false,
} satisfies FeaturesWithFallbacks
const fastify = Fastify({ logger: true })
const client = new SupaClient({
apiKey: process.env.SUPASHIP_API_KEY,
environment: process.env.ENVIRONMENT || 'production',
features: FEATURE_FLAGS,
})
// 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(
['new-api-endpoint', 'premium-support', 'advanced-metrics'],
{ 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, FeaturesWithFallbacks } from '@supashiphq/javascript-sdk'
const FEATURE_FLAGS = {
'new-dashboard': false,
'premium-features': false,
} satisfies FeaturesWithFallbacks
const client = new SupaClient({
apiKey: process.env.SUPASHIP_API_KEY,
environment: process.env.ENVIRONMENT || 'production',
features: FEATURE_FLAGS,
})
export default async function handler(req, res) {
const { userId, email } = req.query
const results = await client.getFeatures(
['new-dashboard', 'premium-features'],
{
context: {
userID: userId,
email,
},
},
)
res.json(results)
}
// 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, FeaturesWithFallbacks } from '@supashiphq/javascript-sdk'
// Define all features used in your serverless function
const FEATURE_FLAGS = {
'new-api': false,
'beta-features': false,
'premium-access': false,
} satisfies FeaturesWithFallbacks
const client = new SupaClient({
apiKey: process.env.SUPASHIP_API_KEY,
environment: process.env.ENVIRONMENT || 'production',
features: FEATURE_FLAGS,
})
export default async function handler(req, res) {
const { userID, feature } = req.query
try {
const isEnabled = await client.getFeature(feature, {
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' })
}
}