5 min read

How OpenFeature was the key to escaping Feature Flag vendor lock-in: A Vue.js story

Discover how we effortlessly transitioned a VueJS project to a new feature flag Provider in just a few lines of code thanks to OpenFeature.
How OpenFeature was the key  to escaping Feature Flag vendor lock-in: A Vue.js story
A Vue developer about to discover whether OpenFeature can help them escape feature flag vendor lock-in

If you've been tuning into our little corner of the internet here at DevCycle, you're well aware that we're pretty big fans of OpenFeature. Lately, we've been busy weaving support for it across all our SDKs and whipping up example apps left and right. Why? To show off just how easy it is to slot OpenFeature into your apps, no matter which of the top frameworks you're playing with these days.

In a recent adventure here in the DevCycle blog, I dove headfirst into our example PHP app, implementing OpenFeature compliant flags and uncovering a few "gotchas" along the way. If you've read the post, I'm sure you'd agree that it could easily have spiraled into a series about the nitty-gritty of swapping out vendor-specific feature flags for OpenFeature goodness in various frameworks. But, for my next post, I wanted to go beyond just the raw implementation steps and tackle something a bit juicer.

Enter the idea that implementation of OpenFeature frees you from the clutches of vendor lock-in.

If there's any truth to this, I figured, flipping an existing project to a different Provider with OpenFeature should be a walk in the park, with most of the legwork coming down to tweaking the SDK setup. And thus a new blog post was born!

Setting up the Test

So, for this little experiment, I zeroed in on a VueJS project I'd recently spruced up with OpenFeature, and set my sights on FeatBit as the new Provider. Why FeatBit, you ask? Two big reasons:

  • First, it's one of the few feature flag management platforms that currently offers an OpenFeature compliant client-side JavaScript provider that plays nice with Vue apps.
  • Second, it has an amazing onboarding (read: DX) experience, letting you spin up a test instance of their slick open-source feature flag system with nothing more than a click on their homepage.

While the onboarding process included in the FeatBit dashboard offers a solid starting point with their SDKs for many scenarios, our journey into OpenFeature territory meant the usual UI shortcuts weren't on the table. Instead, we had to dive deep into the Featbit provider repositories nestled within their GitHub organization to find a basic example application.

GitHub - featbit/openfeature-provider-js-client
Contribute to featbit/openfeature-provider-js-client development by creating an account on GitHub.

This, it turned out, was our treasure map to integrating FeatBit into our existing OpenFeature's example application.

Taking the first steps...

package.json was the first stop on our OpenFeature adventure. Here things kicked off with the removal of DevCycle specific packages and the addition of:

  • @featbit/openfeature-provider-js-client
  • @openfeature/web-sdk
  • featbit-js-client-sdk

The logical progression then led us to devcycle.js, the heart of our original integration. In a move towards a more provider-agnostic future, we re-christened it to provider.js before moving into the nuts and bolts of how we instantiated the new Provider.

As you can see in our original VueJS example project repo, the instantiation process was fairly straightforward:

  1. Fetch the SDK key from our environment file,
  2. Conjure up a simple options object, and then
  3. Blend these two ingredients to summon a new DevCycle Provider.

With the Provider ready to go, we could then set the OpenFeature context to our Users object, attach the provider to the OpenFeature instance, and finally lay our hands on our OpenFeature client.

export const setUpOpenFeature = async () => {
  const DEVCYCLE_CLIENT_SDK_KEY = import.meta.env.VITE_DEVCYCLE_CLIENT_SDK_KEY;
  if (!DEVCYCLE_CLIENT_SDK_KEY) {
    alert(
      "Set your VITE_DEVCYCLE_CLIENT_SDK_KEY environment variable to use the DevCycle JavaScript SDK."
    );
  }

  const devcycleOptions = { logLevel: "debug" };
  
  devcycleProvider = new DevCycleProvider(
    DEVCYCLE_CLIENT_SDK_KEY,
    devcycleOptions
  );
  
  await OpenFeature.setContext(users[0]);
  
  await OpenFeature.setProviderAndWait(devcycleProvider);

  return OpenFeature.getClient();
};

Original DevCycle Provider Instantiation Process

Pivoting to FeatBit introduced a subtle change in our approach. The previously simple options array evolved into a more complex entity, tasked with not only carrying the SDK key and user object but also the API endpoint—essential for tapping into FeatBit's self-hosting capabilities. This enriched options object enabled us to craft a new Provider, attach it to our OpenFeature instance, and finally, access the client itself.

export const setUpOpenFeature = async () => {

  const SDK_KEY = import.meta.env.VITE_SDK_KEY;
  if (!SDK_KEY) {
    alert("Set your SDK_KEY environment variable to OpenFeature Web SDK.");
  }

  const providerOptions = {
    secret: SDK_KEY,
    api: "https://featbit-tio-eu-eval.azurewebsites.net",
    user: users[0],
  };

  provider = new FbProvider(providerOptions);

  await OpenFeature.setProviderAndWait(provider);

  return OpenFeature.getClient();
};

Instantiation Process for the Featbit Provider

This shift in managing the user object was also a signal that the ripples of change extended beyond just the Provider configuration. And so, taking a look at user.js, there was one more change needed, with all occurrences of user_id within the user array updated to keyId to gel with FeatBit's requirements.

Venturing into the .vue files marked the final phase of our adaptation. This stage was less about dramatic transformation and more about fine-tuning—updating import paths and stripping away DevCycle-centric enchantments. A notable task here was excising the getVarationName logic from our example app, a functionality unique to DevCycle that found no counterpart in FeatBit's domain, an oddity I've previously explored.

The Verdict

What stands out in this journey isn't necessarily in the steps taken but the sheer efficiency of the transition:

  • user.js: 3 lines revised, with no additions or removals.
  • Togglebot.vue: 9 lines excised, no additions or revisions.
  • App.vue: A single line removed, another revised, and no additions.
  • .env.sample: 1 line revised, standing unaltered otherwise.
  • provider.js: A modest reshuffle with 2 lines removed and 10 lines revised.

In total, a mere 20 lines of code underwent modification, concentrated largely within a single file. Even allowing for a margin of error—say, an extra 25%—the simplicity of this vendor switch is undeniable. To be honest, it took far more time to write this blog post than it did to spin-up a Featbit instance, learn the platform, update our existing example application and make a tweet about it!

If this doesn't epitomize a streamlined process for transitioning between Providers, I'm at a loss for what does.

Where can I access your code?

Visit the DevCycle Labs GitHub organization to explore the repository for our new VueJS OpenFeature example application and see these modifications in practice:

GitHub - DevCycleHQ-Labs/example-openfeature-vue3: An example app built using Vue3 and the OpenFeature Web SDK
An example app built using Vue3 and the OpenFeature Web SDK - DevCycleHQ-Labs/example-openfeature-vue3

Where can I read more about OpenFeature?

Interested in reading more about our experience with this new standard in feature flagging? Then be sure to check out the new OpenFeature category here in our blog!

OpenFeature - DevCycle
DevCycle is a proud supporter of the OpenFeature ecosystem and we are excited to share insights on this transformative approach to feature flagging. Stay tuned for content that explores the benefits, best practices, and our journey with OpenFeature