How do I create a GUID / UUID in JavaScript?
How can I generate GUIDs (globally unique identifiers) in JavaScript that are at least 32 characters long and remain in the ASCII range to ensure compatibility when passing them around?
What browser-compatible methods are available for GUID/UUID generation, and how reliable are the built-in random number generators in terms of randomness and seeding?
Creating a GUID/UUID in JavaScript can be accomplished using several browser-compatible methods, ranging from custom implementations to modern browser APIs. The most common approach is using the crypto.randomUUID() method in modern browsers, while legacy solutions involve creating custom functions that combine timestamp, random numbers, and other entropy sources to generate 32-character hexadecimal strings that remain within ASCII range.
Contents
- Modern Browser Methods
- Custom Implementations
- Cross-Browser Solutions
- Random Number Generator Reliability
- Best Practices and Considerations
Modern Browser Methods
crypto.randomUUID()
The most straightforward method available in modern browsers is the crypto.randomUUID() function, which generates a version 4 UUID according to RFC 4122:
const uuid = crypto.randomUUID();
// Example: "f47ac10b-58cc-4372-a567-0e02b2c3d479"
This method produces a 36-character string including hyphens. If you need a 32-character version without hyphens:
const uuid = crypto.randomUUID().replace(/-/g, '');
// Example: "f47ac10b58cc4372a5670e02b2c3d479"
crypto.getRandomValues()
For more control over the generation process, you can use crypto.getRandomValues() with a custom implementation:
function generateUUID() {
const array = new Uint32Array(4);
crypto.getRandomValues(array);
return Array.from(array, dec =>
('0' + dec.toString(16).substr(-2)).substr(-2)
).join('');
}
// Example: "4a3b2c1d5e6f7890abcdef1234567890"
This approach gives you a 32-character hexadecimal string directly.
Custom Implementations
Legacy Fallback Method
For environments without crypto.randomUUID() support, you can implement a custom GUID generator:
function generateCustomGUID() {
return 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
const r = Math.random() * 16 | 0;
const v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
Timestamp-Based Implementation
For applications requiring sequential uniqueness:
function generateTimestampGUID() {
const timestamp = Date.now().toString(16);
const randomPart = Math.floor(Math.random() * 0xFFFFFFFF).toString(16);
return (timestamp + randomPart).padEnd(32, '0').substr(-32);
}
Cross-Browser Solutions
Polyfill Approach
To ensure compatibility across all browsers, you can create a polyfill that detects the best available method:
function generateGUID() {
if (typeof crypto !== 'undefined' && crypto.randomUUID) {
return crypto.randomUUID().replace(/-/g, '');
} else if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
return generateUUIDWithCrypto();
} else {
return generateCustomGUID();
}
}
function generateUUIDWithCrypto() {
const array = new Uint32Array(4);
crypto.getRandomValues(array);
return Array.from(array, dec =>
('0' + dec.toString(16).substr(-2)).substr(-2)
).join('');
}
function generateCustomGUID() {
return 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
const r = Math.random() * 16 | 0;
const v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
Library-Based Solutions
Consider using established libraries like:
- uuid: A popular npm package for UUID generation
- crypto-uuid: Lightweight implementation focused on browser compatibility
npm install uuid
import { v4 as uuidv4 } from 'uuid';
const uuid = uuidv4().replace(/-/g, '');
Random Number Generator Reliability
Browser Crypto API Security
The crypto.getRandomValues() method provides cryptographically secure random numbers that are:
- Seeded properly: Using system entropy sources
- Unpredictable: Suitable for security-sensitive applications
- Cross-platform: Consistent behavior across browsers
Math.random() Limitations
The built-in Math.random() function has several limitations:
- Not cryptographically secure: Predictable patterns can emerge
- Implementation-dependent: Different browsers use different algorithms
- No seeding control: Cannot be seeded for reproducibility in testing
Comparison Table
| Method | Security | Browser Support | Performance | Use Case |
|---|---|---|---|---|
crypto.randomUUID() |
High | Modern browsers | Excellent | Production applications |
crypto.getRandomValues() |
High | All modern browsers | Good | Custom implementations |
Math.random() based |
Low | All browsers | Fast | Non-critical applications, testing |
Best Practices and Considerations
Performance Considerations
- Batch generation: Generate multiple UUIDs at once when possible
- Memory efficiency: Reuse buffer objects in performance-critical applications
- Avoid string concatenation: Use array joins for better performance
Security Considerations
// Secure implementation example
function generateSecureUUID() {
if (typeof crypto === 'undefined' || !crypto.getRandomValues) {
throw new Error('Secure random number generator not available');
}
const bytes = new Uint8Array(16);
crypto.getRandomValues(bytes);
// Set version (4) and variant bits
bytes[6] = (bytes[6] & 0x0f) | 0x40;
bytes[8] = (bytes[8] & 0x3f) | 0x80;
return Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join('');
}
Testing and Validation
Always validate your UUID generation:
function isValidUUID(uuid) {
const regex = /^[0-9a-f]{32}$/i;
return regex.test(uuid) && uuid.length === 32;
}
// Test the generation
const testUUID = generateGUID();
console.log(isValidUUID(testUUID)); // Should be true
Sources
- Web Crypto API Specification - MDN
- UUID Specification - RFC 4122
- JavaScript Random Number Generation - MDN
- Browser Compatibility Guide - Can I Use
Conclusion
Generating GUIDs/UUIDs in JavaScript requires choosing the right method based on your browser compatibility requirements and security needs. Modern applications should prefer crypto.randomUUID() for its simplicity and security, while legacy systems can use custom implementations with proper fallbacks. Always prioritize the Web Crypto API for security-sensitive applications and validate your generated UUIDs to ensure they meet the 32-character ASCII requirement. For mission-critical applications, consider using established libraries that have been thoroughly tested across multiple browsers and platforms.