DEV Community

Priya Khanna
Priya Khanna

Posted on

A Quick guide to Dependency injection in JavaScript

Introduction: Dependency Injection(DI) might sound like a complex design pattern, but at its core, its a simple technique to make your code more modular, testable and maintainable. Lets look at how DI works in JavaScript and why it's worth using.

What is DI?
Its a pattern where an object or function receives its dependencies from the outside rather than creating them internally.

Without DI

class UserService{
   constructor(){
     this.api= new API();// tightly coupled
   }
}
Enter fullscreen mode Exit fullscreen mode

using DI

class UserService{
   constructor(api){
     this.api= api;// Dependency injected
   }
}
Enter fullscreen mode Exit fullscreen mode

here when we use DI userservice doesn't care how api is created- it gets and use when called.

Why use DI?

  1. Maintainability: You don’t hardcode dependencies — you swap them without rewriting core logic.
  2. Testability: You can inject mocks or stubs, making unit tests a breeze.
  3. Loose coupling: Your components/services aren’t stuck to concrete implementations.

Simple DI example in javaScript

js

// API service that fetches a user (mock implementation)
class API(){
  getUser(){
   return {id:1, name:'Priya khanna'}
  }
}

//UserService depends on API but does not create it internally

class UserService(){
  constructor(api){
   this.api=api;// Dependency injected
  }

  getUserInfo(){
   const user= this.api.getUser();
   return 'User : ${user.name}- ${user.id}'
  }
}

//application entry point
function main(){
 const api= new API();//create the dependency
 const userService= new UserService(api);// DI 

console.log(userService.getUserInfo());



}


main();
Enter fullscreen mode Exit fullscreen mode

Note:

  • the API class simulates a service that returns the data.
  • UserService expects an API instance passed in- this is constructor injection.

  • this pattern makes UserService easily testable and decoupled from API

bash

node di-example.js
Enter fullscreen mode Exit fullscreen mode

Key points:-

Dependency Injection (DI) isn’t exclusive to Angular; it’s a powerful design pattern used across many JavaScript frameworks and libraries to improve modularity, testability, and maintainability.

Here’s a quick overview of how DI appears beyond Angular:

  1. React: While React doesn’t have a built-in DI system like Angular, you can achieve DI-like behavior using Context API or third-party libraries like InversifyJS or BottleJS. These let you inject dependencies into components or hooks, improving decoupling.

  2. Vue.js: Vue supports DI through its provide/inject API, allowing parent components to provide dependencies that child components can inject, enabling flexible dependency management across component trees.

  3. Svelte: Svelte offers a context API similar to Vue’s provide/inject, enabling simple dependency passing without prop drilling.

  4. Node.js: On the backend, frameworks like NestJS (built on top of Express) implement DI extensively, inspired by Angular’s system, to manage service lifecycles and dependencies efficiently.

So, DI is a broadly applicable pattern in the JavaScript ecosystem, implemented differently depending on the framework’s architecture but always aiming to make code cleaner, more modular, and easier to test.

Top comments (0)