Top 4 JavaScript design patterns you should know

This guest post on JavaScript design patterns was written by Educative, Inc., an online learning platform for software engineers that provides interactive, text-based courses for learners of all levels. They help 400,000+ learners upskill and crack coding interviews through a personalized, hands-on learning experience.

Every JavaScript developer aims to write readable, reusable code. As your applications become larger, it becomes increasingly important to structure your code well. You can do this with design patterns. They provide an organization that will accommodate or solve common issues you’ll encounter in JavaScript.  

JavaScript design patterns are essential to your career as a JS developer, especially if you are preparing for a coding interview. System design concepts are used by interviewers to gauge your “hireability level”. There are all sorts of design patterns that you could master, but JavaScript developers tend to use certain patterns more than others. For more JavaScript interview prep, check out our list of JavaScript interview questions from top tech companies.

Read on as we learn about the 4 most common JavaScript design patterns and how we can use them to improve our code. We’ll discuss these patterns using real-world examples and challenges that you’re likely to encounter in an interview or on the job. 

Let’s get started! 

To take your learning to the next level, check out Educative’s interactive course JavaScript Design Patterns for Coding Interviews. By the end of this course, you’ll be able to confidently tackle advanced coding interview questions in JavaScript. 

What are design patterns?

In software engineering, a design pattern is a general, reusable solution to a common problem or situation, such as building a JavaScript web application. A design pattern is like a blueprint that provides a reusable template for solving these problems. Using a design pattern has many advantages for your JS code:

  • They are widely applicable. You can solve a multitude of common problems with the generic templates that they provide.
  • They are reusable. Other developers can easily build upon a design pattern. Since they aren’t tied to a specific problem, they can be reused throughout your code. 
  • They solve problems elegantly. Design patterns reduce the size of a codebase through optimized solutions. 
  • They are proven solutions. The results are reliable and efficient. That is because they are derived from the best practices of other experienced developers. You can be certain they’ll work when implemented. 
  • They eradicate the need to refactor code. Design patterns are the most tested, optimal solution for a given problem, so it’s unlikely that you’ll need to refactor the code. 

Design patterns fall under general umbrella terms that describe their overall behavior or structure. The four categories that design patterns fall under are: creational, structural, behavioral, and architectural. Check out our article Ace the top JavaScript Design Patterns for Coding Interviews to learn more about these categories. Or, keep reading as we discuss the top 4 design patterns and get familiar with their uses. 

1. Command design patterns

The command pattern allows encapsulation of the requests or operations into separate objects. It decouples the objects that send requests from the objects responsible for executing those requests. This makes it easy to pass method calls and issue commands that delegate responsibility to other objects. You can use it to: 

  • Queue and execute requests at different times
  • Perform operations such as reset or undo
  • Keep a history of requests 

Consider an example: a client is directly accessing the methods of an API throughout an application. Well, what happens when the implementation of that API changes? We could make use of abstraction to separate the requesting objects from those implementing the request. Now, if a change occurs, only the object making the call will need to change. The essence of the command pattern includes the following components. 

  • Invoker: asks the command to carry out the request
  • Command: has information about the action and binds it to the receiver by invoking the corresponding operation 
  • Receiver: knows how to perform the operations associated with the command
  • Client: creates a command and sets the receiver who’ll receive the command

Let’s look at an example of the pattern in JavaScript using the example of a printer. Here, we have a printingMachine with three operations. When the machine receives a command for those operations, it executes them. These classes extend the abstract Command class, and the child classes inherit the execute function.

2. Observer design pattern

The observer design pattern is useful for places where objects communicate with other objects. For example, there are many situations where one component of your code changes, so another component needs an update. The observer pattern communicates with dependent objects to do just that . In this behavioral pattern, the modules only modify the current state of data. An example of this is the MVC architecture: as one component changes, the other updates. 

When working with this pattern, we need to distinguish between independent and interdependent objects.  This pattern allows objects (called observers) that have subscribed to an event to wait for input and react to it when notified. The main subject maintains a list of all the observers. When the event occurs, it notifies the observers to update. 

The observer pattern is used when we need to: 

  • Improve code management by breaking down large applications into loosely-coupled objects
  • Provide greater flexibility by enabling a dynamic relationship between observers and subscribers 
  • Improve communication between different parts of the application
  • Create a one-to-many dependency between objects that are loosely coupled

Let’s look at an example in JavaScript code to understand how we implement this pattern. In this example, we have a Subject that stores the list of observers. The constructor initializes the list observerList that stores all the observers. It has two other properties: newArticlePosted (boolean variable to check whether a new article has been posted or not) and articleName (the name of the article). 

The constructor also defines the subscribe and unsubscribe functions to register or remove an observer from the subscription. We also define the Observer class with an update function that is invoked by the Subject to notify the observer. 

3. Singleton Pattern

The singleton pattern is a type of creational pattern that restricts the instantiation of a class to a single object. A class can create an instance of the class the first time it is instantiated, but on the next try, the existing instance of the class is returned. The singleton pattern is used mostly when you want a single object to coordinate actions across a system. 

Singletons are mostly used by:

  • Services: services can be singleton since they store the state, configuration, and provide access to resources. Therefore, it makes sense to have a single instance of a service in an application.
  • Databases: when it comes to database connections, databases such as MongoDB utilize the singleton pattern.
  • Configurations: if there is an object with a specific configuration, you don’t need a new instance every time that configuration object is needed.

For example, think of a printer in an office. The single printer instance is a shared resource amongst all the employees. When an employee needs to use a printer, they do not create a new one. Instead, they are directed to the existing printer. Then, they use that to print.  

Let’s create an instance of a printer in JavaScript code to see how it works. Here, we create a single instance of the class Printer with the getInstance function. This will accept the parameter numOfpages followed by some if statements. 

4. Prototype design pattern

The prototype creational pattern is used to instantiate objects and their default values using an existing object. We are essentially cloning the object and providing the existing properties to the cloned object using the concept of prototypal inheritance.

In prototypal inheritance, a prototype object is like a blueprint that other objects inherit from when instantiated. Any properties defined in the prototype (parent) will also be present in the cloned object (child). The prototypal pattern has native support in JavaScript. This pattern boosts the performance and efficiency of code and can be used in the following cases:

  • To eliminate the overhead of initializing an object
  • When you want the system to be independent about how its products are created
  • When creating objects from a database where the values are copied to the cloned object

Let’s see how this is done in JavaScript using the Object.create method. In this example, we will create two cars from a prototype. Here, both car1 and car2 have the same properties and methods as the car objects. So, Object.create takes an object as a parameter and returns an object with a prototype property that points to the object car. 

What to learn next 

Congratulations! You’ve now learned the basics of the top 4 JavaScript design patterns and seen how they can help your code. Design patterns are essential for writing optimized, reusable code.

There’s still a lot to learn to truly master design patterns. Your next step is to learn more object-oriented concepts.. Or, you can start mastering the other JavaScript design patterns like: 

  • Factory Pattern
  • Abstract Pattern
  • Facade Pattern
  • Flyweight Pattern
  • Iterator Pattern
  • Visitor Pattern 
  • And more 

To start learning these patterns and solving challenges that solidify your knowledge, check out Educative’s top-notch course JavaScript Design Patterns for Coding Interviews. You will learn how to effectively deploy design patterns to answer interview questions. By the end, you will be able to confidently use all Creational, Structural, Behavioral and Architectural design patterns to tackle advanced coding interview questions in JavaScript.

Happy learning!


Pathrise is a full service organization that helps people land their dream job in tech. We work extensively with software engineers by providing technical workshops, 1-on-1 mentoring sessions, and pair programming sessions. In addition, we offer guidance on other components of the job search, including resume, GitHub, and LinkedIn optimization, reverse recruiting, cold emailing, behavioral interviewing, salary negotiation, and more.

Apply today.

Leave a Reply

Your email address will not be published. Required fields are marked *