Maven plugin for Vaadin Flow applications that handles frontend resource management, webpack bundling, and development workflow automation
npx @tessl/cli install tessl/maven-com-vaadin--vaadin-maven-plugin@24.9.0The Vaadin Maven Plugin is a comprehensive build tool for Vaadin Flow applications that handles frontend resource management, webpack bundling, and development workflow automation. It provides Maven goals for preparing frontend dependencies, building production bundles, and managing the complete lifecycle of modern web applications built with the Vaadin Flow framework.
pom.xml (see Basic Usage)The plugin is configured in the Maven pom.xml build section:
<build>
<plugins>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<version>24.9.0</version>
</plugin>
</plugins>
</build><build>
<plugins>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<version>24.9.0</version>
<executions>
<execution>
<goals>
<goal>prepare-frontend</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>Run goals via Maven:
mvn flow:prepare-frontend
mvn flow:build-frontendPrepares the development environment by verifying Node.js/npm installation and setting up frontend dependencies.
<goal>prepare-frontend</goal>The prepare-frontend goal verifies requirements, copies frontend resources from JAR dependencies, and generates configuration files.
Builds optimized frontend bundles for production deployment with complete dependency management.
<goal>build-frontend</goal>The build-frontend goal creates production-ready bundles with npm dependency installation and webpack optimization.
Cleans frontend files and removes generated artifacts to reset the project to a clean state.
<goal>clean-frontend</goal>
<!-- Easter egg alias -->
<goal>dance</goal>Both goals remove node_modules, lock files, and generated frontend artifacts.
Converts legacy Polymer-based components to modern Lit framework for improved performance and maintainability.
<goal>convert-polymer</goal>Automated conversion tool for migrating Polymer templates to Lit components.
Generates CycloneDX SBOM files for both backend (Maven) and frontend (npm) dependencies for security and compliance.
<goal>generate-maven-sbom</goal>
<goal>generate-npm-sbom</goal>Creates standardized SBOM files for dependency tracking and vulnerability analysis.
Generates CycloneDX SBOM files for backend Java dependencies for security compliance and vulnerability analysis.
<goal>generate-maven-sbom</goal>Creates standardized SBOM files for Maven dependency tracking and security analysis.
Generates CycloneDX SBOM files for frontend npm dependencies for complete dependency visibility.
<goal>generate-npm-sbom</goal>Creates SBOM files for frontend dependency tracking and vulnerability scanning.
<configuration>
<frontendDirectory>${project.basedir}/src/main/frontend</frontendDirectory>
<npmFolder>${project.basedir}</npmFolder>
<javaSourceFolder>${project.basedir}/src/main/java</javaSourceFolder>
<javaResourceFolder>${project.basedir}/src/main/resources</javaResourceFolder>
</configuration><configuration>
<nodeVersion>v18.17.0</nodeVersion>
<nodeAutoUpdate>true</nodeAutoUpdate>
<nodeDownloadRoot>https://nodejs.org/dist/</nodeDownloadRoot>
<requireHomeNodeExec>false</requireHomeNodeExec>
</configuration><configuration>
<pnpmEnable>true</pnpmEnable>
<bunEnable>false</bunEnable>
<useGlobalPnpm>false</useGlobalPnpm>
<postinstallPackages>
<param>package-name-1</param>
<param>package-name-2</param>
</postinstallPackages>
</configuration><configuration>
<productionMode>false</productionMode>
<optimizeBundle>true</optimizeBundle>
<generateBundle>true</generateBundle>
<commercialWithBanner>false</commercialWithBanner>
<reactEnable>null</reactEnable>
</configuration><configuration>
<frontendHotdeploy>null</frontendHotdeploy>
<skipDevBundleRebuild>false</skipDevBundleRebuild>
<frontendIgnoreVersionChecks>false</frontendIgnoreVersionChecks>
<npmExcludeWebComponents>false</npmExcludeWebComponents>
<frontendExtraFileExtensions>
<param>extension1</param>
<param>extension2</param>
</frontendExtraFileExtensions>
</configuration><configuration>
<applicationIdentifier>my-app</applicationIdentifier>
<eagerServerLoad>null</eagerServerLoad>
<generatedTsFolder>${frontendDirectory}/generated</generatedTsFolder>
<openApiJsonFile>${project.build.directory}/generated-resources/openapi.json</openApiJsonFile>
</configuration><!-- Directory path configuration -->
<frontendDirectory>path</frontendDirectory>
<npmFolder>path</npmFolder>
<generatedTsFolder>path</generatedTsFolder>
<javaSourceFolder>path</javaSourceFolder>
<javaResourceFolder>path</javaResourceFolder>
<resourceOutputDirectory>path</resourceOutputDirectory>
<frontendOutputDirectory>path</frontendOutputDirectory>
<frontendResourcesDirectory>path</frontendResourcesDirectory>
<projectBuildDir>path</projectBuildDir>
<!-- Boolean flags -->
<productionMode>true|false|null</productionMode>
<generateBundle>true|false</generateBundle>
<runNpmInstall>true|false</runNpmInstall>
<optimizeBundle>true|false</optimizeBundle>
<pnpmEnable>true|false</pnpmEnable>
<bunEnable>true|false</bunEnable>
<useGlobalPnpm>true|false</useGlobalPnpm>
<nodeAutoUpdate>true|false</nodeAutoUpdate>
<requireHomeNodeExec>true|false</requireHomeNodeExec>
<commercialWithBanner>true|false</commercialWithBanner>
<skipDevBundleRebuild>true|false</skipDevBundleRebuild>
<frontendIgnoreVersionChecks>true|false</frontendIgnoreVersionChecks>
<npmExcludeWebComponents>true|false</npmExcludeWebComponents>
<generateEmbeddableWebComponents>true|false</generateEmbeddableWebComponents>
<ciBuild>true|false</ciBuild>
<forceProductionBuild>true|false</forceProductionBuild>
<cleanFrontendFiles>true|false</cleanFrontendFiles>
<!-- Boolean or null flags -->
<reactEnable>true|false|null</reactEnable>
<frontendHotdeploy>true|false|null</frontendHotdeploy>
<eagerServerLoad>true|false|null</eagerServerLoad>
<!-- String values -->
<nodeVersion>version</nodeVersion>
<nodeDownloadRoot>url</nodeDownloadRoot>
<applicationIdentifier>identifier</applicationIdentifier>
<!-- Array values -->
<postinstallPackages>
<param>package-name-1</param>
<param>package-name-2</param>
</postinstallPackages>
<frontendExtraFileExtensions>
<param>extension1</param>
<param>extension2</param>
</frontendExtraFileExtensions>Control which dependencies are scanned for frontend resources:
<frontendScanner>
<enabled>true</enabled>
<includeOutputDirectory>true</includeOutputDirectory>
<includes>
<include>
<groupId>com.vaadin*</groupId>
<artifactId>*</artifactId>
</include>
</includes>
<excludes>
<exclude>
<groupId>com.example</groupId>
<artifactId>unwanted-*</artifactId>
</exclude>
</excludes>
</frontendScanner>The plugin provides detailed error messages and troubleshooting guidance:
nodeVersion and nodeDownloadRootrequireHomeNodeExecmvn -X for detailed diagnosticsCommon troubleshooting approaches:
mvn flow:clean-frontend to reset frontend state-X flag