In JavaScript primitive types are passed by value.
let counter = 1;
let factory = () => {
  ...
  // The property `counter` in this object gets passed a value of the `counter` declared in the scope of `factory.js`.
  // It does not get a reference.
  return { counter, increment };
}
When you return the object from the factory function, its property counter is assigned a value from the counter declared in the scope of factory.js. This essentially means the counter property on the object received a copy of the value – there is nothing linking the value of the counter variable and the counter property.
let counter = 1;
let factory = () => {
  let increment = function () {
    // The `++` operates on the `counter` variable declared in the scope of `factory.js`.
    // There is no link between the value `counter` in the scope of `factory.js` and the `counter` as the property of the object returned.
    // As a result when the `counter` variable is incremented, the `counter` property remains the same as the value initially passed to it.
    counter++;
  };
};
When you increment the counter, you are incrementing the value of the variable declared in the scope of factory.js. The variable's value is a Number therefore being a primitive. Primitive values are passed by value so there is no link between the variable counter and the property counter.
Hopefully all that makes sense. If you want to do some more reading on this idea of passing by value (compared to passing by reference) you can see the following StackOverflow questions:
At this point in time you might be asking how can I fix this?
Instead of incrementing counter you need to increment this.counter. Like this:
let increment = () => {
  this.counter++;
};
This works because the context of this is the object being returned from the function factory. The counter property is on the variable you assigned the result of calling factory.