Installation Guide
This guide covers detailed installation, configuration, and customization options for Jet. If you just want to get started quickly, see the Quick Start guide .
Prerequisites
Make sure you have the following installed before starting:
Node.js 18.19+ or 20.9+
npm 10+ (comes with Node.js)
Git for version control
A code editor (VS Code recommended)
Verify Installation
node --version # Should show v18.19+ or v20.9+
npm --version # Should show 10+
git --version # Any recent version
Initial Setup
Clone Repository
git clone https://github.com/your-username/your-repo-name.git
cd your-repo-name
Install Dependencies
This installs all required packages and enables Husky for git hooks. The installation process will prepare git hooks automatically. If you see Husky errors, run npm run prepare.
Environment Configuration
Create Environment File
Copy the example environment file:
Environment Variables
Jet uses @ngx-env/builder for environment management. Configure these variables in .env:
.env
.env.example (Template)
# Google Analytics (optional)
NG_APP_GOOGLE_ANALYTICS_MEASUREMENT_ID = G-XXXXXXXXXX
NG_APP_IS_ANALYTICS_ENABLED = false
# Logging (recommended for development)
NG_APP_IS_LOGGING_ENABLED = true
# Supabase (required for auth)
NG_APP_SUPABASE_PUBLISHABLE_OR_ANON_KEY = your-anon-key
NG_APP_SUPABASE_URL = https://your-project.supabase.co
Never commit your .env file to version control. It’s already in .gitignore.
Access Environment Variables
Environment variables are available via injection tokens:
import { inject } from '@angular/core' ;
import { SUPABASE_CLIENT } from '@jet/injection-tokens/supabase-client.injection-token' ;
import { IS_LOGGING_ENABLED } from '@jet/injection-tokens/is-logging-enabled.injection-token' ;
export class MyService {
readonly #supabase = inject ( SUPABASE_CLIENT );
readonly #isLoggingEnabled = inject ( IS_LOGGING_ENABLED );
}
Supabase Setup
Jet uses Supabase for authentication, database, and storage. You can run Supabase locally or connect to a cloud project.
Local Development
Configure Project ID
Edit supabase/config.toml and set a unique project ID: project_id = "your-unique-project-id"
Start Supabase
This starts local Supabase containers with:
PostgreSQL database
Auth server
Storage server
Edge Functions runtime
Note the output - it contains your local credentials.
Update Environment
Copy the credentials to your .env file: NG_APP_SUPABASE_URL = http://localhost:54321
NG_APP_SUPABASE_PUBLISHABLE_OR_ANON_KEY =< anon-key-from-output >
Cloud Setup
Create Supabase Project
Go to supabase.com
Click “New Project”
Enter project name and database password
Select a region
Get Credentials
From your Supabase project dashboard:
Go to Settings > API
Copy the “URL” (Project URL)
Copy the “anon/public” key
Update Environment
Add credentials to .env: NG_APP_SUPABASE_URL = https://your-project.supabase.co
NG_APP_SUPABASE_PUBLISHABLE_OR_ANON_KEY = your-anon-key
Link Project
npx supabase link --project-ref your-project-ref
Get your project ref from the Supabase dashboard URL:
https://app.supabase.com/project/<project-ref>
Push Migrations
Apply database migrations to your cloud project:
Supabase Commands
Local Development
Migrations
Edge Functions
# Start Supabase locally
npx supabase start
# Stop Supabase
npx supabase stop
# Check status
npx supabase status
# Reset database
npx supabase db reset
Angular CLI Configuration
Jet uses Angular 21+ with the following configuration in angular.json:
Build Configuration
{
"build" : {
"builder" : "@ngx-env/builder:application" ,
"options" : {
"browser" : "src/main.ts" ,
"tsConfig" : "tsconfig.app.json" ,
"inlineStyleLanguage" : "scss" ,
"assets" : [{ "glob" : "**/*" , "input" : "public" }],
"styles" : [ "src/styles.scss" , "src/app-styles.scss" ]
},
"configurations" : {
"production" : {
"budgets" : [
{ "type" : "initial" , "maximumWarning" : "500kB" , "maximumError" : "1MB" },
{ "type" : "anyComponentStyle" , "maximumWarning" : "4kB" , "maximumError" : "8kB" }
],
"outputHashing" : "all" ,
"serviceWorker" : "ngsw-config.json"
}
}
}
}
The dev server includes production-like security headers:
{
"serve" : {
"options" : {
"headers" : {
"Content-Security-Policy" : "default-src 'none'; base-uri 'self'; connect-src 'self' http://localhost:54321 https://*.google-analytics.com ..." ,
"Cross-Origin-Embedder-Policy" : "credentialless" ,
"Cross-Origin-Opener-Policy" : "same-origin" ,
"Strict-Transport-Security" : "max-age=31536000; includeSubDomains; preload" ,
"X-Content-Type-Options" : "nosniff"
}
}
}
}
TypeScript Configuration
Jet uses strict TypeScript settings for maximum type safety:
{
"compilerOptions" : {
"strict" : true ,
"noImplicitOverride" : true ,
"noImplicitReturns" : true ,
"noFallthroughCasesInSwitch" : true ,
"exactOptionalPropertyTypes" : true ,
"noUncheckedIndexedAccess" : true ,
"noUnusedLocals" : true ,
"noUnusedParameters" : true ,
"target" : "ES2022" ,
"paths" : {
"@jet/services/*" : [ "src/app/services/*" ],
"@jet/components/*" : [ "src/app/components/*" ],
"@jet/guards/*" : [ "src/app/guards/*" ]
}
}
}
Path aliases make imports cleaner and prevent relative path issues.
ESLint
Lint your code:
Configuration in eslint.config.js with strict Angular rules.
Prettier
Format your code:
# Format all files
npm run format
# Format staged files only
npm run format-staged
Prettier runs automatically on commit via lint-staged.
Commitlint
Commit messages must follow Conventional Commits :
# Good commits
git commit -m "feat: add user profile page"
git commit -m "fix: resolve navigation issue"
git commit -m "docs: update readme"
# Or use the interactive prompt
npm run commit
Invalid commit messages will be rejected by Husky.
Customization
Theming
Jet uses Angular Material 3 theming. Generate a custom theme:
Visit Material Theme Builder
Choose your colors
Export the theme
Add to src/styles.scss
i18n
Add a new language:
Add Translation File
Create public/i18n/<lang-code>.json (copy from en.json): {
"home-page" : {
"toolbar-title" : "Accueil"
}
}
Register Language
Edit src/app/constants/language-options.constant.ts: export const LANGUAGE_OPTIONS : LanguageOption [] = [
{ flag: '🇺🇸' , name: 'English' , value: 'en' },
{ flag: '🇫🇷' , name: 'Français' , value: 'fr' },
];
Load Language Font (Optional)
Add language-specific fonts in src/index.html if needed.
Icons
Jet uses Material Symbols . Add icons in src/index.html:
< link
href = "https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,[email protected] ,100..700,0..1,-50..200&icon_names=home,settings,login,logout,menu,close"
rel = "stylesheet"
/>
Keep icon names alphabetically sorted for optimal font loading.
Development Workflow
Generate Components
# Generate a component
ng g c components/my-component
# Generate a page component
ng g c components/my-page
Follow the patterns in existing components:
Use ChangeDetectionStrategy.OnPush
Inject LoggerService
Use path aliases for imports
Add translations to i18n files
Generate Services
ng g s services/my-service/my-service
Services should:
Inject LoggerService
Log initialization
Use signals for reactive state
Add Routes
Edit src/app/app.routes.ts:
export const routes : Routes = [
{ component: HomePageComponent , path: '' },
{
path: 'my-page' ,
loadComponent : async () =>
( await import ( './components/my-page/my-page.component' )). MyPageComponent ,
},
];
Use lazy loading for better performance and smaller initial bundles.
Building for Production
Build Command
This creates optimized bundles in dist/ with:
Subresource integrity hashes
Optimized translations
Service worker for PWA
Minified code
Post-Build Scripts
Jet runs post-build optimizations automatically:
{
"scripts" : {
"build" : "ng build --subresource-integrity" ,
"postbuild" : "node ./scripts/add-icon-font-preload-tag.mjs && node ./scripts/optimize-translations.mjs"
}
}
Deployment
Vercel
Deploy to Vercel with zero configuration:
Deploy
Follow the prompts to link your project.
Set Environment Variables
In the Vercel dashboard:
Go to Settings > Environment Variables
Add all NG_APP_* variables
Redeploy
Jet works on any static hosting:
Netlify : Drag dist/browser to Netlify Drop
Cloudflare Pages : Connect repository, set build command to ng build
AWS S3 + CloudFront : Upload dist/browser contents
Firebase Hosting : Use firebase deploy
The output directory is dist/browser after building.
Removing Features
Remove Supabase
If you don’t need authentication:
Remove Supabase injection token from src/app/injection-tokens/
Remove auth components (sign-in, sign-up, etc.)
Remove Supabase packages:
npm uninstall @supabase/supabase-js
Delete supabase/ directory
Remove auth guards from routes
Remove RBAC
To remove role-based access control:
Delete src/app/enums/app-role.enum.ts
Remove role checks from guards
Remove role-related columns from database migrations
Remove Analytics
npm uninstall ga-gtag @types/ga-gtag
Remove AnalyticsService and AnalyticsDirective.
Troubleshooting
Port Already in Use
# Use a different port
ng serve --port 4300
Husky Not Working
# Reinstall git hooks
npm run prepare
Build Errors
# Clear caches
rm -rf .angular dist node_modules
npm install
Supabase Connection Issues
Check that:
Supabase is running (npx supabase status)
URL and key in .env are correct
CORS is configured in Supabase dashboard
Next Steps
Add Components Generate new components and build your UI
Configure Supabase Set up your database schema and auth flows
Customize Theme Make it your own with custom colors and fonts
Deploy Ship your app to production