Skip to content

Document pinning npm versions from an add-on (META-INF/VAADIN/versions/) #6167

Description

@peholmst

Tell us about your request

Since Vaadin 25.3, an add-on JAR can pin the npm versions its Java code needs by shipping a versions file in META-INF/VAADIN/versions/ (vaadin/flow#25308, listed under Breaking Changes in the Flow 25.3.0 release notes). The only place the docs mention it is a short note in the upgrade guide (articles/upgrading/index.adoc, npm Version Pinning Moved to META-INF/VAADIN/versions), which tells add-on authors to move their versions file without explaining what one is or how to write it.

The add-on section, articles/building-apps/components, doesn't cover it at all. It should, since this is how an add-on that wraps a JavaScript library makes sure applications resolve the exact npm version the wrapper was built against, including transitive packages.

What changed in Flow

  • Flow reads every .json file in META-INF/VAADIN/versions/ on the classpath, from whichever JAR ships it, and merges them into one set of pinned packages. Previously it read only vaadin-core-versions.json and vaadin-versions.json at the classpath root, which only the platform ships. Files left at the old locations are no longer read.
  • The pins end up in the generated package.json and in the npm, pnpm, and Bun overrides.
  • If several files pin the same package to different versions, the newest version wins and the build logs a warning naming both files.
  • A file can exclude packages with an exclusions array. Only such declared exclusions apply across all files.
  • A malformed or unreadable file is skipped with a warning; other files still apply. A package with a name but no version is skipped with a warning.
  • A platform field in an add-on's file is ignored. Only the platform's own files determine the Vaadin version.
  • Constants.VAADIN_CORE_VERSIONS_JSON and Constants.VAADIN_VERSIONS_JSON are removed, replaced by Constants.PINNED_NPM_VERSIONS_FOLDER.

Example from the PR, src/main/resources/META-INF/VAADIN/versions/acme-charts-versions.json:

{
  "acme": {
    "charts": {
      "npmName": "@acme/charts",
      "jsVersion": "4.2.1",
      "exclusions": ["@acme/charts-legacy-shim"]
    }
  }
}

No build plugin or registration is needed. Any application with the add-on on its classpath gets @acme/charts pinned to 4.2.1, and @acme/charts-legacy-shim excluded.

Suggested changes

  • articles/building-apps/components/package-component.adoc: add a section on pinning npm versions, next to Frontend Resources. Cover where the file goes, its format (npmName, jsVersion, exclusions, and whether the nesting keys matter), and the merge and conflict rules. Also explain how it relates to the version in @NpmPackage: when a pin is needed on top of the annotation, for example for transitive dependencies.
  • The wrapping articles (wrap-web-component.adoc The Three Annotations, wrap-js-library.adoc, and wrap-react-component.adoc) could link to it from where they explain @NpmPackage.
  • Consider linking the upgrade guide note to the new section, so add-on authors moving an existing versions file know where to find the format.
  • Mark the new content with a since badge for 25.3.

Things to confirm with the Flow team before writing: the full file format (fields such as mode-specific entries, which the PR mentions but doesn't show), and the recommended way to combine a pin with @NpmPackage.


If you think this issue is important, add a 👍 reaction to help the community and maintainers prioritize this issue.

🤖 Generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions