search
Angular star Featured

Fix: NG8001: 'app-component' is not a known element error in Angular

Learn how to fix the 'NG8001: 'app-component' is not a known element' error in Angular. This comprehensive guide covers component declarations, modules, and best practices.

person By Gautam Sharma
calendar_today January 2, 2026
schedule 11 min read
Angular NG8001 Components Error Frontend Development

The ‘NG8001: ‘app-component’ is not a known element’ error is a common Angular compilation issue that occurs when Angular’s template compiler cannot find a declared component. This error typically happens when components are not properly declared in modules, not imported correctly, or when there are issues with component selectors.

This comprehensive guide explains what causes this error, why it happens, and provides multiple solutions to fix it in your Angular projects with clean code examples and directory structure.


What is the NG8001 Error?

The “NG8001: ‘app-component’ is not a known element” error occurs when Angular’s template compiler encounters a component selector in a template but cannot find the corresponding component declaration. This is Angular’s way of telling you that it doesn’t recognize the element you’re trying to use.

Common Error Messages:

  • NG8001: 'app-component' is not a known element
  • Error occurs in the template of component MyComponent
  • 'app-component' is not a known element:
  • Can't bind to 'property' since it isn't a known property of 'app-component'

Understanding the Problem

Angular uses a modular system where components must be declared in modules or imported properly to be available for use. The NG8001 error occurs when there’s a mismatch between component selectors and their declarations, or when components aren’t properly exported/imported between modules.

Typical Angular Project Structure:

my-angular-app/
├── package.json
├── angular.json
├── src/
│   ├── app/
│   │   ├── app.component.ts
│   │   ├── app.component.html
│   │   ├── app.component.css
│   │   ├── app.module.ts
│   │   ├── shared/
│   │   │   ├── shared.module.ts
│   │   │   └── components/
│   │   │       └── reusable-component/
│   │   │           ├── reusable.component.ts
│   │   │           └── reusable.component.html
│   │   └── features/
│   │       └── feature-module/
│   │           ├── feature.component.ts
│   │           └── feature.module.ts
│   ├── assets/
│   └── index.html
└── node_modules/

Solution 1: Declare Component in AppModule

The most common cause is missing component declaration in the main application module.

❌ Without Proper Declaration:

// src/app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
// Importing the component but not declaring it

@NgModule({
  declarations: [
    AppComponent
    // ❌ Missing MyComponent in declarations
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

✅ With Proper Declaration:

app.module.ts:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { MyComponent } from './components/my-component/my-component.component'; // Import component

@NgModule({
  declarations: [
    AppComponent,
    MyComponent // ✅ Add component to declarations array
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Component File:

// src/app/components/my-component/my-component.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-my-component', // This selector must match template usage
  template: `<div>Hello from My Component!</div>`,
  styles: [`div { padding: 20px; }`]
})
export class MyComponent {
  // Component logic here
}

Using the Component:

<!-- src/app/app.component.html -->
<div>
  <h1>My Application</h1>
  <app-my-component></app-my-component> <!-- Component selector matches -->
</div>

Solution 2: Import Component in Feature Module

When using feature modules, ensure components are declared in the correct module.

feature.module.ts:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FeatureComponent } from './feature.component';
import { ChildComponent } from './child/child.component';

@NgModule({
  declarations: [
    FeatureComponent,
    ChildComponent // ✅ Declare child component in feature module
  ],
  imports: [
    CommonModule
  ],
  exports: [
    FeatureComponent // Export if needed by other modules
  ]
})
export class FeatureModule { }

Using Child Component:

<!-- feature.component.html -->
<div>
  <h2>Feature Component</h2>
  <app-child></app-child> <!-- Child component selector -->
</div>

Solution 3: Export and Import Components Between Modules

For components used across different modules, proper export/import is required.

shared.module.ts:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ReusableComponent } from './reusable.component';

@NgModule({
  declarations: [
    ReusableComponent
  ],
  imports: [
    CommonModule
  ],
  exports: [
    ReusableComponent // ✅ Export component for use in other modules
  ]
})
export class SharedModule { }

feature.module.ts:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FeatureComponent } from './feature.component';
import { SharedModule } from '../shared/shared.module'; // Import shared module

@NgModule({
  declarations: [
    FeatureComponent
  ],
  imports: [
    CommonModule,
    SharedModule // ✅ Import shared module containing reusable component
  ]
})
export class FeatureModule { }

Solution 4: Using Standalone Components (Angular 14+)

With standalone components, import components directly in the imports array.

parent.component.ts:

import { Component } from '@angular/core';
import { ChildComponent } from './child/child.component'; // Import child component

@Component({
  selector: 'app-parent',
  standalone: true,
  imports: [ChildComponent], // ✅ Import child component
  template: `
    <div>
      <h2>Parent Component</h2>
      <app-child></app-child> <!-- Child component usage -->
    </div>
  `
})
export class ParentComponent { }

child.component.ts:

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

@Component({
  selector: 'app-child',
  standalone: true,
  template: `<div>This is a child component</div>`
})
export class ChildComponent { }

Solution 5: Verify Component Selector Matching

Ensure component selectors match exactly between declaration and usage.

❌ Mismatched Selectors:

// Component with selector 'app-user-profile'
@Component({
  selector: 'app-user-profile',
  template: `<div>User Profile</div>`
})
export class UserProfileComponent { }
<!-- ❌ Using wrong selector -->
<app-user></app-user>

✅ Correct Selector Usage:

<!-- ✅ Using correct selector -->
<app-user-profile></app-user-profile>

Solution 6: Lazy Loading Module Issues

For lazy-loaded modules, ensure components are properly declared and routed.

feature-routing.module.ts:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { FeatureComponent } from './feature.component';

const routes: Routes = [
  { path: '', component: FeatureComponent }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class FeatureRoutingModule { }

feature.module.ts:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FeatureComponent } from './feature.component';
import { FeatureRoutingModule } from './feature-routing.module';

@NgModule({
  declarations: [
    FeatureComponent
  ],
  imports: [
    CommonModule,
    FeatureRoutingModule
  ]
})
export class FeatureModule { }

Solution 7: Complete Module Configuration

A comprehensive module configuration that handles components properly.

app.module.ts:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';

import { AppComponent } from './app.component';
import { HeaderComponent } from './layout/header/header.component';
import { FooterComponent } from './layout/footer/footer.component';
import { SidebarComponent } from './layout/sidebar/sidebar.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { AppRoutingModule } from './app-routing.module';

@NgModule({
  declarations: [
    AppComponent,
    HeaderComponent,
    FooterComponent,
    SidebarComponent,
    DashboardComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Working Code Examples

Complete Component Example:

// src/app/components/user-card/user-card.component.ts
import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-user-card', // Component selector
  templateUrl: './user-card.component.html',
  styleUrls: ['./user-card.component.css']
})
export class UserCardComponent {
  @Input() name: string = '';
  @Input() email: string = '';
  @Input() avatar: string = '';
}
<!-- src/app/components/user-card/user-card.component.html -->
<div class="user-card">
  <img [src]="avatar" [alt]="name" class="avatar">
  <div class="user-info">
    <h3>{{ name }}</h3>
    <p>{{ email }}</p>
  </div>
</div>
<!-- Using the component in another template -->
<app-user-card 
  [name]="'John Doe'" 
  [email]="'john@example.com'"
  [avatar]="'/assets/avatar.jpg'">
</app-user-card>

Module Declaration:

// src/app/components/components.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { UserCardComponent } from './user-card/user-card.component';

@NgModule({
  declarations: [
    UserCardComponent
  ],
  imports: [
    CommonModule
  ],
  exports: [
    UserCardComponent // Export for use in other modules
  ]
})
export class ComponentsModule { }

Best Practices for Component Management

1. Organize Components by Feature

// ✅ Group related components together
// src/app/features/user/
// ├── user.module.ts
// ├── user.component.ts
// ├── user-list.component.ts
// └── user-detail.component.ts

2. Use Shared Modules for Reusable Components

// ✅ Create shared modules for reusable components
@NgModule({
  exports: [CommonModule, FormsModule, ReactiveFormsModule]
})
export class SharedModule { }

3. Verify Selector Naming Convention

// ✅ Use consistent naming convention
@Component({
  selector: 'app-feature-name' // app- prefix with kebab-case
})

Debugging Steps

Step 1: Check Component Declaration

# Verify component is declared in the module
grep -r "declarations:" src/app/

Step 2: Verify Selector Matching

# Find component selector in TypeScript file
grep -r "selector:" src/app/components/my-component/

Step 3: Check Module Imports

# Verify module imports
grep -r "imports:" src/app/

Step 4: Test Component Usage

# Run Angular application to test
ng serve

Common Mistakes to Avoid

1. Forgetting to Declare Components

// ❌ Missing component in declarations
declarations: [
  AppComponent
  // Missing MyComponent
]

// ✅ Include all components
declarations: [
  AppComponent,
  MyComponent
]

2. Incorrect Selector Usage

<!-- ❌ Wrong selector -->
<app-wrong-selector></app-wrong-selector>

<!-- ✅ Correct selector -->
<app-correct-selector></app-correct-selector>

3. Not Exporting Shared Components

// ❌ Component not exported
exports: [] // Missing component export

// ✅ Export shared components
exports: [SharedComponent]

4. Circular Dependencies

// ❌ Avoid circular imports between modules
// Module A imports Module B, Module B imports Module A

Performance Considerations

1. Use Lazy Loading for Feature Modules

// Lazy load feature modules to improve initial load time
const routes: Routes = [
  { path: 'feature', loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule) }
];

2. Implement OnPush Change Detection

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

@Component({
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class MyComponent { }

Security Considerations

1. Sanitize Dynamic Content

import { DomSanitizer } from '@angular/platform-browser';

export class MyComponent {
  constructor(private sanitizer: DomSanitizer) {}
  
  sanitizeContent(content: string) {
    return this.sanitizer.bypassSecurityTrustHtml(content);
  }
}

2. Validate Component Inputs

import { Input, OnChanges } from '@angular/core';

export class MyComponent implements OnChanges {
  @Input() userId: number = 0;
  
  ngOnChanges() {
    if (this.userId <= 0) {
      throw new Error('Invalid user ID');
    }
  }
}

Testing Components

1. Unit Test for Component Usage

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MyComponent } from './my-component.component';

describe('MyComponent', () => {
  let component: MyComponent;
  let fixture: ComponentFixture<MyComponent>;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [MyComponent]
    });

    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

2. Test Component Integration

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ParentComponent } from './parent.component';
import { ChildComponent } from './child.component';

describe('ParentComponent', () => {
  let component: ParentComponent;
  let fixture: ComponentFixture<ParentComponent>;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [ParentComponent, ChildComponent] // Include child component
    });

    fixture = TestBed.createComponent(ParentComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create parent with child component', () => {
    expect(component).toBeTruthy();
  });
});

Alternative Solutions

1. Use Dynamic Components

import { ComponentFactoryResolver, ViewContainerRef } from '@angular/core';

export class MyComponent {
  constructor(
    private resolver: ComponentFactoryResolver,
    private container: ViewContainerRef
  ) {}

  loadComponent() {
    const factory = this.resolver.resolveComponentFactory(MyDynamicComponent);
    this.container.createComponent(factory);
  }
}

2. Use Structural Directives

<!-- Use *ngComponentOutlet for dynamic component loading -->
<div *ngComponentOutlet="dynamicComponent"></div>

Migration Checklist

  • Identify all components with NG8001 errors
  • Verify component declarations in appropriate modules
  • Check selector matching between declaration and usage
  • Ensure shared components are properly exported/imported
  • Test component functionality after fixes
  • Update documentation for team members
  • Verify lazy-loaded modules work correctly

Conclusion

The ‘NG8001: ‘app-component’ is not a known element’ error is a module declaration and import issue that can be resolved by properly declaring components in Angular modules or importing them correctly in standalone components. By following the solutions provided in this guide—whether through proper module declarations, shared module patterns, or standalone component imports—you can ensure your Angular applications recognize and render all components correctly.

The key is to understand Angular’s modular system and ensure that every component you want to use in a template is either declared in the same module or properly imported from another module. With proper component management, your Angular applications will work seamlessly with all custom elements, providing a smooth development experience.

Remember to maintain consistent naming conventions, organize components logically, and test thoroughly after making changes to ensure all components continue to work as expected.

Gautam Sharma

About Gautam Sharma

Full-stack developer and tech blogger sharing coding tutorials and best practices

Related Articles

Angular

Fix: Angular ExpressionChangedAfterItHasBeenCheckedError Error

Learn how to fix the 'ExpressionChangedAfterItHasBeenCheckedError' in Angular. This comprehensive guide covers change detection, lifecycle hooks, and best practices.

January 2, 2026
Angular

Fix: Angular app not working after build (production issue)

Learn how to fix Angular applications that don't work after production build. This comprehensive guide covers common production issues, optimization, and best practices.

January 2, 2026
Angular

How to Fix Cannot find module '@angular/compiler-cli Error in Angular'

Learn how to fix the 'Cannot find module @angular/compiler-cli' error in Angular projects. This comprehensive guide covers installation, dependencies, and best practices.

January 2, 2026