They are actually called “CSS Module Scripts” and are a native browser feature, as opposed to the popular open-source project that essentially does scoped styles by creating unique class name identifiers in both HTML and CSS.
Native CSS Modules are a part of ES Modules (a lot like JSON modules we recently covered):
// Regular ES Modules
import React from "https://cdn.skypack.dev/[email protected]";
// Newfangled JSON Modules
import configData from './config-data.json' assert { type: 'json' };
// Newfangled CSS Modules
import styleSheet from "./styles.css" assert { type: "css" };
I first saw this from Justin’s tweet:
This is a Chrome-thing for now. Relevant links:
- Intent to Implement: CSS Modules V1
- Chrome Platform Status: CSS Module Scripts
- GitHub/WhatWG: Introduce CSS Module Script
As I write, it only works in Chrome Canary with the Experimental Web Platform Features on. If your question is, When can I use this on production projects with a wide variety of users using whatever browser they want?
I’d say: I have no idea. Probably years away. Maybe never. But it’s still interesting to check out. Maybe support will move fast. Maybe you’ll work on an Electron project or something where you can count on specific browser features.
This looks like an extension of Constructable Stylesheets, which are also Chrome-only, so browsers that are “behind” on this would have to start there.
I gave Justin’s idea a spin here:
If I log what I get back from the CSS Modules import, it’s a CSSStyleSheet
:

If you’re going to actually use the styles… that’s on you. Justin’s idea basically applies the style as a one-liner because it just so happens that lit-html supports CSSStyleSheet
(those docs don’t make that clear, but I imagine they will at some point). For native web components, it’s not much different: you import it, get the CSSStyleSheet
, then apply it to the web component like:
this.shadowRoot.adoptedStyleSheets = [myCSSStyleSheet];
I would think the point of all this is:
- we needed a way to import a stylesheet in JavaScript and this is basically the first really clear crack at it that I’m aware of,
- now we have programatic access to manipulate the CSS before using it, if we wanted, and
- it looks particularly nice for Web Components usage, but it’s generic. Do whatever you want with the stylesheet once you have it.
Makes me wish we had native support for loaders.
Being unable to prototype something like this in userland is bad enough, but being unable to polyfill the browser is kind of crippling – it drives us back towards bundlers, when HTTP/2 and native modules were starting to promise a simpler future. That, or waiting (potentially years) for browser vendors to implement and users to upgrade.
In really wish they would try to solve the loader problem before introducing anymore module types.
Css modules is enable soon in chrome stable and the proposal is in stage 3 of the tc39