
Static Methods vs. Instance Methods in JavaScript Classes

Once developers are comfortable with JavaScript class syntax, a more practical design question usually follows:
Should this method live on the class itself, or on each instance?
That is the difference between static methods and instance methods.
It is not only a syntax detail. It affects how the API reads, what data the method can access, and whether the class design stays intuitive as it grows.
Instance Methods Belong to Objects Created from the Class
If we define a method normally inside a class, instances can call it:
class User { constructor(public firstName: string, public lastName: string) {} getFullName(): string { return `${this.firstName} ${this.lastName}`; }}const user = new User('Ellie', 'Nguyen');console.log(user.getFullName());getFullName() is an instance method because it operates on the data stored in a particular user object.
That is the key clue. Instance methods usually need this.
Static Methods Belong to the Class Itself
If we add the static keyword, the method is called on the class rather than an instance:
class User { constructor(public firstName: string, public lastName: string) {} static createGuest(): User { return new User('Guest', 'User'); }}const guest = User.createGuest();Now the method lives on User, not on guest.
This is why the following would fail:
guest.createGuest();Static methods are not copied onto each instance.
The Simplest Decision Rule
Ask this question:
Does the method need to work with a specific instance's state?
If yes, it is probably an instance method.
If no, and it belongs conceptually to the class as a type or factory, it may be a good candidate for a static method.
Instance Methods Describe Object Behaviour
These are often the methods that read like verbs attached to a particular thing:
class Cart { constructor(public items: string[] = []) {} addItem(item: string): void { this.items.push(item); } getItemCount(): number { return this.items.length; }}Both methods rely on the state of one particular cart.
That makes them instance methods almost by definition.
Static Methods Often Work Well as Factory Helpers
This is one of the nicest uses of the feature.
For example:
class User { constructor(public firstName: string, public lastName: string) {} static fromApi(data: { first_name: string; last_name: string; }): User { return new User(data.first_name, data.last_name); }}fromApi() is not about one existing user instance. It is about creating a user instance from some external data shape.
That makes it feel much more natural as a static method than as an instance method.
Static Methods Can Also Group Class‑Related Utilities
Sometimes a helper is tightly related to the concept represented by the class, but does not belong to a specific object:
class Temperature { static fromFahrenheit(value: number): number { return (value - 32) * (5 / 9); }}You could write a standalone function instead. That is also valid.
The benefit of a static method is that it keeps the utility attached to the domain concept in a discoverable way.
A Common Mistake is Trying to Access Instance State from a Static Method
This catches people quickly:
class User { constructor(public firstName: string) {} static greet(): string { return `Hello, ${this.firstName}`; }}That does not do what many beginners expect, because in a static method this refers to the class itself, not an instance created from it.
If the method needs instance data, it should not be static.
The opposite Mistake Happens Too
Some methods are placed on instances even though they do not use instance state at all:
class User { formatName(firstName: string, lastName: string): string { return `${firstName} ${lastName}`; }}That forces callers to create a User instance just to use a general helper, which is usually a sign the method is in the wrong place.
It might belong:
- as a static method
- as a plain standalone function
The right answer depends on whether the logic truly belongs to the class concept.
Good Class Apis Usually Make the Distinction Feel Obvious
When the design is clean, the method placement reads naturally.
Instance methods feel like behaviour of a thing:
user.getFullName();cart.addItem('Notebook');Static methods feel like behaviour of the type:
User.createGuest();User.fromApi(payload);That difference in call site readability matters more than people sometimes admit.
Static Methods are Not Automatically "Better Organised"
There is a temptation to push lots of unrelated helpers into classes as static methods because it feels tidy.
But a class full of static utilities can easily become a namespace in disguise rather than a well‑shaped model.
So the real test is not whether a method can be made static. It is whether making it static improves the meaning of the API.
Inheritance Affects Static Methods Too
One subtle point worth knowing is that static methods are inherited by subclasses as well.
That can be useful for factory patterns, though it also means class hierarchies can become more complex if too many responsibilities are piled into static APIs.
You do not need to memorise every edge of that immediately. The important part is simply knowing that static behaviour is part of the class system, not a separate random feature.
The Real Question is Where the Behaviour Belongs
That is the theme behind all of this.
If the method answers a question about one object, or changes that object's data, make it an instance method.
If the method creates instances, transforms external input into instances, or offers class‑level behaviour that does not depend on one object's state, a static method may fit well.
When that distinction is respected, class‑based APIs stay much easier to read and maintain.
Static and Instance Methods are Both Useful for Different Reasons
This is not a contest where one style wins.
Instance methods make objects feel alive and coherent.
Static methods make class‑level helpers and factories discoverable.
The trick is simply to put each piece of behaviour in the place that reflects what it actually depends on. Once you do that, the syntax stops being the interesting part, and the class design starts making sense.
Related Articles

Understanding the :hover Pseudo‑Class in CSS. Understanding the

The will‑change Property in CSS. The
will‑changeProperty in CSS
UseReducer in React. useReducerin React
The LeetCode Zigzag Conversion Problem in TypeScript. The LeetCode Zigzag Conversion Problem in TypeScript

Flattening Arrays in JavaScript. Flattening Arrays in JavaScript

Solving the 'Letter Combinations of a Phone Number' Problem with TypeScript. Solving the 'Letter Combinations of a Phone Number' Problem with TypeScript

JavaScript Symbols: When and Why to Use Them. JavaScript Symbols: When and Why to Use Them

Array.find(), Array.some(), and Array.every() in JavaScript. Array.find(),Array.some(), andArray.every()in JavaScript
What Does a Software Engineer Do? What Does a Software Engineer Do?

Installing Gatsby onto an M1 MacBook Air. Installing Gatsby onto an M1 MacBook Air

Why querySelector Returns null in JavaScript. Why
querySelectorReturnsnullin JavaScript
All About Headless CMSes. All About Headless CMSes