manutej/luxor-claude-marketplace/angular-development

Claude Code and agent skill by manutej/luxor-claude-marketplace

Trust tier 2
  • community
  • ext:[{"type":"hook","description":"Pre/post lifecycle hooks"}]
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Comprehensive Angular framework development covering components, directives, services, dependency injection, routing, and reactive programming based on official Angular documentation

Install

npx vskill@latest install manutej/luxor-claude-marketplace/angular-development

Semi-extensibleMentions customization, but needs skill-specific knowledge. Read the extensible skills standard

SKILL.md

Angular Development Skill

When to Use This Skill

Use this skill when working with Angular applications, including:

  • Building modern Angular applications with standalone components
  • Creating reactive UIs with Angular's component system
  • Implementing dependency injection patterns
  • Setting up routing with lazy loading and guards
  • Building reactive forms with validation
  • Managing state with Signals and RxJS
  • Creating custom directives and pipes
  • Implementing HTTP client integrations
  • Migrating from older Angular patterns to modern approaches
  • Optimizing Angular applications for performance
  • Setting up Angular projects with best practices

Core Concepts

Components

Components are the fundamental building blocks of Angular applications. They control a portion of the screen called a view.

Modern Standalone Component Pattern:

typescript
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-user-profile',
standalone: true,
imports: [CommonModule],
template: `
<div class="profile">
<h2>{{ user.name }}</h2>
<p>{{ user.email }}</p>
<button (click)="updateProfile()">Update</button>
</div>
`,
styles: [`
.profile {
padding: 20px;
border: 1px solid #ccc;
border-radius: 8px;
}
`]
})
export class UserProfileComponent {
user = {
name: 'John Doe',
email: 'john@example.com'
};
updateProfile() {
console.log('Updating profile...');
}
}

Component Lifecycle Hooks:

typescript
import { Component, OnInit, OnDestroy, AfterViewInit } from '@angular/core';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-lifecycle-demo',
standalone: true,
template: `<div>{{ message }}</div>`
})
export class LifecycleDemoComponent implements OnInit, OnDestroy, AfterViewInit {
message = '';
private subscription?: Subscription;
ngOnInit() {
// Called once after component initialization
console.log('Component initialized');
this.message = 'Component ready';
}
ngAfterViewInit() {
// Called after view initialization
console.log('View initialized');
}
ngOnDestroy() {
// Called before component destruction
console.log('Component destroyed');
this.subscription?.unsubscribe();
}
}
Services and Dependency Injection

Services provide shared functionality across components. Angular's dependency injection system makes services available throughout your application.

Modern Injectable Service with inject() Function:

typescript
import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
export interface User {
id: number;
name: string;
email: string;
}
@Injectable({
providedIn: 'root' // Singleton service available app-wide
})
export class UserService {
// Modern inject() function instead of constructor injection
private http = inject(HttpClient);
private apiUrl = 'https://api.example.com/users';
getUsers(): Observable<User[]> {
return this.http.get<User[]>(this.apiUrl);
}
getUserById(id: number): Observable<User> {
return this.http.get<User>(`${this.apiUrl}/${id}`);
}
createUser(user: Omit<User, 'id'>): Observable<User> {
return this.http.post<User>(this.apiUrl, user);
}
updateUser(id: number, user: Partial<User>): Observable<User> {
return this.http.patch<User>(`${this.apiUrl}/${id}`, user);
}
deleteUser(id: number): Observable<void> {
return this.http.delete<void>(`${this.apiUrl}/${id}`);
}
}

Using Services in Components:

typescript
import { Component, OnInit, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { UserService, User } from './user.service';
@Component({
selector: 'app-user-list',
standalone: true,
imports: [CommonModule],
template: `
<div class="user-list">
<h2>Users</h2>
@if (loading) {
<p>Loading...</p>
} @else if (error) {
<p class="error">{{ error }}</p>
} @else {
<ul>
@for (user of users; track user.id) {
<li>{{ user.name }} - {{ user.email }}</li>
}
</ul>
}
</div>
`
})
export class UserListComponent implements OnInit {
private userService = inject(UserService);
users: User[] = [];
loading = false;
error = '';
ngOnInit() {
this.loadUsers();
}
loadUsers() {
this.loading = true;
this.userService.getUsers().subscribe({
next: (users) => {
this.users = users;
this.loading = false;
},
error: (err) => {
this.error = 'Failed to load users';
this.loading = false;
console.error(err);
}
});
}
}
Signals - Modern Reactive State Management

Signals provide a new way to manage reactive state in Angular with fine-grained reactivity.

typescript
import { Component, signal, computed, effect } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-counter',
standalone: true,
imports: [CommonModule],
template: `
<div class="counter">
<h2>Counter: {{ count() }}</h2>
<p>Double: {{ doubleCount() }}</p>
<p>Status: {{ status() }}</p>
<button (click)="increment()">Increment</button>
<button (click)="decrement()">Decrement</button>
<button (click)="reset()">Reset</button>
</div>
`
})
export class CounterComponent {
// Writable signal
count = signal(0);
// Computed signal - automatically updates when count changes
doubleCount = computed(() => this.count() * 2);
status = computed(() => {
const value = this.count();
if (value < 0) return 'Negative';
if (value === 0) return 'Zero';
return 'Positive';
});
constructor() {
// Effect runs whenever signals it reads change
effect(() => {
console.log(`Count changed to: ${this.count()}`);
});
}
increment() {
this.count.update(value => value + 1);
}
decrement() {
this.count.update(value => value - 1);
}
reset() {
this.count.set(0);
}
}

Advanced Signals Pattern - Shopping Cart:

typescript
import { Injectable, signal, computed } from '@angular/core';
export interface CartItem {
id: number;
name: string;
price: number;
quantity: number;
}
@Injectable({
providedIn: 'root'
})
export class CartService {
private items = signal<CartItem[]>([]);
// Computed values
totalItems = computed(() =>
this.items().reduce((sum, item) => sum + item.quantity, 0)
);
totalPrice = computed(() =>
this.items().reduce((sum, item) => sum + (item.price * item.quantity), 0)
);
// Read-only access to items
getItems = this.items.asReadonly();
addItem(item: Omit<CartItem, 'quantity'>) {
this.items.update(currentItems => {
const existing = currentItems.find(i => i.id === item.id);
if (existing) {
return currentItems.map(i =>
i.id === item.id ? { ...i, quantity: i.quantity + 1 } : i
);
}
return [...currentItems, { ...item, quantity: 1 }];
});
}
removeItem(id: number) {
this.items.update(currentItems =>
currentItems.filter(item => item.id !== id)
);
}
updateQuantity(id: number, quantity: number) {
if (quantity <= 0) {
this.removeItem(id);
return;
}
this.items.update(currentItems =>
currentItems.map(item =>
item.id === id ? { ...item, quantity } : item
)
);
}
clear() {
this.items.set([]);
}
}
Routing

Angular's router enables navigation between views and lazy loading of feature modules.

Modern Route Configuration with Lazy Loading:

typescript
import { Routes } from '@angular/router';
export const routes: Routes = [
{
path: '',
redirectTo: '/home',
pathMatch: 'full'
},
{
path: 'home',
loadComponent: () => import('./home/home.component').then(m => m.HomeComponent)
},
{
path: 'users',
loadComponent: () => import('./users/user-list.component').then(m => m.UserListComponent)
},
{
path: 'users/:id',
loadComponent: () => import('./users/user-detail.component').then(m => m.UserDetailComponent)
},
{
path: 'admin',
loadComponent: () => import('./admin/admin.component').then(m => m.AdminComponent),
canActivate: [(route, state) => inject(AuthGuard).canActivate(route, state)]
},
{
path: '**',
loadComponent: () => import('./not-found/not-found.component').then(m => m.NotFoundComponent)
}
];

Route Guards with inject() Function:

typescript
import { Injectable, inject } from '@angular/core';
import { Router, CanActivateFn } from '@angular/router';
import { AuthService } from './auth.service';
// Functional guard (modern approach)
export const authGuard: CanActivateFn = (route, state) => {
const authService = inject(AuthService);
const router = inject(Router);
if (authService.isAuthenticated()) {
return true;
}
// Redirect to login
return router.createUrlTree(['/login'], {
queryParams: { returnUrl: state.url }
});
};
// Class-based guard (traditional approach)
@Injectable({
providedIn: 'root'
})
export class AuthGuard {
private authService = inject(AuthService);
private router = inject(Router);
canActivate(route: any, state: any): boolean {
if (this.authService.isAuthenticated()) {
return true;
}
this.router.navigate(['/login'], {
queryParams: { returnUrl: state.url }
});
return false;
}
}

Router with Route Parameters:

typescript
import { Component, OnInit, inject } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { switchMap } from 'rxjs/operators';
import { UserService, User } from '../services/user.service';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-user-detail',
standalone: true,
imports: [CommonModule],
template: `
<div class="user-detail">
@if (user) {
<h2>{{ user.name }}</h2>
<p>Email: {{ user.email }}</p>
<button (click)="goBack()">Back</button>
<button (click)="editUser()">Edit</button>
} @else {
<p>Loading user...</p>
}
</div>
`
})
export class UserDetailComponent implements OnInit {
private route = inject(ActivatedRoute);
private router = inject(Router);
private userService = inject(UserService);
user?: User;
ngOnInit() {
this.route.paramMap.pipe(
switchMap(params => {
const id = Number(params.get('id'));
return this.userService.getUserById(id);
})
).subscribe(user => {
this.user = user;
});
}
goBack() {
this.router.navigate(['/users']);
}
editUser() {
this.router.navigate(['/users', this.user?.id, 'edit']);
}
}
Reactive Forms

Reactive forms provide a model-driven approach to handling form inputs with built-in validation.

Form with Validation:

typescript
import { Component, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ReactiveFormsModule, FormBuilder, Validators } from '@angular/forms';

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
62
Repository forks
14
7-day trend score
21

Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 17 Mar 2026, 7 months ago.

Extension points

  • hookPre/post lifecycle hooks

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/manutej/luxor-claude-marketplace/angular-development/badge)](https://verified-skill.com/skills/manutej/luxor-claude-marketplace/angular-development)

Something wrong with this skill or its page? Tell us.