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, create the repository, then clone it
- Create a copy of
.env.example
and name it.env
- Delete
./.github/FUNDING.yml
- Delete
./CHANGELOG.md
- a fresh one will be created on first release - Delete
./LICENSE
and thelicense
property in./package.json
and./package-lock.json
- Reset the
version
property in both./package.json
and./package-lock.json
to0.0.0
- Run
npm install
- this will also enable Husky - Run
ng serve
and start building!
Nice to do:
- Delete or update
./README.md
- Find and replace
https://jet-tau.vercel.app
with the base URL of your app - Empty the footer template
- Set
this._prefix
in StorageService andproject_id
in./supabase/config.toml
to something unique to the project
- 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 status
npx supabase start
npx supabase stop
npx supabase functions new <function-name>
npx supabase functions serve
npx supabase migrations new
npx supabase db reset
- Set
project_id
in 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.