{"_path":"/code-first-feature-flags","_draft":false,"_partial":false,"_locale":"en","_empty":false,"title":"Code-first Feature Flags","description":"You know what's annoying about using today's typical feature flag services such as LaunchDarkly, Flagsmith, and others? In order to create and manage feature flags, I have to leave my IDE and log in to their website and use their UI. I think we can do better.","excerpt":{"type":"root","children":[{"type":"element","tag":"h1","props":{"id":"code-first-feature-flags"},"children":[{"type":"text","value":"Code-first Feature Flags"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You know what's annoying about using today's typical feature flag services such as LaunchDarkly, Flagsmith, and others? In order to create and manage feature flags, I have to leave my IDE and log in to their website and use their UI. I think we can do better."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"What if I never had to leave my IDE? After all, that's where the feature flag is actually consumed."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"But first, let's rewind and walk through what creating and managing a feature flag using one of these services looks like:"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's say I'm working on implementing a new version of a feature that I know we'll want to feature flag. I've picked out the spot in my code where the logic will fork."}]},{"type":"element","tag":"code","props":{"code":"if (true) {\n  // new behavior\n} else {\n  // old behavior\n}\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"if (true) {\n  // new behavior\n} else {\n  // old behavior\n}\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I'm forced to log in to their UI, and only from there can I create the feature flag."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"img","props":{"alt":"Creating a feature flag","src":"/ff.gif"},"children":[]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Finally, I can return to my ide and start consuming my feature flag"}]},{"type":"element","tag":"code","props":{"code":"if (flagsmith.hasFeature('my_feature')) {\n  // new behavior\n} else {\n  // old behavior\n}\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"if (flagsmith.hasFeature('my_feature')) {\n  // new behavior\n} else {\n  // old behavior\n}\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"That was annoying. I was forced to context switch away from code to the feature flag UI."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Why can't I just define my feature flag in the code, and have it appear in the UI for non technical folks to interact with?"}]},{"type":"element","tag":"code","props":{"code":"const flags = setupFlags([\n  {\n    name: 'my_feature',\n    description: 'Determines whether or not to enable my feature',\n    default: false,\n  },\n])\n\nif (flags.hasFeature('my_feature')) {\n  // new behavior\n} else {\n  // old behavior\n}\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"const flags = setupFlags([\n  {\n    name: 'my_feature',\n    description: 'Determines whether or not to enable my feature',\n    default: false,\n  },\n])\n\nif (flags.hasFeature('my_feature')) {\n  // new behavior\n} else {\n  // old behavior\n}\n"}]}]}]}]},"date":"2022-07-31","body":{"type":"root","children":[{"type":"element","tag":"h1","props":{"id":"code-first-feature-flags"},"children":[{"type":"text","value":"Code-first Feature Flags"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You know what's annoying about using today's typical feature flag services such as LaunchDarkly, Flagsmith, and others? In order to create and manage feature flags, I have to leave my IDE and log in to their website and use their UI. I think we can do better."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"What if I never had to leave my IDE? After all, that's where the feature flag is actually consumed."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"But first, let's rewind and walk through what creating and managing a feature flag using one of these services looks like:"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's say I'm working on implementing a new version of a feature that I know we'll want to feature flag. I've picked out the spot in my code where the logic will fork."}]},{"type":"element","tag":"code","props":{"code":"if (true) {\n  // new behavior\n} else {\n  // old behavior\n}\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-df7817"},"children":[{"type":"text","value":"if"}]},{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"class":"ct-01f2c5"},"children":[{"type":"text","value":"true"}]},{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":") {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":"  "}]},{"type":"element","tag":"span","props":{"class":"ct-18185c"},"children":[{"type":"text","value":"// new behavior"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":"} "}]},{"type":"element","tag":"span","props":{"class":"ct-df7817"},"children":[{"type":"text","value":"else"}]},{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":" {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":"  "}]},{"type":"element","tag":"span","props":{"class":"ct-18185c"},"children":[{"type":"text","value":"// old behavior"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":"}"}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I'm forced to log in to their UI, and only from there can I create the feature flag."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"img","props":{"alt":"Creating a feature flag","src":"/ff.gif"},"children":[]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Finally, I can return to my ide and start consuming my feature flag"}]},{"type":"element","tag":"code","props":{"code":"if (flagsmith.hasFeature('my_feature')) {\n  // new behavior\n} else {\n  // old behavior\n}\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-df7817"},"children":[{"type":"text","value":"if"}]},{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":" (flagsmith."}]},{"type":"element","tag":"span","props":{"class":"ct-9e2825"},"children":[{"type":"text","value":"hasFeature"}]},{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"class":"ct-68e771"},"children":[{"type":"text","value":"'"}]},{"type":"element","tag":"span","props":{"class":"ct-028a11"},"children":[{"type":"text","value":"my_feature"}]},{"type":"element","tag":"span","props":{"class":"ct-68e771"},"children":[{"type":"text","value":"'"}]},{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":")) {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":"  "}]},{"type":"element","tag":"span","props":{"class":"ct-18185c"},"children":[{"type":"text","value":"// new behavior"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":"} "}]},{"type":"element","tag":"span","props":{"class":"ct-df7817"},"children":[{"type":"text","value":"else"}]},{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":" {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":"  "}]},{"type":"element","tag":"span","props":{"class":"ct-18185c"},"children":[{"type":"text","value":"// old behavior"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":"}"}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"That was annoying. I was forced to context switch away from code to the feature flag UI."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Why can't I just define my feature flag in the code, and have it appear in the UI for non technical folks to interact with?"}]},{"type":"element","tag":"code","props":{"code":"const flags = setupFlags([\n  {\n    name: 'my_feature',\n    description: 'Determines whether or not to enable my feature',\n    default: false,\n  },\n])\n\nif (flags.hasFeature('my_feature')) {\n  // new behavior\n} else {\n  // old behavior\n}\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-df7817"},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":" flags "}]},{"type":"element","tag":"span","props":{"class":"ct-df7817"},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"class":"ct-9e2825"},"children":[{"type":"text","value":"setupFlags"}]},{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":"(["}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":"  {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":"    name"}]},{"type":"element","tag":"span","props":{"class":"ct-df7817"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"class":"ct-68e771"},"children":[{"type":"text","value":"'"}]},{"type":"element","tag":"span","props":{"class":"ct-028a11"},"children":[{"type":"text","value":"my_feature"}]},{"type":"element","tag":"span","props":{"class":"ct-68e771"},"children":[{"type":"text","value":"'"}]},{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":","}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":"    description"}]},{"type":"element","tag":"span","props":{"class":"ct-df7817"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"class":"ct-68e771"},"children":[{"type":"text","value":"'"}]},{"type":"element","tag":"span","props":{"class":"ct-028a11"},"children":[{"type":"text","value":"Determines whether or not to enable my feature"}]},{"type":"element","tag":"span","props":{"class":"ct-68e771"},"children":[{"type":"text","value":"'"}]},{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":","}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":"    default"}]},{"type":"element","tag":"span","props":{"class":"ct-df7817"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"class":"ct-01f2c5"},"children":[{"type":"text","value":"false"}]},{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":","}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":"  },"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":"])"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-df7817"},"children":[{"type":"text","value":"if"}]},{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":" (flags."}]},{"type":"element","tag":"span","props":{"class":"ct-9e2825"},"children":[{"type":"text","value":"hasFeature"}]},{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"class":"ct-68e771"},"children":[{"type":"text","value":"'"}]},{"type":"element","tag":"span","props":{"class":"ct-028a11"},"children":[{"type":"text","value":"my_feature"}]},{"type":"element","tag":"span","props":{"class":"ct-68e771"},"children":[{"type":"text","value":"'"}]},{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":")) {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":"  "}]},{"type":"element","tag":"span","props":{"class":"ct-18185c"},"children":[{"type":"text","value":"// new behavior"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":"} "}]},{"type":"element","tag":"span","props":{"class":"ct-df7817"},"children":[{"type":"text","value":"else"}]},{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":" {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":"  "}]},{"type":"element","tag":"span","props":{"class":"ct-18185c"},"children":[{"type":"text","value":"// old behavior"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"class":"ct-18d2a6"},"children":[{"type":"text","value":"}"}]}]}]}]}]},{"type":"element","tag":"style","children":[{"type":"text","value":".ct-028a11{color:#E7EE98}.ct-68e771{color:#DEE492}.ct-9e2825{color:#62E884}.ct-18185c{color:#7B7F8B}.ct-01f2c5{color:#BF9EEE}.ct-18d2a6{color:#F6F6F4}.ct-df7817{color:#F286C4}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"_type":"markdown","_id":"content:code-first-feature-flags.md","_source":"content","_file":"code-first-feature-flags.md","_extension":"md"}