An open API service indexing awesome lists of open source software.

https://github.com/giacomo/elements-template

A modern, opinionated starter kit for building **Custom Web Components** (Web Components / Custom Elements) powered by **Angular 21**, **Tailwind CSS v4**, and **Vitest** — ready to drop into any web page or framework.
https://github.com/giacomo/elements-template

Last synced: about 17 hours ago
JSON representation

A modern, opinionated starter kit for building **Custom Web Components** (Web Components / Custom Elements) powered by **Angular 21**, **Tailwind CSS v4**, and **Vitest** — ready to drop into any web page or framework.

Awesome Lists containing this project

README

          

# 🧩 Angular Elements Starter Kit

> A modern, opinionated starter kit for building **Custom Web Components** (Web Components / Custom Elements) powered by **Angular 21**, **Tailwind CSS v4**, and **Vitest** — ready to drop into any web page or framework.

![Angular](https://img.shields.io/badge/Angular-21-red?logo=angular)
![Angular Elements](https://img.shields.io/badge/%40angular%2Felements-21-dd0031?logo=angular)
![Tailwind CSS](https://img.shields.io/badge/TailwindCSS-v4-38bdf8?logo=tailwindcss)
![Vitest](https://img.shields.io/badge/tested%20with-Vitest-6e9f18?logo=vitest)
![Yarn](https://img.shields.io/badge/Yarn-4-2c8ebb?logo=yarn)

---

## ✨ Features

- **Dual-mode bootstrap** — runs as a normal Angular app in development; compiles to a self-contained `widget.js` in production
- **`@angular/elements`** — wraps Angular components as standard Custom Elements (``)
- **Shadow DOM encapsulation** — components are style-isolated by default via `ViewEncapsulation.ShadowDom`
- **Zoneless** — uses `provideZonelessChangeDetection()` for maximum performance and smaller bundles
- **Tailwind CSS v4** — utility-first styling included out of the box
- **Vitest** — fast unit testing via the Angular CLI Vitest builder
- **Single-file output** — `concat.js` post-build script produces one clean `dist/release/widget.js`

---

## 🔧 Prerequisites

| Tool | Version |
|------|---------|
| Node.js | ≥ 20 |
| Yarn | 4 (corepack) |
| Angular CLI | 21 (`npm i -g @angular/cli`) |

Enable Yarn 4 via Corepack (once):

```bash
corepack enable
```

---

## 🚀 Getting Started

```bash
# 1. Clone the repo
git clone https://github.com/your-org/elements-template.git
cd elements-template

# 2. Install dependencies
yarn install

# 3. Start the dev preview
yarn start
```

Open `http://localhost:4200` — you'll see the example chat widget rendered inside the Angular dev shell.

---

## 📜 Available Scripts

| Script | Description |
|--------|-------------|
| `yarn start` | Start the dev server at `localhost:4200` |
| `yarn build` | Standard Angular production build to `dist/` |
| `yarn build:wc` | **Build the Web Component** → outputs `dist/release/widget.js` |
| `yarn test` | Run unit tests with Vitest |
| `yarn watch` | Incremental dev build in watch mode |

---

## 🏗️ How It Works

### Dual-mode bootstrap (`src/main.ts`)

The entry point detects the environment flag and switches modes:

```
development → bootstrapApplication(App) full Angular dev shell
production → createApplication() +
createCustomElement(Example) registers
```

- **Dev mode** boots the standard Angular app so you can iterate fast with HMR.
- **Production mode** calls `createApplication()` (no root component) and registers each Angular component as a native Custom Element via `customElements.define()`.

### Build pipeline (`yarn build:wc`)

```
ng build --configuration production
└─ dist/elements-template/browser/main-.js
↓ concat.js
dist/release/widget.js ← single deployable file
```

`concat.js` locates the hashed main bundle and copies it to a stable, hash-free filename you can reference from any HTML page.

---

## 📦 Using the Widget

After running `yarn build:wc`, include the single output file in any HTML page — no Angular, no build tools needed on the consumer side:

```html


My Page



```

The widget is fully encapsulated — its styles live inside the Shadow DOM and will not bleed into or be affected by the host page's CSS.

---

## 🛠️ Creating a New Web Component

### 1. Generate the component

```bash
ng generate component components/my-widget
```

### 2. Enable Shadow DOM encapsulation

```typescript
// src/app/components/my-widget/my-widget.ts
import { Component, ViewEncapsulation } from '@angular/core';

@Component({
selector: 'app-my-widget',
templateUrl: './my-widget.html',
styleUrl: './my-widget.css',
encapsulation: ViewEncapsulation.ShadowDom, // ← required
})
export class MyWidget {}
```

### 3. Register it as a Custom Element (`src/main.ts`)

```typescript
import { MyWidget } from './app/components/my-widget/my-widget';

createApplication({ providers: [provideZonelessChangeDetection()] })
.then((appRef) => {
customElements.define(
'my-widget',
createCustomElement(MyWidget, { injector: appRef.injector })
);
});
```

### 4. Build & ship

```bash
yarn build:wc
# → dist/release/widget.js
```

> **Tip:** You can register multiple components from the same build by chaining additional `customElements.define()` calls inside the same `.then()` block.

---

## 🗂️ Project Structure

```
src/
├── main.ts # Dual-mode bootstrap
├── environments/
│ ├── environment.ts # production: true → Web Component mode
│ └── environment.development.ts # production: false → Dev shell mode
└── app/
├── app.ts / app.html # Dev-only shell (not part of the WC build)
└── components/
└── example/ # Sample chat widget component
├── example.ts # ViewEncapsulation.ShadowDom
├── example.html
└── example.css
concat.js # Post-build script → dist/release/widget.js
```

---

## 🔑 Key Technologies

| Technology | Role |
|------------|------|
| [Angular 21](https://angular.dev) | Component framework |
| [@angular/elements](https://angular.dev/guide/elements) | Custom Elements bridge |
| [Tailwind CSS v4](https://tailwindcss.com) | Utility-first styling |
| [Vitest](https://vitest.dev) | Unit test runner |
| [Yarn 4](https://yarnpkg.com) | Package manager |

---

## 📚 Resources

- [Angular Elements Guide](https://angular.dev/guide/elements)
- [Custom Elements (MDN)](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements)
- [Shadow DOM (MDN)](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM)
- [Angular CLI Reference](https://angular.dev/tools/cli)
- [Tailwind CSS v4 Docs](https://tailwindcss.com/docs)