A comprehensive, production-ready starter template for creating Web Components. This template is based on the architecture and best practices from my web components work, incorporating Google's Custom Element Best Practices.
- Modern Tooling: Vitest, ESLint, Prettier, Happy DOM
- Best Practices: Shadow DOM, Custom Elements v1, proper encapsulation, following Google's recommendations
- Multiple Import Options: Auto-define, manual definition, or both
- Testing: Comprehensive test setup with coverage reporting
- CI/CD: GitHub Actions workflows included
- Developer Experience: Demo page, interactive setup, extensive documentation
- Publishing Ready: npm package configuration and automated publishing workflow
- Click "Use this template" on GitHub, or:
git clone https://github.com/aarongustafson/web-component-starter.git my-component
cd my-component- Run the interactive setup:
npm install
npm run setupThe setup wizard will:
- Ask for your component name (e.g.,
my-awesome-component) - Ask for a description
- Rename all files automatically
- Replace all placeholders in code and configuration
- Generate your component's README from template
- Clean up template setup files (SETUP.md, README.tpl, scripts/)
- Install dependencies
- Initialize git repository
If you prefer manual setup, see SETUP.md for detailed instructions.
web-component-starter/
├── COMPONENT-NAME.js # Component implementation
├── index.js # Main entry (class + auto-define)
├── define.js # Auto-define only
├── custom-elements.json # Custom Elements Manifest
├── package.json # Package config with scripts
├── LICENSE # MIT License
├── README.md # This file (replaced after setup)
├── README.tpl # Template for your component's README
├── WEB-COMPONENTS-BEST-PRACTICES.md # Best practices documentation
├── .gitignore # Git ignore
├── .npmignore # npm ignore
├── .prettierrc # Prettier config
├── .editorconfig # Editor config
├── eslint.config.js # ESLint config
├── vitest.config.js # Vitest config
├── .github/
│ ├── workflows/
│ │ ├── ci.yml # Continuous integration
│ │ └── publish.yml # Auto-publish to npm
│ └── ISSUE_TEMPLATE/ # Bug & feature templates
├── scripts/
│ └── setup.js # Interactive setup wizard (removed after setup)
├── test/
│ ├── setup.js # Test configuration
│ └── COMPONENT-NAME.test.js # Test suite
├── demo/
│ └── index.html # Live demo page
├── SETUP.md # Manual setup guide (removed after setup)
└── CONTRIBUTING.md # Contribution guidelines
npm run setup # Interactive setup wizard
npm test # Run tests in watch mode
npm run test:run # Run tests once
npm run test:ui # Open Vitest UI
npm run test:coverage # Generate coverage report
npm run lint # Lint with ESLint + Prettier
npm run format # Auto-fix linting issuesThis template provides flexible import options:
Option 1: Manual registration
import { ComponentNameElement } from '@yourscope/component-name';
customElements.define('my-custom-name', ComponentNameElement);Option 2: Guarded auto-define (browser environments only)
import '@yourscope/component-name/define.js';
// Registers the element when customElements is availablePrefer to control when registration happens? Call the helper directly:
import { defineComponentName } from '@yourscope/component-name/define.js';
defineComponentName();Includes:
- Vitest: Fast, modern test runner
- Happy DOM: Lightweight browser environment
- Testing Library: DOM testing utilities
- Coverage: V8 coverage reporting
- UI: Interactive test debugging
Example:
import { describe, it, expect } from 'vitest';
describe('MyComponent', () => {
it('should render', () => {
const el = document.createElement('my-component');
expect(el).toBeInstanceOf(HTMLElement);
});
});This template is configured to publish to npm using OpenID Connect (OIDC), which is more secure than using long-lived NPM tokens.
Initial Setup:
-
Publish your package to npm manually the first time:
npm run test:run # Ensure tests pass npm run lint # Ensure code is clean npm publish # First publish must be manual
-
Configure OIDC on npm:
- Visit your package's access page:
https://www.npmjs.com/package/@yourscope/your-component-name/access - Under "Publishing Access", click "Configure OIDC"
- Add GitHub Actions as a trusted publisher with these settings:
- Provider: GitHub
- Organization/Username: Your GitHub username or organization
- Repository: Your repository name
- Workflow:
.github/workflows/publish.yml - Environment: Leave blank (unless you use GitHub environments)
- Visit your package's access page:
-
Create a GitHub release to trigger automated publishing:
- Use
npm versionto update version and create a tag:npm version patch(orminor/major) - Push with tags:
git push --follow-tags - Or create a release through GitHub's UI
- Use
The GitHub Actions workflow (.github/workflows/publish.yml) will automatically publish to npm when you create a new version tag.
If you prefer to publish manually without automation:
npm run test:run # Ensure tests pass
npm run lint # Ensure code is clean
npm publish # Publish to npmWorks in all modern browsers supporting:
- Custom Elements v1
- Shadow DOM v1
- ES Modules
For legacy browsers, use polyfills.
- WEB-COMPONENTS-BEST-PRACTICES.md - Explanation of best practices used in this template
- SETUP.md - Detailed setup instructions (removed after setup)
- CONTRIBUTING.md - Contribution guidelines
- LICENSE - MIT License
Perfect for:
- Reusable UI components
- Design system elements
- Form controls and widgets
- Interactive content blocks
- Accessibility-enhanced components
Based on best practices from:
- Google's Custom Element Best Practices
- form-obfuscator by Aaron Gustafson
- Open Web Components
MIT - See LICENSE
Contributions welcome! See CONTRIBUTING.md
Ready to build your web component? Run npm run setup to get started! 🚀