Skip to main content

Best practices for versioning UI extensions

To maintain stability and ensure smooth transitions when updating UI extensions, include a version suffix in the ID of the extension point or exposed component. This practice preserves compatibility while allowing developers to manage breaking changes in a controlled way.

Use a version suffix in the ID​

Each extension point ID/component ID should include a suffix indicating the major version of the extension.

Example:

// Initial version
export const EXTENSION_POINT_OR_COMPONENT_ID_V1 = 'my-plugin-id/feature/v1';

// Breaking change introduced
export const EXTENSION_POINT_OR_COMPONENT_ID_V2 = 'my-plugin-id/feature/v2';
  • Non-breaking changes (for example, adding optional properties) do not require a new version suffix.
  • Breaking changes (for example, modifying behaviors or removing properties) must introduce a new version suffix.

Support multiple versions during transition​

When introducing a new major version, the application should serve both the old and new versions for a transition period. This allows consumers time to migrate without immediate disruptions.

Example:

  • my-plugin-id/feature/v1 continues to function while my-plugin-id/feature/v2 is introduced.
  • Consumers gradually migrate to v2.
  • After a deprecation period for v1, you can safely remove it.

Clearly communicate deprecations​

Deprecation should be clearly communicated to consumers to ensure a smooth transition.

  • Use the @deprecated keyword in published types and reference the changelog or migration guide.

    Example:

    /**
    * @deprecated Use FeatureConfigV2 instead. See migration guide: https://example.com/migration-guide
    */
    export type FeatureContextV1 = {
    /* ... */
    };
  • Document changes in a changelog or migration guide.

  • Provide a timeline for deprecating older versions.

  • Notify consumers of upcoming changes to prevent unexpected breakages.

Publish types with version suffixes​

note

This option is currently only availabe for plugins developed within the grafana organization.

To support consuming multiple versions simultaneously, publish types to @grafana/plugin-types using the same version suffix. This allows developers to import types from different versions without conflicts.

Example:

// Extension point context
import { FeatureContextV1 } from '@grafana/plugin-types/my-plugin-id';
import { FeatureContextV2 } from '@grafana/plugin-types/my-plugin-id';

// Exposed component props
import { ComponentPropsV1 } from '@grafana/plugin-types/my-plugin-id';
import { ComponentPropsV2 } from '@grafana/plugin-types/my-plugin-id';
  • Ensures type safety when working with different extension versions.
  • Avoids breaking existing consumers when introducing changes.

Summary​

By following this approach to version extensions and extension points, you can ensure they remain stable while allowing for iterative improvements, smooth migrations, and safer type management.

Grafana Labs uses cookies for the normal operation of this website. Learn more.