Appearance
Publishing Web Components
Web components published incorrectly cause bundling issues, break tree-shaking, require polyfills consumers don't need, or fail in different build systems. Publish ES modules directly — let consumers handle the rest.
Module format
Publish ES2017 JavaScript as standard modules. Do not bundle, minify, or transpile to CommonJS.
json
{
"name": "my-component",
"type": "module",
"main": "./src/index.js",
"module": "./src/index.js",
"exports": {
".": "./src/index.js"
}
}Set both "main" and "module" to the same entry point. Use .js extensions (not .mjs). The "type": "module" field tells Node.js and bundlers that all .js files in the package are ES modules.
Code practices
Do:
- Use bare import specifiers for dependencies:
import { LitElement } from "lit" - Include file extensions on local imports:
import "./utils.js" - Self-register custom elements:
customElements.define("my-element", MyElement) - Export element classes for subclassing
- Publish a
custom-elements.jsonmanifest - Include TypeScript declarations (
.d.tsfiles)
Don't:
- Import polyfills into your modules — polyfills are the consumer's responsibility
- Include bundler-specific transforms or config in your source
- Depend on a specific build tool being present
What consumers handle
The consumer — not the package — decides:
- Which browsers to support
- Whether to polyfill
- How to bundle and minify
- Whether to transpile to older JS versions
If you bundle, you've made those decisions for them and broken the flexibility that makes web components composable.
Checklist
- [ ]
"type": "module"in package.json - [ ]
"main"and"module"point to the same ES2017 entry point - [ ]
.jsextensions on all source files - [ ] File extensions included in all local import statements
- [ ] Element classes exported for subclassing
- [ ] Elements self-registered with
customElements.define() - [ ]
custom-elements.jsonmanifest included - [ ] TypeScript declarations included
- [ ] No polyfill imports in source files
- [ ] Source not bundled or minified
See also
- How to Publish Web Components to npm: The original source for these guidelines, by Justin Fagnani.
- Encapsulation: Shadow DOM vs. light DOM — affects how consumers can style your component.