{"id":16773648,"url":"https://github.com/borjapazr/angular-skeleton","last_synced_at":"2025-03-21T23:34:29.364Z","repository":{"id":37448701,"uuid":"488376671","full_name":"borjapazr/angular-skeleton","owner":"borjapazr","description":"🅰️🦸 Template to start developing a Progressive Web Application with Angular, Transloco, Angular Universal, SSR/ISR, TailwindCSS, Jest, Cypress, ESLint, Prettier, Husky, etc.","archived":false,"fork":false,"pushed_at":"2023-07-21T06:47:09.000Z","size":2656,"stargazers_count":38,"open_issues_count":1,"forks_count":7,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-10-14T06:46:37.417Z","etag":null,"topics":["angular","angular-universal","angular14","cypress","eslint","hacktoberfest","husky","isr","jest","prerender","prettier","pwa","seo","ssr","tailwindcss","transloco"],"latest_commit_sha":null,"homepage":"https://angular-skeleton.bpaz.dev","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/borjapazr.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null}},"created_at":"2022-05-03T22:08:10.000Z","updated_at":"2024-08-12T15:35:55.000Z","dependencies_parsed_at":"2022-07-13T19:30:33.946Z","dependency_job_id":null,"html_url":"https://github.com/borjapazr/angular-skeleton","commit_stats":null,"previous_names":[],"tags_count":21,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/borjapazr%2Fangular-skeleton","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/borjapazr%2Fangular-skeleton/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/borjapazr%2Fangular-skeleton/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/borjapazr%2Fangular-skeleton/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/borjapazr","download_url":"https://codeload.github.com/borjapazr/angular-skeleton/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221820632,"owners_count":16886222,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["angular","angular-universal","angular14","cypress","eslint","hacktoberfest","husky","isr","jest","prerender","prettier","pwa","seo","ssr","tailwindcss","transloco"],"created_at":"2024-10-13T06:46:34.043Z","updated_at":"2024-10-28T11:16:55.783Z","avatar_url":"https://github.com/borjapazr.png","language":"TypeScript","readme":"\u003cdiv align=\"center\"\u003e\n \u003cimg\n  width=\"500\"\n alt=\"Node.js, Typescript and Express template\"\n src=\"https://i.imgur.com/ysaMVxF.png\"\u003e\n\u003cbr\u003e\n\u003cimg\n  width=\"500\"\n alt=\"Node.js, Typescript and Express template\"\n src=\"https://i.imgur.com/LydboRD.png\"\u003e\n \n\u003cbr\u003e\n\n![GitHub package.json version](https://img.shields.io/github/package-json/v/borjapazr/angular-skeleton?style=flat-square)\n![GitHub CI Workflow Status](https://img.shields.io/github/actions/workflow/status/borjapazr/angular-skeleton/ci.yml?branch=main\u0026style=flat-square\u0026logo=github\u0026label=CI)\n![GitHub CD Workflow Status](https://img.shields.io/github/actions/workflow/status/borjapazr/angular-skeleton/cd.yml?branch=main\u0026style=flat-square\u0026logo=github\u0026label=CD)\n![GitHub LICENSE](https://img.shields.io/github/license/borjapazr/angular-skeleton?style=flat-square)\n[![Demo](https://img.shields.io/badge/demo-🎮-yellow.svg?style=flat-square)](https://angular-skeleton.marsmachine.space/)\n[![Documentation](https://img.shields.io/badge/documentation-80%25-orange?style=flat-square)](https://img.shields.io/badge/documentation-80%25-orange?style=flat-square)\n\n\u003ch4\u003e\n  🅰️🦸 Production-ready template for Progressive Web Applications implemented with Angular, TailwindCSS, Transloco, ngx-isr, etc.\n\u003c/h4\u003e\n\n\u003ca href=\"#ℹ️-about\"\u003eℹ️ About\u003c/a\u003e •\n\u003ca href=\"#-features\"\u003e📋 Features\u003c/a\u003e •\n\u003ca href=\"#-contributing\"\u003e 🤝 Contributing\u003c/a\u003e •\n\u003ca href=\"#️-roadmap\"\u003e 🛣️ Roadmap\u003c/a\u003e •\n\u003ca href=\"#-credits\"\u003e🎯 Credits\u003c/a\u003e •\n\u003ca href=\"#-license\"\u003e🚩 License\u003c/a\u003e\n\n\u003c/div\u003e\n\n---\n\n## ℹ️ About\n\nThe main goal of this project is to provide a base template for the generation of a production-ready web application made with `Angular`. The idea is to avoid having to configure all the tools involved in a project every time it is started and thus be able to focus on the definition and implementation of the business logic.\n\n\u003e 📣 This is an opinionated template. The architecture of the code base and the configuration of the different tools used has been based on best practices and personal preferences.\n\n### 🚀 Quick start\n\n- Start project in development mode:\n\n  ```bash\n  npm run start:dev\n  ```\n\n- Start project in production mode:\n\n  ```bash\n  npm run start:prod\n  ```\n\n## 📋 Features\n\n- [Angular](https://angular.io/): Angular is a platform for building mobile and desktop web applications.\n- [Angular Universal](https://angular.io/guide/universal): Server-side rendering (SSR) with Angular Universal.\n- [TailwindCSS](https://tailwindcss.com/): A utility-first CSS framework packed with classes like flex, pt-4, text-center and rotate-90 that can be composed to build any design, directly in your markup.\n- [ng-lazyload-image](https://www.npmjs.com/package/ng-lazyload-image): A super small libary for lazy loading images for Angular apps with zero dependencies\n- [ngx-isr](https://www.npmjs.com/package/ngx-isr): Incremental Static Regeneration (ISR) enables developers and content editors to use static-generation on a per-page basis, without needing to rebuild the entire site. With ISR, you can retain the benefits of static while scaling to millions of pages.\n- i18n using [Transloco](https://ngneat.github.io/transloco/)\n- Unit tests using [Jest](https://github.com/facebook/jest)\n- e2e tests using [Cypress](https://www.cypress.io/)\n- [Spell check](https://github.com/streetsidesoftware/cspell)\n- Linting with [ESLint](https://github.com/eslint/eslint)\n- Formatting with [Prettier](https://github.com/prettier/prettier)\n- [Stylelint](https://stylelint.io/): A mighty, modern linter that helps you avoid errors and enforce conventions in your styles.\n- [HTMLHint](https://htmlhint.com/): A linter for HTML that helps you avoid errors and enforce conventions in your HTML.\n- Commit messages must meet conventional commits format\n- Git hooks with [Husky](https://github.com/typicode/husky) and [lint-staged](https://github.com/okonet/lint-staged)\n- Containerised using [Docker](https://www.docker.com/) and [Docker Compose](https://docs.docker.com/compose/)\n- GitHub Actions\n- Makefile as project entrypoint\n- A lot of emojis 🛸\n\n### 🗂 Codebase structure\n\n```txt\nangular-skeleton/\n├── .github/\n├── .husky/\n├── .vscode/\n├── cypress/\n│   ├── e2e/\n│   ├── fixtures/\n│   ├── support/\n│   ├── coverage.webpack.js\n│   └── tsconfig.json\n├── docker/\n├── src/\n│   ├── app/\n│   │   ├── core/\n│   │   │   ├── components/\n│   │   │   ├── constants/\n│   │   │   ├── enums/\n│   │   │   ├── guards/\n│   │   │   ├── handlers/\n│   │   │   ├── interceptors/\n│   │   │   ├── loaders/\n│   │   │   ├── models/\n│   │   │   ├── resolvers/\n│   │   │   ├── services/\n│   │   │   ├── strategies/\n│   │   │   ├── tokens/\n│   │   │   ├── utils/\n│   │   │   ├── ...\n│   │   │   └── core.module.ts\n│   │   ├── features\n│   │   │   ├── feature-a\n│   │   │   │   ├── components/\n│   │   │   │   ├── models/\n│   │   │   │   ├── pages/\n│   │   │   │   ├── services/\n│   │   │   │   ├── ...\n│   │   │   │   ├── home-routing.module.ts\n│   │   │   │   └── home.module.ts\n│   │   │   ├── feature-b\n│   │   │   └── ...\n│   │   ├── shared/\n│   │   │   ├── components/\n│   │   │   ├── directives/\n│   │   │   ├── modules/\n│   │   │   ├── pipes/\n│   │   │   ├── services/\n│   │   │   └── shared.module.ts\n│   │   ├── app-routing.module.ts\n│   │   ├── app.browser.module.ts\n│   │   ├── app.component.html\n│   │   ├── app.component.scss\n│   │   ├── app.component.ts\n│   │   ├── app.module.ts\n│   │   └── app.server.module.ts\n│   ├── assets/\n│   │   ├── i18n/\n│   │   ├── icons/\n│   │   └── images/\n│   ├── environments/\n│   ├── styles/\n│   │   ├── abstracts/\n│   │   ├── base/\n│   │   ├── components/\n│   │   ├── layout/\n│   │   ├── vendors/\n│   │   └── main.scss\n│   ├── types/\n│   ├── favicon.ico\n│   ├── favicon.png\n│   ├── index.html\n│   ├── jest.mocks.ts\n│   ├── jest.setup.ts\n│   ├── main.browser.ts\n│   ├── main.server.ts\n│   ├── manifest.webmanifest\n│   ├── polyfills.ts\n│   ├── robots.txt\n│   └── styles.scss\n├── .browserslistrc\n├── .commitlintrc.js\n├── .cspell.json\n├── .czrc\n├── .dockerignore\n├── .editorconfig\n├── .env\n├── .eslintcache\n├── .eslintignore\n├── .eslintrc.js\n├── .gitignore\n├── .htmlhintrc\n├── .lintstagedrc.js\n├── .ncurc.js\n├── .npmignore\n├── .prettierignore\n├── .prettierrc.js\n├── .stylelintcache\n├── .stylelintignore\n├── .tool-versions\n├── .versionrc.js\n├── CHANGELOG.md\n├── LICENSE\n├── Makefile\n├── README.md\n├── TODO.md\n├── angular.json\n├── cypress.config.ts\n├── jest.config.js\n├── ngsw-config.json\n├── nyc.config.js\n├── package-lock.json\n├── package.json\n├── routes.txt\n├── server.ts\n├── stylelint.config.js\n├── tailwind.config.js\n├── transloco.config.js\n├── tsconfig.app.json\n├── tsconfig.json\n├── tsconfig.server.json\n└── tsconfig.spec.json\n```\n\n### 🎛️ Code style and best practices\n\n\u003e ⚠️ This section has yet to be fully documented.\n\n- Prettier\n- ESLint\n- Stylelint\n- HTMLHint\n- commitlint\n\n### 🛢 Barrel files\n\nBarrel files are used to organize exports. This significantly reduces the size of the import blocks.\n\n### 🏞 Application layout\n\n\u003e ⚠️ This section has yet to be fully documented.\n\n- Flexbox layout\n- TailwindCSS\n- Dark theme\n- Styles (SCSS) folder structure\n\n### 🌐 Internationalization (i18n)\n\n\u003e ⚠️ This section has yet to be fully documented.\n\n- Transloco\n- Route language prefixing\n\n### 🏎 Server Side Rendering (SSR) and Incremental Static Rendering (ISR)\n\n\u003e ⚠️ This section has yet to be fully documented.\n\n- Angular Universal\n- Domino\n- ngx-isr\n\n### 📇 Prerendering\n\n\u003e ⚠️ This section has yet to be fully documented.\n\n- Angular Universal\n\n### 📈 SEO\n\n\u003e ⚠️ This section has yet to be fully documented.\n\n- CustomPageTitleStrategy\n\n### 🔰 Progressive Web Application (PWA)\n\n\u003e ⚠️ This section has yet to be fully documented.\n\n- Service Worker configuration\n- Stale while revalidate strategy\n- Offline support\n\n### 🌠 Image lazy-loading\n\n\u003e ⚠️ This section has yet to be fully documented.\n\n- ng-lazyload-image\n\n### 💨 Module preloading strategies\n\n\u003e ⚠️ This section has yet to be fully documented.\n\n- [NoPreloading](https://angular.io/api/router/NoPreloading) (default)\n- [PreloadAllModules](https://angular.io/api/router/PreloadAllModules)\n- [CustomRoutePreloadStrategy](src/app/core/strategies/custom-route-preload.strategy.ts)\n- [NetworkAwareRoutePreloadingStrategy](src/app/core/strategies/network-aware-route-preload.strategy.ts)\n- [HoverPreloadStrategy](https://github.com/mgechev/ngx-hover-preload/blob/master/projects/ngx-hover-preload/src/lib/hover-preload.strategy.ts)\n- [QuicklinkStrategy](https://github.com/mgechev/ngx-quicklink/blob/master/src/quicklink-strategy.service.ts)\n\n### 🛣 Route reusability\n\n- RouteReuseStrategy\n\n### 🏒 Pipes\n\n\u003e ⚠️ This section has yet to be fully documented.\n\n### 🧪 Testing\n\n\u003e ⚠️ This section has yet to be fully documented.\n\n#### Unit and integration tests\n\n- Jest\n- jest-extended\n\n#### e2e tests\n\n- Cypress\n\n### 🐐 Makefile rules\n\nThe main actions on this project are managed using a [Makefile](Makefile) as an entrypoint.\n\n```bash\nUsage: make TARGET [ARGUMENTS]\n\nTargets:\n  build/csr                 Build csr image\n  build/ssr                 Build ssr image\n  clean/csr                 Clean CSR application\n  clean/ssr                 Clean SSR application\n  help                      Show this help\n  start/csr                 Start application in Client Side Rendering mode\n  start/ssr                 Start application in Server Side Rendering mode\n  stop/csr                  Stop application in Client Side Rendering mode\n  stop/ssr                  Stop application in Server Side Rendering mode\n```\n\n### ⚡ Scripts\n\n[package.json](package.json) scripts:\n\n```json\n  ...\n  \"scripts\": {\n    \"start:dev\": \"ng serve --configuration development --port 4200 --open\",\n    \"start:prod\": \"ng serve --configuration production --port 4300 --open\",\n    \"start:ssr:dev\": \"ng run angular-skeleton:serve-ssr:development --port 4201 --open\",\n    \"start:ssr:prod\": \"ng run angular-skeleton:serve-ssr:production --port 4301 --open\",\n    \"build:dev\": \"rimraf dist \u0026\u0026 ng build --configuration development\",\n    \"build:prod\": \"rimraf dist \u0026\u0026 ng build --configuration production \u0026\u0026 npm run build:optimize\",\n    \"build:ssr:dev\": \"rimraf dist \u0026\u0026 ng build --configuration development \u0026\u0026 ng run angular-skeleton:server:development\",\n    \"build:ssr:prod\": \"rimraf dist \u0026\u0026 ng build --configuration production \u0026\u0026 ng run angular-skeleton:server:production \u0026\u0026 npm run build:optimize\",\n    \"build:prerender:dev\": \"rimraf dist \u0026\u0026 ng run angular-skeleton:prerender:development\",\n    \"build:prerender:prod\": \"rimraf dist \u0026\u0026 ng run angular-skeleton:prerender:production \u0026\u0026 npm run build:optimize\",\n    \"build:optimize\": \"run-s optimize:* \u0026\u0026 ngsw-config dist/browser ./ngsw-config.json\",\n    \"optimize:i18n\": \"transloco-optimize dist/browser/assets/i18n\",\n    \"serve:pwa\": \"http-server -p 4400 -P http://localhost:4400? dist/browser -o\",\n    \"serve:ssr\": \"node dist/server/main.js\",\n    \"i18n:extract\": \"transloco-keys-manager extract\",\n    \"i18n:find\": \"transloco-keys-manager find\",\n    \"check:types\": \"tsc --pretty --noEmit \u0026\u0026 tsc --project cypress/tsconfig.json --pretty --noEmit\",\n    \"check:format\": \"prettier --check .\",\n    \"check:lint\": \"eslint . --ext .js,.ts --color\",\n    \"check:html\": \"htmlhint .\",\n    \"check:scss\": \"stylelint 'src/**/*.{css,scss}' --color\",\n    \"check:spelling\": \"cspell --config=.cspell.json \\\"{README.md,TODO.md,.github/*.md,src/**/*.ts,src/**/*.json}\\\"\",\n    \"check:i18n\": \"transloco-validator src/assets/i18n/*.json src/assets/i18n/**/*.json\",\n    \"check:staged\": \"lint-staged\",\n    \"fix:format\": \"prettier --check --write --ignore-unknown .\",\n    \"fix:lint\": \"npm run check:lint -- --fix\",\n    \"fix:scss\": \"npm run check:scss -- --fix\",\n    \"test\": \"cross-env NODE_ENV=test jest --verbose --colors --runInBand\",\n    \"test:spec\": \"npm run test -- --testPathPattern=spec\",\n    \"test:unit\": \"npm run test -- --testPathPattern=unit\",\n    \"test:int\": \"npm run test -- --testPathPattern=integration\",\n    \"e2e\": \"ng e2e\",\n    \"e2e:run\": \"ng run angular-skeleton:cypress-run\",\n    \"e2e:open\": \"ng run angular-skeleton:cypress-open\",\n    \"e2e:coverage:view\": \"http-server -p 9004 ./coverage-e2e/lcov-report -o\",\n    \"test:watch\": \"npm run test -- --watch\",\n    \"test:coverage\": \"npm run test -- --coverage --silent\",\n    \"test:coverage:view\": \"http-server -p 9003 ./coverage/lcov-report -o\",\n    \"reset-hard\": \"git clean -dfx \u0026\u0026 git reset --hard \u0026\u0026 npm install\",\n    \"version\": \"standard-version -t\",\n    \"prepare-release\": \"run-s reset-hard version\",\n    \"commit\": \"cz\",\n    \"update-deps\": \"npm-check-updates -u\",\n    \"prepare\": \"husky install\"\n  },\n  ...\n```\n\n## 🤝 Contributing\n\nJust fork and open a pull request. All contributions are welcome 🤗\n\n## 🛣️ Roadmap\n\nPlease, check [TODO](TODO.md) for the current roadmap.\n\n## 🎯 Credits\n\nTo implement this project I have based myself on many similar projects. There were countless of them and I gave them all a star.\n\n🙏 Thank you very much for these wonderful creations.\n\n### ⭐ Stargazers\n\n[![Stargazers repo roster for @borjapazr/angular-skeleton](https://reporoster.com/stars/borjapazr/angular-skeleton)](https://github.com/borjapazr/angular-skeleton/stargazers)\n\n## 🚩 License\n\nMIT @ [borjapazr](https://bpaz.dev). Please see [License](LICENSE) for more information.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fborjapazr%2Fangular-skeleton","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fborjapazr%2Fangular-skeleton","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fborjapazr%2Fangular-skeleton/lists"}