Skip to Content

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-sdk

Quick 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' }) } }
Last updated on