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:
@NgModule({
imports: [BrowserModule, HttpClientModule],
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule {}
Since Angular 18 marks HttpClientModule
as deprecated, if your project uses this module:
- Your code will show deprecation warnings
- Your application might break in future Angular versions
- 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:
- Deprecated:
HttpClientModule
(from@angular/common/http
) - Replacement:
provideHttpClient()
function (also from@angular/common/http
) - Migration path:
- Remove
HttpClientModule
imports - Add
provideHttpClient()
to providers - Supports both module-based and standalone apps
- Remove
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:
@NgModule({
providers: [provideHttpClient(withInterceptorsFromDi())]
})
Migration Steps
For Module-based Applications
- Remove
HttpClientModule
from your module imports - Add
provideHttpClient()
to your module's providers
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'
:
- Remove any
HttpClientModule
imports from components - Only import in app module as shown above
For Standalone Applications
Angular 18 new projects default to standalone configuration:
- Remove
HttpClientModule
from existing imports - Add
provideHttpClient()
to your application providers
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient } from '@angular/common/http';
export const appConfig: ApplicationConfig = {
providers: [
// Other providers...
provideHttpClient()
]
};
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()
:
import { provideHttpClient, withFetch } from '@angular/common/http';
// In your providers:
provideHttpClient(withFetch());
Adding Interceptors
Use the functional interceptor pattern with withInterceptors
:
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);
};
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
- Simplified Setup: No need for multiple configuration formats
- Future-proof: Aligns with Angular standalone direction
- Tree-shakable: Better optimization potential
- Interoperability: Works consistently across module/standalone apps
- Reduced Errors: Eliminates common misconfiguration mistakes
Conclusion
Migrating from HttpClientModule
to provideHttpClient()
in Angular 18 is a straightforward process:
- Remove deprecated module imports
- Add
provideHttpClient()
to providers - Use
withFetch()
for Fetch API backend - 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.