mrkeyoor.com_
Wed 05 Aug 05:01 UTC
npmWeb Frontendupdated 05 Aug 2026

@angular/core

@angular/core is the runtime of the Angular framework: components, dependency injection, signals for reactive state, lifecycle hooks, and change detection. Angular is a full platform rather than a view library; the official package family covers routing, forms, HTTP, SSR, and animations, and the CLI generates, builds, tests, and migrates projects. Modern Angular is standalone-component and signals based, with template control flow (@if, @for) built into the compiler, and v22 continues that line. You almost never install this package alone; it arrives as part of a CLI-generated workspace.

Verdict

Still the strongest option for large enterprise TypeScript apps that value one official way to do everything. For small or fast-moving projects the framework weight and twice-yearly major cadence cost more than they return.

API stability4/5Majors ship on a published schedule with long deprecation windows and automated ng update migrations; the NgModule-to-standalone and signals transitions still mean older code needs periodic modernization work
Docs5/5angular.dev has interactive tutorials, an in-browser playground, a complete API reference, and a per-version-pair update guide
Maintenance5/5Google-backed with pushes landing daily, 100k+ stars, about 1,150 open issues and PRs on a very large monorepo, and scheduled releases (22.1.0 current)
Ecosystem4/5Official packages plus Angular Material cover most needs; third-party breadth trails React's, and community libraries often lag a major or two behind

Use it if

  • You are building a large, long-lived app where one official answer for routing, forms, HTTP, DI, and testing beats assembling a stack from npm
  • Your team wants strong conventions and TypeScript-first tooling: the CLI scaffolds, builds, and upgrades projects (ng update) with automated migrations
  • You need structured dependency injection for testability across hundreds of services and components
  • You maintain enterprise apps where a predictable release schedule and long deprecation windows matter more than novelty
Skip it if

Setup reality

You do not npm install @angular/core by hand; you install the CLI globally (npm install -g @angular/cli) and run ng new, which generates the workspace and pins the whole @angular/* constellation plus peer dependencies (rxjs, zone.js, @angular/compiler) at matching versions. Version alignment is the recurring pain: every @angular/* package must move together, so upgrades go through ng update rather than editing package.json. New projects are standalone-component based; older codebases carry NgModules until someone runs the migration.

Patterns

Define a standalone componentstandalone-component

import { Component } from '@angular/core';

@Component({
  selector: 'app-hello',
  template: '<h1>Hello {{ name }}</h1>',
})
export class HelloComponent {
  name = 'Angular';
}

Components are standalone by default in modern Angular; you no longer write standalone: true or declare them in an NgModule.

Reactive state with signal and computedsignal-state

import { Component, computed, signal } from '@angular/core';

@Component({
  selector: 'app-counter',
  template: '<button (click)="inc()">{{ count() }} / {{ double() }}</button>',
})
export class CounterComponent {
  count = signal(0);
  double = computed(() => this.count() * 2);
  inc() {
    this.count.update((c) => c + 1);
  }
}

Signals are functions: read with count(), not count; forgetting the parentheses binds the function object instead of the value.

Declare a typed signal inputsignal-input

import { Component, input } from '@angular/core';

@Component({
  selector: 'app-user',
  template: '{{ user().name }}',
})
export class UserComponent {
  user = input.required<{ name: string }>();
}

input() replaces the @Input() decorator; input.required has no default, and reading it before the parent binds it throws.

Emit events to a parent with outputcomponent-output

import { Component, output } from '@angular/core';

@Component({
  selector: 'app-save',
  template: '<button (click)="saved.emit(\'ok\')">Save</button>',
})
export class SaveButtonComponent {
  saved = output<string>();
}

output() replaces @Output() with EventEmitter; parents still listen with (saved)="handler($event)" in the template.

Template control flow with @if and @forcontrol-flow

@if (user(); as u) {
  <p>{{ u.name }}</p>
} @else {
  <p>Loading</p>
}

@for (item of items(); track item.id) {
  <li>{{ item.label }}</li>
} @empty {
  <li>No items</li>
}

track is mandatory in @for; the compiler rejects the block without it, unlike the optional trackBy of the old *ngFor.

Get dependencies with inject()inject-service

import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({ providedIn: 'root' })
export class CartService {
  private http = inject(HttpClient);
}

inject() only works in an injection context (field initializers, constructors, provider factories); calling it inside a method throws NG0203.

Make HTTP calls with HttpClienthttp-request

// app.config.ts
import { provideHttpClient } from '@angular/common/http';

export const appConfig = {
  providers: [provideHttpClient()],
};

// user.service.ts
private http = inject(HttpClient);
users$ = this.http.get<User[]>('/api/users');

HttpClient observables are cold: nothing fires until something subscribes (the async pipe or toSignal counts).

Lazy-load a route with loadComponentlazy-route

import { Routes } from '@angular/router';

export const routes: Routes = [
  {
    path: 'admin',
    loadComponent: () =>
      import('./admin/admin.component').then((m) => m.AdminComponent),
  },
];

loadComponent lazy-loads a standalone component with no NgModule involved; the bundle split happens automatically at build.

Bootstrap a standalone applicationbootstrap-app

import { bootstrapApplication } from '@angular/platform-browser';
import { provideRouter } from '@angular/router';
import { AppComponent } from './app/app.component';
import { routes } from './app/app.routes';

bootstrapApplication(AppComponent, {
  providers: [provideRouter(routes)],
});

bootstrapApplication replaces platformBrowserDynamic().bootstrapModule; app-wide providers all move into this providers array.

Run side effects when signals changesignal-effect

import { Component, effect, signal } from '@angular/core';

@Component({ selector: 'app-theme', template: '' })
export class ThemeComponent {
  theme = signal<'light' | 'dark'>('light');

  constructor() {
    effect(() => {
      document.body.dataset.theme = this.theme();
    });
  }
}

effect() must be created in an injection context such as a constructor, and re-runs whenever any signal it read changes.

Alternatives

PackageRegistryPick it when
reactnpmYou want the biggest ecosystem and hiring pool and prefer picking your own router, state, and form libraries
vuenpmYou want a batteries-included framework with a gentler learning curve and single-file components
sveltenpmSmall bundles and compile-time reactivity matter more than enterprise structure