Last Updated: 3/9/2026
Browser
Nano ID works in all modern browsers with the Web Crypto API.
Browser Support
- ✅ Chrome 11+
- ✅ Firefox 21+
- ✅ Safari 6.1+
- ✅ Edge (all versions)
- ✅ iOS Safari 6.1+
- ✅ Android Browser 4.4+
Installation
Via npm + Bundler
npm install nanoidimport { nanoid } from 'nanoid'
const id = nanoid()
console.log(id) //=> "V1StGXR8_Z5jdHi6B-myT"Via CDN
<script type="module">
import { nanoid } from 'https://cdn.jsdelivr.net/npm/nanoid/nanoid.js'
const id = nanoid()
console.log(id)
</script>Web Crypto API
Browsers use crypto.getRandomValues() for random generation:
// Nano ID uses this internally
const bytes = crypto.getRandomValues(new Uint8Array(21))Entropy sources:
- Hardware RNG (Intel RDRAND, ARM TrustZone)
- OS CSPRNG
- Browser entropy pool (mouse movements, timings)
Bundle Size
nanoid 118 bytes (minified + brotli)
customAlphabet 165 bytes
non-secure 90 bytesImpact: Negligible for most applications.
Bundler Configuration
Vite
// vite.config.js
export default {
// No configuration needed
}Webpack
// webpack.config.js
module.exports = {
resolve: {
alias: {
// Automatically uses index.browser.js
}
}
}Rollup
// rollup.config.js
import { nodeResolve } from '@rollup/plugin-node-resolve'
export default {
plugins: [
nodeResolve({
browser: true // Uses browser field from package.json
})
]
}Performance
Benchmark: ~381K ops/sec in Chrome
Why slower than Node.js?
- No pooling (direct crypto calls)
- Browser overhead
- Still fast enough for any real-world use
Use Cases
Form IDs
import { nanoid } from 'nanoid'
function createForm() {
const formId = nanoid()
return `
<form id="${formId}">
<label for="${formId}-name">Name</label>
<input id="${formId}-name" />
</form>
`
}Local Storage Keys
import { nanoid } from 'nanoid'
function saveItem(data) {
const id = nanoid()
localStorage.setItem(`item:${id}`, JSON.stringify(data))
return id
}Analytics Events
import { nanoid } from 'nanoid'
function trackEvent(event) {
analytics.track({
id: nanoid(),
event,
timestamp: Date.now()
})
}