How JavaScript Stores Primitive Values in Memory
Primitive values in JavaScript are stored directly in the variable's memory slot on the stack. Learn how this works, why primitives are immutable, and what happens during assignment.
JavaScript primitive memory storage works by keeping the value directly inside the variable itself. When you declare a variable and assign a primitive value to it, the engine stores that value directly in a memory region commonly called the stack. The variable's memory slot contains the actual data, not a pointer to somewhere else.
This direct storage model explains why primitives behave the way they do during assignment, comparison, and mutation.
The ECMAScript spec never mandates a stack or a heap. "Stack for primitives, heap for objects" is the mental model most engines like V8 follow in practice, and it is the right way to reason about the behavior in this article. Just do not treat it as a guarantee documented in the spec itself.
Each variable owns its value completely. There is no sharing, no indirection, and no hidden connection between variables.
When you assign a primitive to another variable, JavaScript copies the value into a new memory slot. The two slots are independent.
The Stack: Direct Value Storage
The stack is a region of memory that follows a last-in, first-out structure. It is fast to allocate and deallocate because it only tracks the top of the stack. JavaScript uses the stack for primitive values and for storing references to objects.
When you declare a variable inside a function, its value goes onto the stack. When the function returns, that stack space is automatically reclaimed. This is why local variables inside functions are destroyed when the function finishes.
function demo() {
let message = "hello"; // "hello" goes on the stack
let score = 10; // 10 goes on the stack
// both are destroyed when demo returns
}
demo();The variables message and score each get their own slot on the stack with their own copy of the value. Nothing is shared between them. This direct, independent storage is the foundation of how primitives work.
What Immutable Really Means
Primitive values are immutable, which means you cannot change the value itself. Any method that appears to modify a primitive actually creates and returns a brand new value. The original is untouched.
let greeting = "hello";
let upper = greeting.toUpperCase();
console.log(greeting); // "hello" (unchanged)
console.log(upper); // "HELLO" (new string)The toUpperCase method did not modify the original string "hello". It could not, because primitives are immutable. Instead, it created a brand new string "HELLO" and returned it.
The variable greeting still holds the original "hello".
This is different from objects, where methods can modify the object in place. Understanding immutability helps you predict what your code does. If a variable holds a primitive, its value never changes unless you explicitly reassign the variable itself.
let points = 10;
points = points + 5; // not mutating the number 10; creating a new number 15
console.log(points); // 15The plus operator did not change the number 10. It computed a new number 15 and assigned that to points, replacing the old value.
Assignment Creates Independent Copies
When you assign a primitive variable to another variable, JavaScript copies the value into a new memory slot. After the assignment, the two variables are completely independent.
let original = 50;
let duplicate = original;
duplicate = 100;
console.log(original); // 50
console.log(duplicate); // 100The variable duplicate received a copy of the number 50. Reassigning duplicate to 100 only affected its own memory slot. The original variable was never touched.
This behavior is consistent across all primitive types: strings, numbers, booleans, null, undefined, symbols, and bigints.
This is fundamentally different from objects. If original held an object instead of a number, duplicate would receive a reference to the same object, and mutating duplicate would also affect original. For a complete comparison of these two behaviors, see the primitive vs reference types guide.
Why Primitives Are Compared by Value
Because each primitive variable holds its own copy of the value, comparing two primitives compares the actual data. Two primitives are equal if they contain the same value, regardless of where that value came from.
let a = "test";
let b = "test";
let c = "other";
console.log(a === b); // true (same value)
console.log(a === c); // false (different value)
let x = 3.14;
let y = 3.14;
console.log(x === y); // true (same value)The comparison operator checks the actual values stored in each variable's memory slot. It does not care whether the values came from the same source or were computed differently. If the bits are the same, the comparison returns true.
The Practical Impact
Understanding stack storage and immutability matters for two practical reasons. First, it means you never need to worry about accidentally sharing primitive data between parts of your code. Every assignment is a safe, independent copy.
Second, it means methods that seem to transform a primitive always return a new value. If you forget to capture the return value, your code silently does nothing:
let name = "alex";
name.toUpperCase(); // returns "ALEX" but you ignored it
console.log(name); // "alex" (unchanged)
name = name.toUpperCase(); // capture the returned value
console.log(name); // "ALEX"This is a common beginner mistake. The method toUpperCase returns a new string, but if you do not assign it to a variable, the result is lost. The original string remains unchanged because primitives are immutable.
For a complete list of all primitive types and their characteristics, see the JavaScript data types guide. To understand how memory works for the other category of values, read the primitive vs reference types guide.
Rune AI
Key Insights
- Primitives are stored directly on the stack, not on the heap.
- Each variable holds its own copy of the primitive value.
- Primitives are immutable: methods return new values instead of modifying.
- Assignment creates an independent copy, never a shared reference.
- Objects, by contrast, are stored on the heap with pointer references.
Frequently Asked Questions
Where are primitive values stored in JavaScript?
What does immutable mean for primitives?
Are bigint and symbol also stored on the stack?
Conclusion
Primitive values are stored directly on the stack inside the variable's memory slot. They are immutable, meaning any method that appears to change a primitive actually returns a new value. Assignment always creates an independent copy. This stack-based, copy-by-value behavior is what makes primitives predictable and safe.
More in this topic
JavaScript While Loop Explained: A Complete Guide
A while loop repeats code as long as a condition stays true. Learn the syntax, see practical examples, and understand when a while loop is the right choice over a for loop.
JavaScript Loops Tutorial: for, while, do while
Loops let JavaScript repeat code without writing it twice. Learn the three core loop types, what each one does, and when to choose one over another.
How to Loop Through Arrays Using JS for Loops Guide
Looping through arrays is the most practical use of JavaScript for loops. Learn how to access each element by index, avoid off-by-one errors, and choose between for, for...of, and forEach.