|
| 1 | +--- |
| 2 | +title: "A Production-Ready Web Component Starter Template" |
| 3 | +date: 2026-01-02 00:06:37 +00:00 |
| 4 | +comments: true |
| 5 | +tags: |
| 6 | + [ |
| 7 | + "web components", |
| 8 | + "JavaScript", |
| 9 | + "open source", |
| 10 | + "developer tools", |
| 11 | + "best practices", |
| 12 | + ] |
| 13 | +description: "I created a comprehensive starter template for creating production-ready web components with modern tooling, testing, and CI/CD—following Google's Custom Element Best Practices." |
| 14 | +twitter_text: "Start building web components the right way with this production-ready template." |
| 15 | +--- |
| 16 | + |
| 17 | +Creating a new web component from scratch involves a lot of boilerplate—testing setup, build configuration, linting, CI/CD, documentation structure, and more. After building — and refining/rebuilding — numerous web components, I’ve distilled all that work into a starter template that lets you focus on your component’s functionality rather than project setup. |
| 18 | + |
| 19 | +<!-- more --> |
| 20 | + |
| 21 | +The [Web Component Starter Template](https://github.com/aarongustafson/web-component-starter) is based on the architecture and patterns I’ve refined across my web component work, incorporating [Google's Custom Element Best Practices](https://web.dev/articles/custom-elements-best-practices) and advice from other web components practitioners including the always-brilliant <a href="https://daverupert.com/">Dave Rupert</a>. |
| 22 | + |
| 23 | +## What's included |
| 24 | + |
| 25 | +The template provides everything you need to create a production-ready web component: |
| 26 | + |
| 27 | +- **Interactive setup wizard** that scaffolds everything for your component. |
| 28 | +- **Multiple import patterns** supporting both auto-define and manual registration. |
| 29 | +- **Demo pages** for development, documentation, and CDN examples. |
| 30 | +- **Code quality tools** including ESLint and Prettier with sensible defaults. |
| 31 | +- **Modern testing setup** with Vitest, Happy DOM, and coverage reporting. |
| 32 | +- **CI/CD workflows** for GitHub Actions with automated testing and npm publishing. |
| 33 | +- **Publishing ready** with proper npm package configuration and OIDC support. |
| 34 | + |
| 35 | +## Quick start with interactive setup |
| 36 | + |
| 37 | +Getting started is straightforward. If you’re a GitHub user, you can create a new repository directly from the template. Alternatively, clone it locally: |
| 38 | + |
| 39 | +```bash |
| 40 | +git clone https://github.com/aarongustafson/web-component-starter.git my-component |
| 41 | +cd my-component |
| 42 | +npm install |
| 43 | +npm run setup |
| 44 | +``` |
| 45 | + |
| 46 | +The setup wizard asks for your component name and description, then automatically: |
| 47 | + |
| 48 | +- Renames all files based on your component name, |
| 49 | +- Updates all code and configuration templates with your details, |
| 50 | +- Generates a proper README from the included template, |
| 51 | +- Cleans up all template-specific files, and |
| 52 | +- Initializes the git repository. |
| 53 | + |
| 54 | +You’re left with a fully scaffolded repository, ready for you to develop your component. |
| 55 | + |
| 56 | +## Flexible import patterns |
| 57 | + |
| 58 | +One of the key features is support for multiple registration patterns. Users of your component can choose what works best: |
| 59 | + |
| 60 | +**Manual registration for full control:** |
| 61 | + |
| 62 | +```javascript |
| 63 | +import { ComponentNameElement } from '@yourscope/component-name'; |
| 64 | + |
| 65 | +customElements.define('my-custom-name', ComponentNameElement); |
| 66 | +``` |
| 67 | + |
| 68 | +**Auto-define for convenience:** |
| 69 | + |
| 70 | +```javascript |
| 71 | +import '@yourscope/component-name/define.js'; |
| 72 | +``` |
| 73 | + |
| 74 | +**Or call the helper directly:** |
| 75 | + |
| 76 | +```javascript |
| 77 | +import { defineComponentName } from '@yourscope/component-name/define.js'; |
| 78 | + |
| 79 | +defineComponentName(); |
| 80 | +``` |
| 81 | + |
| 82 | +The auto-define approach includes guards to ensure it only runs in browser environments and checks if `customElements` is available, making it safe for server-side rendered (SSR) scenarios. |
| 83 | + |
| 84 | +## Testing made easy |
| 85 | + |
| 86 | +The template includes a comprehensive testing setup using Vitest: |
| 87 | + |
| 88 | +```javascript |
| 89 | +import { describe, it, expect } from 'vitest'; |
| 90 | + |
| 91 | +describe('MyComponent', () => { |
| 92 | + it('should render', () => { |
| 93 | + const el = document.createElement('my-component'); |
| 94 | + expect(el).toBeInstanceOf(HTMLElement); |
| 95 | + }); |
| 96 | +}); |
| 97 | +``` |
| 98 | + |
| 99 | +Happy DOM provides a lightweight browser environment, and the included scripts support: |
| 100 | + |
| 101 | +- Watch mode for development: `npm test` |
| 102 | +- Single run for CI: `npm run test:run` |
| 103 | +- Interactive UI: `npm run test:ui` |
| 104 | +- Coverage reports: `npm run test:coverage` |
| 105 | + |
| 106 | +## Automated publishing with OIDC |
| 107 | + |
| 108 | +The template is configured for secure automated publishing to npm using OpenID Connect (OIDC), which is more secure than long-lived tokens. After you manually publish the first version and configure OIDC on npm, create a GitHub release and the workflow handles publishing automatically. |
| 109 | + |
| 110 | +Manual publishing is still supported if you prefer that approach. |
| 111 | + |
| 112 | +## Following best practices |
| 113 | + |
| 114 | +The template bakes in best practices from the start: |
| 115 | + |
| 116 | +- Shadow DOM with proper encapsulation |
| 117 | +- Custom Elements v1 API |
| 118 | +- Reflection of properties to attributes |
| 119 | +- Lifecycle callbacks used appropriately |
| 120 | +- Accessible patterns and ARIA support |
| 121 | +- Progressive enhancement approach |
| 122 | + |
| 123 | +The included [`WEB-COMPONENTS-BEST-PRACTICES.md` document](https://github.com/aarongustafson/web-component-starter/blob/main/WEB-COMPONENTS-BEST-PRACTICES.md) explains the reasoning behind each pattern, making it a learning resource as well as a starter template. |
| 124 | + |
| 125 | +## Why I built this |
| 126 | + |
| 127 | +After creating components like [form-obfuscator](https://github.com/aarongustafson/form-obfuscator), [tabbed-interface](https://github.com/aarongustafson/tabbed-interface), and several others, I found myself copying and adapting the same project structure each time. This template captures those patterns so I — and now you — can start building components faster. |
| 128 | + |
| 129 | +If you build something with it, I’d love to hear about it! |
0 commit comments