Library / SDK
material-components/material-web avatar
material-components/material-web

Material Web (@material/web): Google's Material 3 components as native web components

Material Design Web Components

11,289 stars1,144 forksSCSSApache-2.0

At a glance

What is it?
Material Web packages Material 3 as Lit-based custom elements, so any framework or none at all can use them. The README carries a maintenance warning, which matters more than the component list.
Who is it for?
Adopt Material Web when you want Material 3 markup that survives a framework change, when your app is plain HTML or Lit, or when you are prototyping against the CDN build. Do not adopt it if you need a component set with an active feature roadmap, and do not adopt it inside Angular without first checking whether Angular Material covers the same controls, because the README itself points Angular users there.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly SCSS, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Material Web solves, and who it is actually for

Most Material implementations are bound to a framework. If you write React, you get Material UI; if you write Angular, you get Angular Material. Material Web takes the opposite route: it publishes Material 3 as web components, which are a browser standard, so the same `<md-outlined-text-field>` element works in a plain HTML page, in Lit, in Vue, or inside a React component that simply renders the tag. The package is `@material/web`, licensed Apache-2.0, and the repository is dominated by per-component directories (button/, checkbox/, chips/, dialog/, menu/, select/, slider/, tabs/, textfield/ and others) plus a tokens/ directory for design tokens and a labs/ directory for components that have not graduated.

The intended reader is someone who wants Google's current design system, Material 3, without adopting a framework's component library. That includes teams with server-rendered pages, teams migrating between frameworks, and teams that already use Lit. It is a weaker fit for anyone who wants a single-vendor, fully supported component suite with a published roadmap of new features, and the README says so itself.

Maintenance mode is the first thing to read in the README

The README carries a note: "MWC is in maintenance mode pending new maintainers", linking to a GitHub discussion. That single sentence should shape the adoption decision more than any feature list. The repository is not archived, and the last push was on 2026-09-21, so code is still landing, but the project's own framing is that it is waiting for maintainers rather than pursuing a feature plan. The README also links a docs/roadmap.md, and a roadmap document in a maintenance-mode project is a statement of intent, not a schedule.

For an engineer, the practical consequence is this: treat Material Web as a component set that exists today, not as one that will grow to cover your next requirement. Check that every control you need is already in the repository's component directories before you build on it. If your product depends on a component that is not there, the maintenance note tells you not to expect it soon.

How it works: Lit elements, an import map, and shared stylesheets

The mechanism is standard custom elements. Each component directory holds a Lit-based element definition, and the package root exposes an `all.ts` entry point that pulls them together. The package declares `"type": "module"` and depends on `lit` (^2.8.0 || ^3.0.0), `@lit/context`, `safevalues` and `tslib`. Styling is authored in SCSS, which is why the repository's primary language is listed as SCSS; the build scripts (`build:sass`, `build:css-to-ts`, `build:ts`, `build:manifest`) compile those styles into TypeScript modules that the elements adopt.

That last point is the part people miss. Typography is not applied automatically to your page. The README's example imports `styles as typescaleStyles` from `@material/web/typography/md-typescale-styles.js` and pushes `typescaleStyles.styleSheet` onto `document.adoptedStyleSheets`. Without that step, the `md-typescale-*` classes on your headings and paragraphs do nothing. The elements themselves are registered by importing them, so tree-shaking depends on whether you import `all.js` or individual component modules.

Installing Material Web and getting a first form on the page

The README shows a buildless path first: an import map points the `@material/web/` prefix at a CDN, then a module script imports `all.js`. The same block also loads Roboto from Google Fonts and adopts the typescale stylesheet, which is what makes the `md-typescale-display-medium` and `md-typescale-body-medium` classes take effect.

html
<head>
  <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet">
  <script type="importmap">
    {
      "imports": {
        "@material/web/": "https://esm.run/@material/web/"
      }
    }
  </script>
  <script type="module">
    import '@material/web/all.js';
    import {styles as typescaleStyles} from '@material/web/typography/md-typescale-styles.js';

    document.adoptedStyleSheets.push(typescaleStyles.styleSheet);
  </script>
</head>

With the elements registered, the README's form uses plain tags. Note that the radio buttons share a `name`, which is what groups them, and that the reset button is an `md-outlined-button` with `type="reset"`, so it clears the fields through normal form semantics rather than a custom handler.

html
<form>
  <md-checkbox></md-checkbox>
  <div>
    <md-radio name="group"></md-radio>
    <md-radio name="group"></md-radio>
    <md-radio name="group"></md-radio>
  </div>
  <md-outlined-text-field label="Favorite color" value="Purple"></md-outlined-text-field>
  <md-outlined-button type="reset">Reset</md-outlined-button>
</form>

For a production build the README points to docs/quick-start.md rather than the CDN snippet, and the package is published on npm as `@material/web`, so the install is the usual `npm install @material/web`. The README does not spell out a bundler configuration in the section shown here; the quick-start document is where that lives.

Where Material Web is the wrong tool

The README's own tip is the clearest limitation: "Using Angular? We recommend using Angular Material components instead." That is not a throwaway line. Angular's forms, change detection and template syntax assume Angular components, and wiring a custom element into them adds a layer the framework's own library does not need. If you are on Angular, the project is telling you to look elsewhere.

The second limitation is the maintenance note. A component library in maintenance mode still works, but bug reports and new component requests go into a queue whose drain rate depends on volunteers. Third, importing `all.js` pulls in every component; the README links docs/size.md precisely because bundle size is a real concern, and the package's `files` field ships compiled JavaScript, type declarations, SCSS and CSS, so consumers who want only two components should import those two modules rather than the aggregate entry point. Finally, the docs directory is the source of truth for component behaviour, and the README does not document a rollback or downgrade path between major versions; the changelog is where that history sits.

How it differs from Material UI and Angular Material

Material UI is a React component library. Its components are React components, its theming runs through a React context and a styling engine, and its release cadence is tied to the React ecosystem. Material Web's components are custom elements with no framework runtime in the component itself; the only shared dependency is Lit, and Lit is small. The difference shows up when you change frameworks: Material UI code has to be rewritten, while `<md-checkbox>` in a template keeps working.

Angular Material is the opposite trade. It is deeply integrated with Angular's DI, theming and accessibility utilities, so it feels native inside an Angular app and is a poor fit outside one. Material Web sits between the two: less integrated with any framework, more portable across all of them. If your application is a single-page React app that will stay React, Material UI gives you more for less friction. If your markup is server-rendered or your stack is unsettled, the web component approach is the one that does not have to be redone.

Licence, upgrade cost and what the release history shows

The licence is Apache-2.0, which permits commercial use and modification and requires you to preserve the licence and notices; it also includes a patent grant. That is a permissive licence with no copyleft obligation on your application code, but the usual caveat applies: this is a description of the file, not legal advice, and your counsel should review anything you redistribute.

On upgrades, the release history shows v2.4.0 in August 2025, v2.4.1 in October 2025 and v2.5.0 in July 2026. That is roughly three releases across a year, which is consistent with the maintenance-mode note rather than with a fast-moving library. The repository uses release-please (release-please-config.json and .release-please-manifest.json at the root) to generate releases and the CHANGELOG, so version bumps and changelog entries are automated from commit messages, and commitlint.config.js enforces the commit format that makes that work. For a consumer, the practical upgrade cost is low while you stay within a major version, but you should read the changelog before each bump because the project does not publish a migration guide in the README; there is a migrations/ directory in the repository, which is where version-to-version changes are recorded.

Editorial conclusion

Adopt Material Web when you want Material 3 markup that survives a framework change, when your app is plain HTML or Lit, or when you are prototyping against the CDN build. Do not adopt it if you need a component set with an active feature roadmap, and do not adopt it inside Angular without first checking whether Angular Material covers the same controls, because the README itself points Angular users there. Before committing, open the maintenance discussion linked from the README, confirm the components you need exist under the repository's per-component directories, and read docs/size.md to see what the bundle costs when you import all.js. The one thing to verify that no badge can tell you is whether the specific control you need is already shipped or still pending a maintainer.

Frequently asked questions

What is Material Web?

It is `@material/web`, a library of web components built on Material 3, Google's current design system. The components are custom elements, so they work in plain HTML or in any framework that can render a tag.

Can I use Material 3 with Angular via Material Web?

Technically the components are framework-agnostic custom elements, but the README explicitly recommends Angular Material instead for Angular projects. Treat that tip as the project's own guidance.

How is Material Web different from Material UI?

Material UI is a React component library whose components only exist inside React. Material Web ships custom elements, so the same `<md-checkbox>` or `<md-outlined-text-field>` works in HTML, Lit, Vue or React, at the cost of tighter framework integration.

How is Material Web different from Angular Material?

Angular Material is built for Angular's dependency injection, theming and forms, so it fits an Angular app closely and fits nothing else. Material Web trades that integration for portability across frameworks.

Official sources

  1. License: Apache-2.0
  2. material-components/material-web on GitHub
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/material-components-material-web.svg)](https://hysenlabs.com/projects/material-components-material-web)