{"id":50372409,"url":"https://github.com/giacomo/elements-template","last_synced_at":"2026-06-17T11:02:00.370Z","repository":{"id":361787351,"uuid":"1237401525","full_name":"giacomo/elements-template","owner":"giacomo","description":"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.","archived":false,"fork":false,"pushed_at":"2026-05-13T06:39:00.000Z","size":34017,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-01T10:04:04.540Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/giacomo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-13T06:37:52.000Z","updated_at":"2026-05-18T20:35:26.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/giacomo/elements-template","commit_stats":null,"previous_names":["giacomo/elements-template"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/giacomo/elements-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giacomo%2Felements-template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giacomo%2Felements-template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giacomo%2Felements-template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giacomo%2Felements-template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/giacomo","download_url":"https://codeload.github.com/giacomo/elements-template/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giacomo%2Felements-template/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34445186,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-17T02:00:05.408Z","response_time":127,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-30T08:00:26.067Z","updated_at":"2026-06-17T11:02:00.366Z","avatar_url":"https://github.com/giacomo.png","language":"TypeScript","funding_links":[],"categories":["Site Templates"],"sub_categories":["Free Templates"],"readme":"# 🧩 Angular Elements Starter Kit\n\n\u003e 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.\n\n![Angular](https://img.shields.io/badge/Angular-21-red?logo=angular)\n![Angular Elements](https://img.shields.io/badge/%40angular%2Felements-21-dd0031?logo=angular)\n![Tailwind CSS](https://img.shields.io/badge/TailwindCSS-v4-38bdf8?logo=tailwindcss)\n![Vitest](https://img.shields.io/badge/tested%20with-Vitest-6e9f18?logo=vitest)\n![Yarn](https://img.shields.io/badge/Yarn-4-2c8ebb?logo=yarn)\n\n---\n\n## ✨ Features\n\n- **Dual-mode bootstrap** — runs as a normal Angular app in development; compiles to a self-contained `widget.js` in production\n- **`@angular/elements`** — wraps Angular components as standard Custom Elements (`\u003cmy-custom-widget\u003e`)\n- **Shadow DOM encapsulation** — components are style-isolated by default via `ViewEncapsulation.ShadowDom`\n- **Zoneless** — uses `provideZonelessChangeDetection()` for maximum performance and smaller bundles\n- **Tailwind CSS v4** — utility-first styling included out of the box\n- **Vitest** — fast unit testing via the Angular CLI Vitest builder\n- **Single-file output** — `concat.js` post-build script produces one clean `dist/release/widget.js`\n\n---\n\n## 🔧 Prerequisites\n\n| Tool | Version |\n|------|---------|\n| Node.js | ≥ 20 |\n| Yarn | 4 (corepack) |\n| Angular CLI | 21 (`npm i -g @angular/cli`) |\n\nEnable Yarn 4 via Corepack (once):\n\n```bash\ncorepack enable\n```\n\n---\n\n## 🚀 Getting Started\n\n```bash\n# 1. Clone the repo\ngit clone https://github.com/your-org/elements-template.git\ncd elements-template\n\n# 2. Install dependencies\nyarn install\n\n# 3. Start the dev preview\nyarn start\n```\n\nOpen `http://localhost:4200` — you'll see the example chat widget rendered inside the Angular dev shell.\n\n---\n\n## 📜 Available Scripts\n\n| Script | Description |\n|--------|-------------|\n| `yarn start` | Start the dev server at `localhost:4200` |\n| `yarn build` | Standard Angular production build to `dist/` |\n| `yarn build:wc` | **Build the Web Component** → outputs `dist/release/widget.js` |\n| `yarn test` | Run unit tests with Vitest |\n| `yarn watch` | Incremental dev build in watch mode |\n\n---\n\n## 🏗️ How It Works\n\n### Dual-mode bootstrap (`src/main.ts`)\n\nThe entry point detects the environment flag and switches modes:\n\n```\ndevelopment  →  bootstrapApplication(App)      full Angular dev shell\nproduction   →  createApplication() +\n                createCustomElement(Example)   registers \u003cmy-custom-widget\u003e\n```\n\n- **Dev mode** boots the standard Angular app so you can iterate fast with HMR.\n- **Production mode** calls `createApplication()` (no root component) and registers each Angular component as a native Custom Element via `customElements.define()`.\n\n### Build pipeline (`yarn build:wc`)\n\n```\nng build --configuration production\n          └─ dist/elements-template/browser/main-\u003chash\u003e.js\n                    ↓  concat.js\n          dist/release/widget.js   ← single deployable file\n```\n\n`concat.js` locates the hashed main bundle and copies it to a stable, hash-free filename you can reference from any HTML page.\n\n---\n\n## 📦 Using the Widget\n\nAfter running `yarn build:wc`, include the single output file in any HTML page — no Angular, no build tools needed on the consumer side:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n\u003chead\u003e\n  \u003cmeta charset=\"UTF-8\" /\u003e\n  \u003ctitle\u003eMy Page\u003c/title\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n\n  \u003c!-- Drop the custom element anywhere on the page --\u003e\n  \u003cmy-custom-widget\u003e\u003c/my-custom-widget\u003e\n\n  \u003c!-- Load the self-contained bundle --\u003e\n  \u003cscript src=\"path/to/widget.js\"\u003e\u003c/script\u003e\n\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\nThe 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.\n\n---\n\n## 🛠️ Creating a New Web Component\n\n### 1. Generate the component\n\n```bash\nng generate component components/my-widget\n```\n\n### 2. Enable Shadow DOM encapsulation\n\n```typescript\n// src/app/components/my-widget/my-widget.ts\nimport { Component, ViewEncapsulation } from '@angular/core';\n\n@Component({\n  selector: 'app-my-widget',\n  templateUrl: './my-widget.html',\n  styleUrl: './my-widget.css',\n  encapsulation: ViewEncapsulation.ShadowDom,  // ← required\n})\nexport class MyWidget {}\n```\n\n### 3. Register it as a Custom Element (`src/main.ts`)\n\n```typescript\nimport { MyWidget } from './app/components/my-widget/my-widget';\n\ncreateApplication({ providers: [provideZonelessChangeDetection()] })\n  .then((appRef) =\u003e {\n    customElements.define(\n      'my-widget',\n      createCustomElement(MyWidget, { injector: appRef.injector })\n    );\n  });\n```\n\n### 4. Build \u0026 ship\n\n```bash\nyarn build:wc\n# → dist/release/widget.js\n```\n\n\u003e **Tip:** You can register multiple components from the same build by chaining additional `customElements.define()` calls inside the same `.then()` block.\n\n---\n\n## 🗂️ Project Structure\n\n```\nsrc/\n├── main.ts                          # Dual-mode bootstrap\n├── environments/\n│   ├── environment.ts               # production: true  → Web Component mode\n│   └── environment.development.ts  # production: false → Dev shell mode\n└── app/\n    ├── app.ts / app.html            # Dev-only shell (not part of the WC build)\n    └── components/\n        └── example/                 # Sample chat widget component\n            ├── example.ts           # ViewEncapsulation.ShadowDom\n            ├── example.html\n            └── example.css\nconcat.js                            # Post-build script → dist/release/widget.js\n```\n\n---\n\n## 🔑 Key Technologies\n\n| Technology | Role |\n|------------|------|\n| [Angular 21](https://angular.dev) | Component framework |\n| [@angular/elements](https://angular.dev/guide/elements) | Custom Elements bridge |\n| [Tailwind CSS v4](https://tailwindcss.com) | Utility-first styling |\n| [Vitest](https://vitest.dev) | Unit test runner |\n| [Yarn 4](https://yarnpkg.com) | Package manager |\n\n---\n\n## 📚 Resources\n\n- [Angular Elements Guide](https://angular.dev/guide/elements)\n- [Custom Elements (MDN)](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements)\n- [Shadow DOM (MDN)](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM)\n- [Angular CLI Reference](https://angular.dev/tools/cli)\n- [Tailwind CSS v4 Docs](https://tailwindcss.com/docs)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgiacomo%2Felements-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgiacomo%2Felements-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgiacomo%2Felements-template/lists"}