The biggest reason JavaScript developers choose UUID v4 is decoupling. The application can generate the identifier itself instead of waiting for the database to assign one. This may seem minor, but it significantly affects system design. If a React or Vue client needs a temporary stable key before the record exists on the server, UUID v4 can provide it. If a Node.js API wants to create an object ID before persistence, logging, and event publication, the same identifier can travel through the entire request lifecycle. If a background worker processes many tasks in parallel, it can issue unique IDs locally without any shared counter.
That independence is especially useful in event-driven and distributed systems. Imagine a Node.js service that receives a request, writes a row, emits an event to Kafka, stores an S3 object, and logs a trace. When the identifier is generated at the application boundary, every downstream system can refer to the same value. UUID v4 is attractive here because it avoids coordination overhead without forcing you to stand up a custom ID service.
There is also a product and security-adjacent reason teams choose UUID v4. Public integer IDs are easy to enumerate. They reveal record counts, imply creation order, and make it trivial to probe adjacent values. That does not automatically create a vulnerability, but it is often undesirable. Random UUID v4 values are much harder to guess and do not expose a visible sequence. For public resource URLs, order IDs, upload tokens, session references, and request correlation IDs, that is often enough to justify using them.
In JavaScript specifically, the ergonomics are good. Modern browsers expose crypto.randomUUID(), and recent server-side JavaScript runtimes expose strong crypto APIs as well. You no longer need a heavy dependency just to create a standards-compliant random UUID. That matters for bundle size, maintenance, and operational simplicity. If the runtime already gives you the right primitive, the barrier to using UUID v4 is very low.