Node.js feature flags: a practical getting started guide with Express.js example

Feature flags in JavaScript illustration

Prerequisites

  1. Prior general knowledge of Node.js and express would be expected.
  2. Some experience of NPM and how to add new packages with NPM would be needed.
  3. Any knowledge of Git and GitHub would be really helpful.
  4. A Flagsmith account will be used to create a feature flag so register now if you have not. There is a free plan available.
  5. You will need a Github account to clone the demo repository and deploy code to Railway.app

Example: Express single-page application for Node.js feature flags

Podcast homepage

Set up feature flag on Flagsmith

Create project GIF
Flagsmith application home section
Creating a new feature in Flagsmith
Flagsmith application home with feature

Install Flagsmith Node.js client

git clone git@github.com:geshan/nodejs-express-tutorial.git
cd nodejs-express-tutorial
npm install
npm start
Eventually podcast homepage
npm i --save flagsmith-nodejs node-cache
npm WARN eventually-podcast@1.0.0 No repository field.

+ node-cache@5.1.2
+ flagsmith-nodejs@1.1.0
updated 2 packages and audited 98 packages in 1.845s
6 packages are looking for funding
run `npm fund` for details

found 0 vulnerabilities

Use Flagsmith Node.js client with some caching

const express = require('express');
const path = require('path');
const flagsmith = require('flagsmith-nodejs');
const nodecache = require('node-cache');

const app = express();
const port = process.env.PORT || '3000';

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(express.static(path.join(__dirname, 'public')));

flagsmith.init({
environmentID: process.env.FLAGSMITH_ENVIRONMENT_ID || 'LKfXyih5yqZxL3huZ5LraP',
cache: new nodecache({stdTTL : 10, checkperiod: 10}),
});

app.get('/', async (req, res) => {
let showFooterIcons = false;
try {
showFooterIcons = await flagsmith.hasFeature('show_footer_icons');
} catch (e) {
console.log(`Error connecting to flagsmith - ${e.getMessage} `, e);
}

console.log(`show footer icons: ${showFooterIcons}`);
res.render(
'index',
{
title: 'Coming Soon!',
mainText: 'Eventually Podcast',
subText: `Drop your email address below and we will let you know when we launch the Eventually podcast.
<br>Brought to you by amazing people`,
showFooterIcons,
}
);
});

app.listen(port, () => {
console.log(`Listening to requests on http://localhost:${port}`);
});
Where to get Environment ID in Flagsmith
showFooterIcons = await flagsmith.hasFeature('show_footer_icons');
extends layout

block body-content
// Header
header#header
h1 #{mainText}
p
| !{subText}
// Signup Form
form#signup-form(method='post' action='#')
input#email(type='email' name='email' placeholder='Email Address')
input(type='submit' value='Sign Up')
// Footer
footer#footer
if showFooterIcons
ul.icons
li
a.icon.brands.fa-twitter(href='#')
span.label Twitter
li
a.icon.brands.fa-instagram(href='#')
span.label Instagram
li
a.icon.brands.fa-github(href='#')
span.label GitHub
li
a.icon.fa-envelope(href='#')
span.label Email
ul.copyright
li &copy; Untitled.
li
| Credits:
a(href='http://html5up.net') HTML5 UP
// Scripts
script(src='/assets/js/main.js')

Test Node.js feature flag

npm start
Eventually podcast homepage
Flagsmith application homepage
Eventually podcast homepage without social icons

Deploy to Railway.app

npm i -g @railway/cli
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated har-validator@5.1.5: this library is no longer supported
> @railway/cli@0.2.45 preuninstall /some/path/node_modules/@railway/cli
> go-npm uninstall
> @railway/cli@0.2.45 postinstall /some/path/node_modules/@railway/cli
> go-npm install
Downloading from URL: https://github.com/railwayapp/cli/releases/download/v0.2.45/railway_0.2.45_darwin_amd64.tar.gz
+ @railway/cli@0.2.45
updated 1 package in 10.009s
railway login
Railway application login
Railway application login successful screen
Press Enter to open the browser (^C to quit)
🚝 Logging in... No dice? Try railway login --browserless
🚊 Logging in...
🎉 Logged in as Your Name (<email>@domain.com)
railway init
✔ Starting Point: Empty Project 
✔ Enter project name: eventually-podcast
✔ Environment: production
🎉 Created project eventually-podcast
Eventually podcast in the Railway application
Flagsmith application with show icons switch ‘on’
Adding Flagsmith Environment ID to Railway application
railway up
☁️ Build logs available at https://railway.app/project/c4fc117f-d04e-4a61-9788-6216fb5e5596/deployments?id=d43a6572-d418-4506-ae88-c0ce678f5c4d

==========================
Using detected Dockerfile!
==========================
Sending build context to Docker daemon 3.394MB
Step 1/9 : FROM node:14-alpine as base
---> fe39f43f1d22
Step 2/9 : WORKDIR /src

---> Running in 6bf8c2cd1fa1
Removing intermediate container 6bf8c2cd1fa1
---> 96ae9ce24569
Step 3/9 : COPY package*.json ./
---> 82cd9bd661a7
Step 4/9 : EXPOSE 3000
---> Running in 89bacb0b1d43
Removing intermediate container 89bacb0b1d43
---> 0dfd09862db1
Step 5/9 : FROM base as production
---> 0dfd09862db1
Step 6/9 : ENV NODE_ENV=production
---> Running in d4ab473be240
Removing intermediate container d4ab473be240
---> bbc350ac53b9
Step 7/9 : RUN npm ci
---> Running in 2970f701628c
added 98 packages in 1.454s
Removing intermediate container 2970f701628c
---> 99b660ab4187
Step 8/9 : COPY . ./
---> 036d470ec912
Step 9/9 : CMD ["node", "index.js"]
---> Running in 380cf6634c1c
Removing intermediate container 380cf6634c1c
---> 6e5936efd6d4
[Warning] One or more build-args [FLAGSMITH_ENVIRONMENT_ID RAILWAY_ENVIRONMENT RAILWAY_STATIC_URL] were not consumed
Successfully built 6e5936efd6d4
Successfully tagged registry.railway.app/d43a6572-d418-4506-ae88-c0ce678f5c4d:latest
======= Build Completed ======
Waiting for Deploy To Finish
☁️ Deployment logs available at https://railway.app/project/c4fc117f-d04e-4a61-9788-6216fb5e5596/deployments?id=d43a6572-d418-4506-ae88-c0ce678f5c4d
OR run `railway logs` to tail them here
☁️ Deployment live at https://eventaully-podcast-production.up.railway.app
Eventually podcast homepage with social icons
Flagsmith application with ‘show icons’ toggle ‘off’
Eventually podcast homepage without social icons

Conclusion

--

--

--

Ship features with confidence. Flagsmith lets you manage features flags and remote config across web, mobile and server side applications.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Amazon-clone using React, Stripe and Firebase (Part 3)

Step by step guide for writing awesome React components

How To Build Re-Usable Component In Angular With component Interaction-Sagar-Jaybhay

Using JavaScript Code in Flutter Web

Creating a SSR site using Next JS and improving your development.

Using redux-loop to make tacos at Grubhub

How the Pros Handle JavaScript Promises

Firebase Cloud Messaging End to End Tutorial

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Flagsmith

Flagsmith

Ship features with confidence. Flagsmith lets you manage features flags and remote config across web, mobile and server side applications.

More from Medium

Extract a Text File from included Jar Programatically (with Gradle)

Local and Remote code development using docker and VS Code

S.O.L.I.D Principles For Software Development

CS373 Spring 2022: Sahran Hashim