DEV Community

Cover image for Using Multiple Versions of a Package in a Single Project: Why and How
John Brooks
John Brooks

Posted on

Using Multiple Versions of a Package in a Single Project: Why and How

Modern software development often calls for innovative approaches to managing dependencies, especially in large-scale JavaScript projects. One such approach is using multiple versions of the same package in a single project. This method, while seemingly unconventional, addresses various needs such as ensuring legacy system support, conducting feature toggling, or facilitating A/B testing.

In this blog post, we’ll delve into the reasons behind using multiple versions of a package, with a focus on feature toggling and A/B testing, and explore how Bit can simplify this complex process.

Why Use Multiple Versions of the Same Package?

  1. Legacy Code and Gradual Updates

Legacy systems often rely on older versions of dependencies. Introducing a new version may cause incompatibilities. Using multiple versions ensures new features can leverage updated libraries while older systems remain stable.

  1. Feature Toggling

Feature toggling enables developers to control the availability of specific features without modifying the codebase. This approach is especially useful when releasing features incrementally or testing their impact.

  • Release Toggles: Delay the public release of a feature while ensuring its code is merged and tested within the main branch.

  • Experiment Toggles:(A/B Testing): Allow testing features with different user segments to determine the optimal implementation.

  • Ops Toggles: Provide operational teams with the ability to enable or disable features without deploying new code.

Feature toggling may require multiple versions of a package or component when toggling involves significant changes, such as upgrading a library or altering a core component.

Tagging Bit components with Pre-Release Versions

Bit offers the bit snap command to version your component with a hash instead of a Semantic Version, to indicate the version is no ready for release (the command also executes a slightly different build pipeline, accordingly).

For example:

'bit snap' => package-name@5475049d02fafa0eaf6885a06d36e42e0ffdc4a3
'bit tag' => package-name@1.2.3 
Enter fullscreen mode Exit fullscreen mode

However, having a hash as the component's version does not give any information about its purpose, its parent release version, or whether this "branch" of the component's history has additional iterations.

A bit snap is useful as a Bit analogy for git commit but not for experimental release versions that should be integrated into production.

To provide more information, it's recommended to use the prerelease option. For example:

bit tag forms/sign-in -m "add SSO option" --increment prerelease --prerelease-id beta
Enter fullscreen mode Exit fullscreen mode

Managing Multiple Versions of a Package

When using multiple versions of a package/Bit component, dependency aliasing is key. This approach allows teams to maintain multiple package versions within the same project.

{
 "dependencies": {
  "@my-org/my-scope.forms.sign-in": "0.0.1",
  "@my-org/my-scope.forms.sign-in-sso": "npm:@my-org/my-scope.forms/sign-in@0.0.2-beta.0",
}
Enter fullscreen mode Exit fullscreen mode

Alias names make it easy to differentiate between versions:

import { SignInForm } from "@my-org/my-scope.forms.sign-in";
import { SignInForm as SignInFormWithSso } from "@my-org/my-scope.forms.sign-in-sso"

export function SignInPage() {
 if (features.flags.sso.enabled) return <SignInFormWithSso />;
 return <SignInForm />
  );
}
Enter fullscreen mode Exit fullscreen mode

Learn more

Top comments (0)