Building a Simple, Scalable Feature Flag System

Kunal Singh

Jul 6, 2025

Feature flags are a powerful way to control your application's behavior without needing to redeploy. Recently, I needed to implement a clean, backend-driven feature flag system to enable or disable features globally or per account. Here's how we did it using just Next.js API routes, Prisma, and a simple frontend fetch approach. No extra libraries or state management layers involved.


🌐 The Goal

We wanted to:

  • Define feature flags that are either global or account-specific
  • Let the backend serve the flags
  • Have a simple way to access those flags on the client

📄 Database Schema (Prisma)

model FeatureFlag {
id String @id @default(uuid())
flagKey String
value Boolean
scope FlagScope
accountId String?
updatedAt DateTime @updatedAt
}

enum FlagScope {
global
account
}

This allows each flag to be:

  • Global: applies to everyone
  • Account-level: overrides global for a specific account

🚀 API Endpoint to Fetch Flags

We expose an endpoint at /api/featureFlags. It optionally accepts an accountId.

If you pass the account ID, it fetches both global and account-specific flags.

GET /api/featureFlags?accountId=abc123

Example Response

{
"success": true,
"flags": {
"global": {
"newDashboard": false
},
"account": {
"abc123": {
"newDashboard": true
}
}
}
}

💪 Using Flags on the Frontend

Just make a fetch call during getServerSideProps or useEffect:

const res = await fetch(`/api/featureFlags?accountId=${accountId}`);
const { flags } = await res.json();

const isNewDashboardEnabled =
flags.account?.[accountId]?.newDashboard ??
flags.global?.newDashboard ??
false;

No Redux, no state libraries — just native fetch.


➕ Adding a New Flag

  1. Add a global default:
INSERT INTO "FeatureFlag" (
id, flagKey, value, scope, accountId, updatedAt
) VALUES (
gen_random_uuid(), 'someFeature', false, 'global', NULL, CURRENT_TIMESTAMP
);
  1. Optionally override for an account:
INSERT INTO "FeatureFlag" (
id, flagKey, value, scope, accountId, updatedAt
) VALUES (
gen_random_uuid(), 'someFeature', true, 'account', 'abc123', CURRENT_TIMESTAMP
);

✨ Final Thoughts

You don’t always need a fancy flag service or state management solution. If you're working with a small team or MVP, this setup can take you very far.

It’s easy to build, debug, and extend — and more importantly, keeps your logic flexible across environments and users.


Let me know if you’re implementing something similar or want to share ideas on improving this further!

Recommendations

I Refactored Without Changing a Feature — And It Broke Everything

#HyrumsLaw

,

#Refactoring

,

#LegacyCode

,

#CodeSmells

,

#TechDebt

,

#SoftwareEngineering

,

#CleanCode

Understanding Hyrum’s Law with a Real-World Lesson on Porting vs Refactoring

Jul 5, 2025

How to Publish Your First npm Package: Creating Rainbow Highlight with Utilities

#npm

,

#npm-package

,

#web

,

#javascript

Learn how to create and publish your first npm package. This step-by-step guide...

Sep 22, 2024

Google Dorking: Unlocking Hidden Search Capabilities & Insights

#seach

,

#seo

,

#research

Explore 16 advanced Google Dorking techniques to uncover valuable data, security...

Aug 8, 2024

This One HTML Attribute Could Save Your Web App from a Security Nightmare

#web-security

,

#cdn

,

#web

Web security is a critical concern for developers, yet some of the most...

Jun 29, 2024

Are You Still Using Basic CSS? Here Are 7 Tricks to Get Ahead of the Curve

#css

Bored of the same old CSS? Unleash 7 hidden gems to take your designs to the...

Dec 27, 2023

Easiest way to store your logs in a file WITHOUT chaging the source file(node)

#productivity

Often, developers face challenges when dealing with a flood of logs in the...

Dec 21, 2023

Build Your Own Pinterest-Style Masonry Grid: A Step-by-Step Guide

#css

,

#web

,

#layout

Create a masonary grid layout with left to right content flow, supporting...

Dec 10, 2023

Using git diff and git apply to Share Local Changes with Peers

#git

,

#productivity

,

#software_engeneering

,

#dev

git diff and git apply are two powerful Git commands that can be used to share...

Nov 12, 2023

React Portals: Render Components Outside the current DOM Hierarchy

#react

,

#web

The createPortal API in React allows you to render child elements into a...

Jul 27, 2023

Cloning Made Easy: Try degit and Clone Directories within Repos.

#git

,

#productivit

Have you ever faced the dilemma of wanting just a small portion of a repository,...

Jul 19, 2023

Debugging Web Apps with Browser Dev Tools: 6 Amazing Tricks

#browser

,

#debugging

,

#web

Debugging web applications can be a challenging task, with errors like...

Jul 13, 2023

Controlled Versus Uncontrolled Components in React

#react

,

#forms

Understanding State Management Within Forms Comparing controlled and...

Nov 5, 2022

Format Numbers, Dates and Currencies with the Intl Object in Javascript

#javascript

,

#html

,

#web

Intl object can be used to format data into commonly used formats of dates,...

Sep 13, 2022

Image Masking on Hover Using CSS Clip Path and Javascript

#javscript

,

#css

,

#html

Image Masking can be used to add fancy hover highlight effects to images for...

Jul 23, 2022

Recreating CSS Tricks Fancy Grid Hover Effect

#html

,

#css

,

#UI

,

#recreation

CSS Trick had a simple yet cool grid layout which I found dope. So lets try to...

May 21, 2022

File Explorer Recursive React Component

#react

,

#javascript

,

#web

How to create a recursive folder Component using react.

Apr 16, 2022

Add Google Fonts to Your React & NextJS + TailwindCSS Project (Next 14)

#css

,

#tailwindcss

,

#react

,

#nextjs

,

#tailwind

,

#design

Use Google Fonts in Your TailwindCSS Projects

Apr 6, 2022

Event Delegation in Javascript

#javscript

,

#css

,

#html

,

#web

,

#performance

Handling multiple Events in Javascript with minimal CPU Usage

Mar 6, 2022

A Simple Web Accessibility Trick that you most probably missed!

#html

,

#css

,

#web-accessibility

,

#user-experience

Imagine that you cannot use the mouse and have to Navigate a Website with the...

Dec 23, 2021

Top Terminal Commands I Use For Productivity

#linux

,

#cli

,

#terminal

The whole point of development is solving problems. But very often we Developers...

Nov 3, 2021

CSS Logical Properties

#css

,

#html

CSS logical properties are properties which are used to design element on the...

Oct 5, 2021

Fluid Typography in CSS 💧

#css

,

#html

,

#typography

CSS Best Practices in Fluid Typography

Aug 15, 2021

CSS Units in a Nutshell 🐚

#css

,

#html

Are you still writing your css units in pixels and percentages? if you are then...

Aug 8, 2021

Master Markdown in 5minutes ⌚

#markdown

,

#documentation

Markdown is a lightweight markup language for creating formatted text using a...

Aug 1, 2021

What is JAMStack ✨

#jamstack

Jamstack stands for Javascript APIS and Markup and it is based on this idea of...

Jul 31, 2021

+

Check my latest Blog Post

Building a Simple, Scalable Feature Flag System

Read Now
Oh My Gawwdd!!!!!!!

Wow you have been viewing my site since 20 seconds!

+
+