Vaadin web components: a standards-based component kit for Vaadin 20 and up
A set of high-quality standards based web components for enterprise web applications. Part of Vaadin 20+
At a glance
- What is it?
- The Vaadin web components repository is a monorepo of custom elements for business web applications, each published as its own npm package under the @vaadin scope, with a next distribution tag for pre-releases and a release pipeline that generates custom element manifests, web types and React wrappers. It suits teams building a Vaadin application who want the component set to keep pace with the platform.
- Who is it for?
- Vaadin web components is the right choice for a team already on Vaadin 20 or later that wants the platform's component set, with per component packages, theme packages and generated tooling, rather than assembling a component library by hand. It is the wrong choice for a plain JavaScript or React application that has no Vaadin dependency, and for a team that needs a component set with a single supported version rather than a latest and a next line.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
An evolving component set for business applications
The Vaadin web components project is described as an evolving set of high-quality web components for business web applications, and the repository description adds that it is part of Vaadin 20 and up. The homepage for the components is vaadin.com/docs/latest/components, which is also where the documentation and live examples live.
The word business is doing real work in that sentence. These are not marketing widgets or a design toy. The component list in the README is the argument: accordion, app-layout, avatar, avatar-group, badge, breadcrumbs, button, card, checkbox, checkbox-group, and so on, each with its own directory under `packages/`, its own npm package under the `@vaadin` scope, and its own label for issues on GitHub. Application layout, navigation, forms and data display are the parts of an interface that a business application needs in quantity, and they are the parts that are painful to get right and painful to keep consistent.
They are standards based. Each component is a custom element, which the repository topics list as `custom-elements`, and the custom element manifest tooling in the build pipeline confirms the approach. That means the components are plain DOM with properties, attributes and events, and a framework is optional. That is the key architectural difference from a server-driven UI framework, and it is why the repository also contains a `react/` directory and a set of React wrapper build scripts.
The project is JavaScript with TypeScript configuration, the last push was on 2026-10-20, and the recent releases include v25.3.3 and v25.2.15 on 2026-10-12 along with a v25.4.0-alpha3 pre-release. The README states that the core components are licensed under the Apache License 2.0, and the repository's own licence field is reported as unknown, which is a detail worth checking against the individual package licences before you vendor anything.
One npm package per component, each with a latest and a next tag
The README's component table has four columns per component, and the middle two are the interesting ones: the npm version, latest, and the npm version, next, followed by a link to that component's issue label.
Every component is published separately. The accordion lives in `packages/accordion` and is published as `@vaadin/accordion`, the button in `packages/button` as `@vaadin/button`, and so on for every entry in the table. The row for the button, for instance, links to the button package directory, to the npm page for `@vaadin/button` and to the npm page for `@vaadin/button/next`.
The dual tag is the operational detail that matters. `latest` is the stable line, `next` is the pre-release line, and a project that wants to move early installs from the `next` tag and upgrades by changing a version range. A component library that shipped one package with one version would force every consumer onto the same upgrade schedule, which for a library of thirty components used by many applications is a real cost. Per component versioning with parallel tags is the compromise the project has chosen, and it explains the release script structure later in the pipeline.
The table also documents where to report problems. Each component has its own GitHub issue label, so a bug in the grid is not filed against the grid and everything else. For a project with this many components, that labelling discipline is what keeps the issue tracker usable.
The scope boundary is stated too: this project contains components for Vaadin 20 and later, and for older Vaadin versions you should look at the individual repositories. A team that has not upgraded past Vaadin 19 should not expect these packages to match its platform.
The release pipeline generates manifests, web types and React wrappers
The root manifest is where the architecture of the monorepo becomes visible, and the release script is the clearest single line of evidence.
"release": "yarn release:themes && yarn release:cem && yarn release:meta && yarn release:web-types && yarn release:react",Five stages, in a specific order, and each one has its own script.
The theme stage comes first, building the `@vaadin/aura` and `@vaadin/vaadin-lumo-styles` packages. The next stage runs the custom elements manifest analyzer with the repository's own configuration and then splits the result with a script in the manifest directory. The custom elements manifest is the machine-readable description of a custom element API, and splitting it is how a single analysis of the whole monorepo becomes per component manifests.
"release:cem": "custom-elements-manifest analyze --config manifest/custom-elements-manifest.config.js && node manifest/scripts/split-cem.js",The meta stage generates meta packages with a script called `generateMetaPackages.js`, the web types stage builds web types with `buildWebtypes.js`, and the React stage builds the `@vaadin/react-components` and `@vaadin/react-components-pro` workspaces.
The last of those matters most for the JavaScript audience. The components themselves are framework independent custom elements, and the React packages are wrappers, built as a separate step after the components, which is what allows a React application to use them with typing and without writing its own adapter. There is a matching clean script for the React build, so a developer working on the wrappers has an explicit way to reset that state.
The api-docs scripts sit alongside this and follow the same pattern, generating a `custom-elements.json` at the repository root before building the documentation workspace, so the published API documentation is derived from the same manifest analysis rather than written by hand. That is the right way to keep documentation honest, and the presence of the file in the repository root is a reminder that it is a build artifact.
Testing runs in several browsers, and the config files say which
The repository is not short on test configuration, and the file names in the top level listing are unusually descriptive. There is a base web-test-runner configuration, and then separate ones for Firefox, for WebKit, for integration tests, for snapshots, and one specifically for the Lumo theme. There are matching runner utility files and a web-dev-server configuration.
That set of files is the honest description of how a component library is tested in practice. The base configuration runs the unit tests, the browser specific configurations run them in more than one engine, the integration configuration runs the slower tests that mount components in a page, the snapshots configuration records and compares rendered output, and the Lumo configuration exists because a theme changes what a component renders, so the visual expectations cannot be shared with the default theme.
The snapshot configuration is worth singling out. For a design system, the rendered result is part of the contract, and a snapshot test that fails when a button's padding changes by a pixel is the mechanism that catches an accidental visual regression long before a user reports it.
Around the tests sit the other quality gates. There is an `eslint.config.js`, a `.stylelintrc` and a `.prettierrc` with a `.prettierignore`, and the lint script runs them in parallel across CSS, JavaScript and types.
"lint:css": "stylelint --ignore-path .gitignore \"packages/**/src/**/*.js\" \"packages/vaadin-lumo-styles/mixins/*.js\" \"packages/**/*.css\" \"dev/**/*.html\"",
"lint:js": "eslint",
"lint:types": "tsc",Note that the CSS lint command covers JavaScript files in package sources and Lumo style mixins as well as CSS and HTML, which tells you the theme layer is written in a mix of languages and the linting is configured accordingly. The `postinstall` script runs patch-package and `prepare` runs husky, so patched dependencies are applied automatically and the git hooks are installed on clone.
Conventions, accessibility and the limits of a component library
The repository carries the written rules that a mature project needs. There is a CONVENTIONS.md, an ACCESSIBILITY.md, a DEVELOPMENT.md, a CONTRIBUTING.md, a PULL_REQUEST_TEMPLATE.md, a CODE_OF_CONDUCT.md, a `.claude/` directory and a CLAUDE.md, plus a `guidelines/` directory, a `custom-rules/` directory and a `dev/` directory for the development harness. The API documentation workspace lives in `api-docs/`, and there is a `manifest/` directory for the custom elements manifest tooling, a `scripts/` directory, a `patches/` directory and a `test/` directory.
Two of those files deserve a mention because they change how you evaluate the library. ACCESSIBILITY.md means the project treats accessibility as a documented concern rather than an afterthought, which for a business component set is the difference between a library you can ship to a public sector client and one you cannot. CONVENTIONS.md is the equivalent for the code, which matters if you are contributing a component and want it to look like its neighbours.
The limits are clearer from the version policy. The repository covers Vaadin 20 and later, and for older versions the README directs you to separate repositories, so the library is tied to a platform generation rather than being a standalone set of web components you could adopt in a plain JavaScript application. The components are also part of the Vaadin product family, which means a decision to adopt them is a decision to be in that ecosystem rather than merely to use some good custom elements.
And there is the licence question. The README says the core components are under the Apache License 2.0, while the licence reported for the repository itself is unknown, which usually means the top level file does not carry a standard header that GitHub can detect. For a set of components you intend to ship inside a commercial product, the per package licence files are the ones to check, and this is not legal advice.
Finally, the release train. The recent tags show two patch lines released on the same day in October 2026 plus an alpha, and the `next` tags mean there is always a pre-release line in parallel. That is a well-run project with an active maintainer group, and it also means consumers have to make a deliberate choice about which line to track, and a team that wants a single frozen version of every component is not served well by this model.
Editorial conclusion
Vaadin web components is the right choice for a team already on Vaadin 20 or later that wants the platform's component set, with per component packages, theme packages and generated tooling, rather than assembling a component library by hand. It is the wrong choice for a plain JavaScript or React application that has no Vaadin dependency, and for a team that needs a component set with a single supported version rather than a latest and a next line. Verify first which component versions your Vaadin release expects, since the repository covers Vaadin 20 and later and older Vaadin versions live in separate repositories, and read ACCESSIBILITY.md and CONVENTIONS.md before contributing a component.
Frequently asked questions
What is the Vaadin web components repository?
It is a monorepo of standards based web components for business web applications, published as individual npm packages under the @vaadin scope, and it is part of Vaadin 20 and later. For older Vaadin versions the README points to separate repositories.
What is the difference between the latest and next npm tags for Vaadin components?
Each component is published twice, with a latest tag for the stable line and a next tag for the pre-release line, as the component table shows for @vaadin/button and every other entry. The release script builds themes, manifests, meta packages, web types and React wrappers in that order.
Can I use the Vaadin web components without Vaadin?
The components are framework independent custom elements, and the repository builds React wrapper packages on top of them, so they can be used from plain JavaScript or React. They are, however, the component set of the Vaadin platform, and the README scopes this repository to Vaadin 20 and later.
How are the Vaadin web components tested?
The repository ships several web-test-runner configurations, a base one plus Firefox, WebKit, integration, snapshot and Lumo theme specific ones, along with a web-dev-server configuration, so unit, integration and rendered output tests run in more than one engine and per theme.
What licence applies to the Vaadin web components?
The README states that the core components are licensed under the Apache License 2.0. The repository's own licence field is reported as unknown, so the per package licence files in the packages/ directories are the ones to check for a commercial product.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/vaadin-web-components)Was this useful?