Angular starter-kit for building quality web apps fast. Now with Supabase.
- 🆕 Modern Angular: Uses Signals, new template syntax, Zoneless, Standalone, lazy-loaded routes, and more.
- 📲 PWA-ready: Has safe-area styles for native-like edge-to-edge content in both portrait and landscape. Has background updating and offline support via @angular/service-worker.
- 🎨 Customizable: Support for light/dark/automatic color schemes. Theme generation via Angular Material. Support for multiple languages and language tools via Transloco. Custom fonts per language, RTL support, and more.
- 🌿 Pre-built features: Production-ready, responsive components for authentication and profile management. Authentication, profile management and RBAC flows integrated with Supabase. Easily set up your own back-end using migrations and swap out Supabase.
- 🚂 Services: Production-ready services for managing alerts, analytics, PWA updates, progress bar, browser storage, and more.
- 🚀 Performant: Modular and tree-shakeable. 80+ on PageSpeed Insights.
- 🔒 Secure: Locked-down CSP and other security headers. 80+ on Mozilla Observatory.
- 📏 Strict linting and formatting: Strict configurations for ESLint, Prettier and TypeScript.
- 🎁 Release management: Commit linting via @commitlint/*. Automatic versioning and changelog generation via Release Please.
- 🌻 Environment support: Easily configure environments via @ngx-env/builder and injection tokens.
- 🗻 Always updated: Actively maintained and regularly built from the ground-up. See 1000+ commits.
- Click the button above, create your repository, then clone it
- Create a copy of
.env.exampleand name it.env - Delete
./.github/FUNDING.yml - Delete
./CHANGELOG.md; a fresh one will be created on first release - Delete
./LICENSEand thelicenseproperty in./package.jsonand./package-lock.json - Reset the
versionproperty in both./package.jsonand./package-lock.jsonto0.0.0 - Run
npm install; this will also enable Husky - Find and replace
https://jet-tau.vercel.appwith the base URL of your app - Run
ng serveand start building!
Nice to do:
- Set namespace name in StorageService and
project_idin./supabase/config.tomlto something unique to your app - Update
./README.md(this file)
- Features
- Guides
- Sponsors
- License
- AppComponent
- FooterComponent
- HomePageComponent
- MessagePageComponent
- PageComponent
- ProfilePageComponent
- ResetPasswordPageComponent
- SettingsPageComponent
- SidenavComponent
- SignInPageComponent
- SignOutPageComponent
- SignUpPageComponent
- ToolbarComponent
- UpdatePasswordPageComponent
- AVATAR_FILE_MAX_SIZE_MB
- COLOR_SCHEME_OPTIONS
- DEFAULT_COLOR_SCHEME_OPTION
- DEFAULT_LANGUAGE_OPTION
- DEFAULT_SETTINGS
- LANGUAGE_OPTIONS
- NAVIGATION_MENU_ITEMS
- AppRole
- LocalStorageKey
- QueryParam
- SessionStorageKey
- SupabaseBucket
- SupabaseEdgeFunction
- SupabaseRpcFunction
- SupabaseTable
- AlertService
- AnalyticsService
- LoggerService
- ProfileService
- ProgressBarService
- ServiceWorkerService
- SettingsService
- StorageService
- ToolbarTitleService
- UserService
If you need help with something not listed here, create a new issue.
Use ng g as you would in any other Angular project.
- Run
ng g c components/<component-name> - In the
@Component()decorator:- Set
changeDetection: ChangeDetectionStrategy.OnPush - Set
imports: [TranslocoModule]
- Set
- In the class:
- Set
readonly #loggerService = inject(LoggerService); - As a convention, at the end of the constructor, set
this.#loggerService.logComponentInitialization('<ClassName>');
- Set
- As a convention, add the component selector as a key in en.json and other translation files
- Update spec
In the template, wrap the contents in:
<ng-container *transloco="let t"> ... </ng-container>- Run
ng g c components/<component-name> - In the
@Component()decorator:- Set
changeDetection: ChangeDetectionStrategy.OnPush - Set
imports: [TranslocoModule, PageComponent]
- Set
- In the class:
- Set
readonly #loggerService = inject(LoggerService); - As a convention, at the end of the constructor, set
this.#loggerService.logComponentInitialization('<ClassName>');
- Set
- As a convention, add the component selector as a key in en.json and other translation files
- Update spec
- Add a route to it in app.routes.ts
- Update sitemap-main.xml
- If required, add an icon and navigation link to it in NAVIGATION_MENU_ITEMS
In the template, wrap the contents in:
<ng-container *transloco="let t">
<jet-page
[seoDescription]="t('<component-selector>.seo.description')"
[seoKeywords]="t('<component-selector>.seo.keywords')"
[seoTitle]="t('<component-selector>.seo.title')"
[toolbarTitle]="t('<component-selector>.toolbar-title')"
>
...
</jet-page>
</ng-container>- Run
ng g s services/<service-name>/<service-name> - In the class:
- Set
readonly #loggerService = inject(LoggerService); - As a convention, at the end of the constructor, set
this.#loggerService.logServiceInitialization('<ClassName>');
- Set
- Add mock
- Update spec
When enabled, Husky prevents pushing code that fails linting or building.
Run npm run format-staged to format staged files. This runs automatically before every commit via Husky and Lint Staged.
Run npm run format to format all files.
Run ng lint. This runs automatically before every commit via Husky and ESLint.
Run ng test.
Run npm run commit, or commit directly with a valid commit message.
Commit messages that don't follow Conventional Commits will be blocked by Husky and Commitlint.
In .commitlintrc.json, update "scope-enum": [2, "always", ["general", "main", "<your-scope-1>", ..., "<your-scope-n>"]].
Update pre-commit. As a good practice, ensure every task is defined package.json and can be run independently.
More tasks mean longer commit times.
Run npm run reinstall-dependencies. It runs the following subscripts to remove all dependencies, then install their latest versions: x:uninstall-devDependencies, x:uninstall-dependencies, x:install-dependencies, x:install-devDependencies. You shouldn't have to run these subscripts yourself.
For this to work, ensure the subscripts are updated every time a dependency is added or removed.
Jet uses Material Symbols for icons. Instead of downloading the entire font, each icon is explicitly specified in index.html. To add or remove icons, update the icon names alphabetically in the <link> element (read more about this requirement here).
Custom SVG icons can be loaded in _setIcons() in AppComponent.
- Generate a Personal Access Token token with no expiry
- Save it to Actions > Secrets as
RELEASE_PLEASE_TOKEN
npx supabase statusnpx supabase startnpx supabase stopnpx supabase functions new <function-name>npx supabase functions servenpx supabase migrations newnpx supabase db reset
- Set
project_idin config.toml to something unique to the project
Support development of Jet. Pay what you like.
This project is licensed under the MIT License. See LICENSE for details.