Skip to main content Skills Marketplace Descubre y explora habilidades de IA creadas por la comunidad.
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Copiar promptMostrar detalles del prompt Un comando directo omite el prompt de revisión. Revisa el origen antes de ejecutarlo.
npx skills add https://github.com/Objective-Arts/lens-dist --skill angular-archEl comando permanece en una sola línea. Desplázate horizontalmente para revisarlo antes de copiarlo.
¿Prefieres una copia local? Descarga los archivos que SkillsMP tiene disponibles ahora.
Descargar Zip Descargando... Ocupaciones relacionadas SOC
Basado en la clasificación ocupacional SOC
Explorador de archivos
2 archivos name angular-arch description Angular architecture and organization patterns allowed-tools []
Deborah Kurata: Angular Architecture
Deborah Kurata's core belief: Well-organized code is maintainable code. Architecture decisions made early compound over the life of a project.
The Foundational Principle
"Structure your Angular application so that you can locate code quickly, identify what the code does at a glance, keep the flattest structure possible, and stay DRY."
The LIFT principle:
L ocate code quickly
I dentify code at a glance
F lattest structure possible
T ry to stay DRY
Core Principles
1. Feature Module Organization
Organize by feature, not by type.
Not this (organize by type):
src/app/
├── components/
│ ├── user-list.component.ts
│ ├── product-list.component.ts
│ └── order-list.component.ts
├── services/
│ ├── user.service.ts
│ ├── product.service.ts
│ └── order.service.ts
└── models/
├── user.model.ts
├── product.model.ts
└── order.model.ts
This (organize by feature):
src/app/
├── users/
│ ├── user-list.component.ts
│ ├── user-detail.component.ts
│ ├── user.service.ts
│ ├── user.model.ts
│ └── users.module.ts
├── products/
│ ├── product-list.component.ts
│ ├── product.service.ts
│ └── products.module.ts
└── shared/
├── components/
├── pipes/
└── shared.module.ts
2. Module Types and Responsibilities
Module Type Purpose Loads Root (App) Bootstrap Once at startup Feature Business feature Lazy loaded Shared Reusable components Imported by features Core Singleton services Once in AppModule Routing Route configuration With parent module
@NgModule ({
providers : [AuthService , LoggingService ]
})
export class CoreModule {
constructor (@Optional () @SkipSelf () parent : CoreModule ) {
if (parent) {
throw new Error ('CoreModule already loaded. Import only in AppModule.' );
}
}
}
@NgModule ({
declarations : [SpinnerComponent , TruncatePipe ],
exports : [SpinnerComponent , TruncatePipe , CommonModule ]
})
export class SharedModule {}
3. Smart vs Presentational Components Clear separation of concerns.
CONTAINER (Smart) PRESENTATIONAL (Dumb)
───────────────── ─────────────────────
user-shell.component user-list.component
user-detail.component
user-form.component
Responsibilities: Responsibilities:
- Fetch data - Display data
- Handle state - Emit events
- Coordinate children - No service injection
- Route handling - Pure @Input/@Output
feature/
├── feature-shell.component.ts # Smart container
├── feature-list.component.ts # Presentational
├── feature-detail.component.ts # Presentational
├── feature-edit.component.ts # Presentational
└── feature.service.ts
4. Barrel Files (index.ts) Export public API, hide internals.
export * from './users.module' ;
export * from './user.model' ;
export * from './user.service' ;
import { UserService , User } from '@app/users' ;
5. Path Aliases Use TypeScript path aliases for clean imports.
{
"compilerOptions" : {
"paths" : {
"@app/*" : [ "src/app/*" ] ,
"@core/*" : [ "src/app/core/*" ] ,
"@shared/*" : [ "src/app/shared/*" ] ,
"@env/*" : [ "src/environments/*" ]
}
}
}
import { UserService } from '@core/services/user.service' ;
6. State Management Patterns Choose complexity appropriate to your app.
COMPLEXITY LEVEL SOLUTION
──────────────── ────────
Simple Services + BehaviorSubject
Medium Component Store (@ngrx/component-store)
Complex Global Store (@ngrx/store)
Simple state (service-based):
@Injectable ({ providedIn : 'root' })
export class UserStateService {
private usersSubject = new BehaviorSubject <User []>([]);
users$ = this .usersSubject .asObservable ();
setUsers (users : User [] ) {
this .usersSubject .next (users);
}
}
Medium state (component store):
interface UserState {
users : User [];
loading : boolean ;
}
@Injectable ()
export class UserStore extends ComponentStore <UserState > {
readonly users$ = this .select (state => state.users );
readonly loading$ = this .select (state => state.loading );
readonly loadUsers = this .effect <void >(trigger$ =>
trigger$.pipe (
tap (() => this .patchState ({ loading : true })),
switchMap (() => this .userService .getAll ().pipe (
tapResponse (
users => this .patchState ({ users, loading : false }),
error => this .patchState ({ loading : false })
)
))
)
);
}
7. Route Organization One routing module per feature, lazy loaded.
const routes : Routes = [
{ path : '' , redirectTo : 'home' , pathMatch : 'full' },
{ path : 'home' , component : HomeComponent },
{
path : 'users' ,
loadChildren : () => import ('./users/users.module' ).then (m => m.UsersModule )
},
{
path : 'products' ,
loadChildren : () => import ('./products/products.module' ).then (m => m.ProductsModule )
},
{ path : '**' , component : PageNotFoundComponent }
];
const routes : Routes = [
{
path : '' ,
component : UserShellComponent ,
children : [
{ path : '' , component : UserListComponent },
{ path : ':id' , component : UserDetailComponent },
{ path : ':id/edit' , component : UserEditComponent }
]
}
];
8. Service Design Patterns Services should be focused and testable.
@Injectable ({ providedIn : 'root' })
export class UserDataService {
private url = '/api/users' ;
constructor (private http : HttpClient ) {}
getAll (): Observable <User []> {
return this .http .get <User []>(this .url );
}
getById (id : number ): Observable <User > {
return this .http .get <User >(`${this .url} /${id} ` );
}
}
@Injectable ({ providedIn : 'root' })
export class UserFacadeService {
constructor (
private userData : UserDataService ,
private userState : UserStateService
) {}
loadUsers ( ) {
this .userData .getAll ().subscribe (users => {
this .userState .setUsers (users);
});
}
}
9. Interface Segregation Small, focused interfaces over large ones.
interface User {
id : number ;
name : string ;
email : string ;
address : Address ;
orders : Order [];
preferences : Preferences ;
}
interface UserBasic {
id : number ;
name : string ;
email : string ;
}
interface UserWithAddress extends UserBasic {
address : Address ;
}
interface UserWithOrders extends UserBasic {
orders : Order [];
}
10. Consistent Naming Conventions ELEMENT NAMING CONVENTION
─────── ─────────────────
Feature module users.module.ts
Routing module users-routing.module.ts
Component user-list.component.ts
Service user.service.ts
Directive highlight.directive.ts
Pipe truncate.pipe.ts
Guard auth.guard.ts
Resolver user.resolver.ts
Interceptor logging.interceptor.ts
Model/Interface user.model.ts
The Kurata Test Before committing architecture decisions, ask:
Can I locate this code quickly? By feature, not by type?
Can I identify what this does at a glance? Clear naming?
Is the structure as flat as possible? No unnecessary nesting?
Am I repeating myself? Should this be in SharedModule?
Is this module focused? One responsibility?
Is state management appropriate? Not over-engineered?
When Reviewing Code
When NOT to Use This Skill Use a different skill when:
Designing DI and testability → Use angular-core
Optimizing performance → Use angular-perf
Working with RxJS → Use rxjs
Applying design patterns → Use design-patterns
Kurata is the Angular organization skill —use it for project structure, module design, and architecture patterns.
Sources
Kurata, "Angular Architecture: Best Practices" (Pluralsight)
Kurata, "RxJS and Reactive Forms in Angular" (Pluralsight)
Angular Style Guide (influenced by Kurata's work)
Kurata's conference talks and blog posts
"Good architecture is not about choosing the right technology—it's about organizing code so your team can work effectively." — Deborah Kurata