Skip to content

Replacing HttpClientModule in Angular 18

Problem Statement

If you've recently upgraded your Angular application to version 18, you may encounter a deprecation warning for HttpClientModule. This module was previously essential for using Angular's HttpClient service to make HTTP requests. In Angular 17 projects, typical usage looked like this:

typescript
@NgModule({
  imports: [BrowserModule, HttpClientModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
export class AppModule {}

Since Angular 18 marks HttpClientModule as deprecated, if your project uses this module:

  1. Your code will show deprecation warnings
  2. Your application might break in future Angular versions
  3. You need an updated setup to continue using HTTP functionality

The core issue is understanding Angular's new approach to providing HTTP services and migrating away from module-based setup to a function-based configuration.

Solution Overview

Angular 18 introduces a streamlined approach for configuring HttpClient:

  1. Deprecated: HttpClientModule (from @angular/common/http)
  2. Replacement: provideHttpClient() function (also from @angular/common/http)
  3. Migration path:
    • Remove HttpClientModule imports
    • Add provideHttpClient() to providers
    • Supports both module-based and standalone apps

This change eliminates duplication in HTTP setup and unifies configuration approaches across Angular's ecosystem.

Why This Change?

The Angular team deprecated HttpClientModule because:

  • It duplicated functionality already provided by provideHttpClient()
  • Caused confusion about having both module and function setups
  • Didn't align with Angular's shift toward standalone components
  • Added unnecessary complexity to dependency injection

The module was functionally equivalent to:

typescript
@NgModule({
  providers: [provideHttpClient(withInterceptorsFromDi())]
})

Migration Steps

For Module-based Applications

  1. Remove HttpClientModule from your module imports
  2. Add provideHttpClient() to your module's providers
typescript
import { provideHttpClient } from '@angular/common/http';

@NgModule({
  imports: [BrowserModule], // Removed HttpClientModule
  declarations: [AppComponent],
  providers: [provideHttpClient()], // Added here
  bootstrap: [AppComponent]
})
export class AppModule {}

WARNING

If you see Type 'EnvironmentProviders' is not assignable to type 'Provider':

  1. Remove any HttpClientModule imports from components
  2. Only import in app module as shown above

For Standalone Applications

Angular 18 new projects default to standalone configuration:

  1. Remove HttpClientModule from existing imports
  2. Add provideHttpClient() to your application providers
typescript
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    // Other providers...
    provideHttpClient()
  ]
};
typescript
import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { AppComponent } from './app/app.component';

bootstrapApplication(AppComponent, appConfig);

Advanced Configurations

Using the Fetch Backend

Enable Angular's Fetch API support by adding withFetch():

typescript
import { provideHttpClient, withFetch } from '@angular/common/http';

// In your providers:
provideHttpClient(withFetch());

Adding Interceptors

Use the functional interceptor pattern with withInterceptors:

typescript
import { HttpInterceptorFn } from '@angular/common/http';

export const authInterceptor: HttpInterceptorFn = (req, next) => {
  const authReq = req.clone({
    setHeaders: {
      Authorization: `Bearer ${sessionStorage.getItem('JWT')}`
    }
  });
  return next(authReq);
};
typescript
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { authInterceptor } from './auth.interceptor';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(
      withInterceptors([authInterceptor])
    )
  ]
};

Key Benefits of the New Approach

  1. Simplified Setup: No need for multiple configuration formats
  2. Future-proof: Aligns with Angular standalone direction
  3. Tree-shakable: Better optimization potential
  4. Interoperability: Works consistently across module/standalone apps
  5. Reduced Errors: Eliminates common misconfiguration mistakes

Conclusion

Migrating from HttpClientModule to provideHttpClient() in Angular 18 is a straightforward process:

  1. Remove deprecated module imports
  2. Add provideHttpClient() to providers
  3. Use withFetch() for Fetch API backend
  4. Implement functional interceptors with withInterceptors()

This change streamlines your HTTP setup and aligns your application with Angular's modern development patterns. Complete migrations ensure compatibility with future Angular releases and allow you to benefit from upcoming HTTP features.