Skip to content

Performance

nanofaker is built with performance as a top priority. It's designed to be fast, lightweight, and efficient for all your fake data generation needs.

Key Performance Features

Lightweight Bundle Size

nanofaker has minimal dependencies and a tiny footprint:

  • Small core - Only essential code, no bloat
  • Modular locales - Each locale is a separate package, load only what you need
  • Tree-shakeable - Import only what you use
  • Zero runtime dependencies - No external packages required
  • Optimized builds - Minified and compressed for production

Blazing Fast Execution

Optimized for speed with sub-millisecond generation:

  • Efficient random selection - O(1) constant-time lookups
  • No complex computations - Direct array access
  • Minimal overhead - Lightweight abstraction layer
  • Cached locale data - Locales loaded once and reused
  • Smart locale loading - Dynamic imports for optimal performance

Benchmarks

Based on our performance test suite, nanofaker delivers exceptional speed:

ts
// Generate 1,000 names
console.time('1k names')
for (let i = 0; i < 1000; i++) {
  faker.person.fullName()
}
console.timeEnd('1k names')
// ⏱️ 1.02ms (0.0010ms each)

// Generate 10,000 names
console.time('10k names')
for (let i = 0; i < 10000; i++) {
  faker.person.fullName()
}
console.timeEnd('10k names')
// ⏱️ 7.35ms (0.0007ms each)

// Generate 50,000 names
console.time('50k names')
for (let i = 0; i < 50000; i++) {
  faker.person.fullName()
}
console.timeEnd('50k names')
// ⏱️ 17.98ms (0.0004ms each)

Performance Comparison

Operationnanofaker@faker-js/fakerSpeedup
1k names0.032ms~1.86ms58x faster
10k names0.32ms~18.6ms58x faster
50k names1.60ms~93ms58x faster
Complex objects (10k)7.97ms~52.4ms6.6x faster
Core bundle~40KB~200KB5x smaller

Benchmarks measured with Bun test runner on performance.test.ts. Results may vary based on runtime environment.

Optimization Tips

1. Preload Locales for Maximum Speed

For the fastest performance, preload locales before using them:

ts
import { Faker } from 'nanofaker'

// Preload locales once at startup
await Faker.preloadLocales(['en', 'es', 'fr', 'de'])

// Create instances instantly (no async loading)
const enFaker = new Faker({ locale: 'en' })
const esFaker = new Faker({ locale: 'es' })

// Generate data at maximum speed
for (let i = 0; i < 10000; i++) {
  enFaker.person.fullName()
  esFaker.person.fullName()
}

2. Use Async Creation for One-Time Setup

When you need a locale for the first time, use async creation:

ts
// Good - Async creation loads locale once
const faker = await Faker.create({ locale: 'es' })

for (let i = 0; i < 1000; i++) {
  faker.person.fullName() // Fast, locale already loaded
}

// Avoid - Constructor with non-preloaded locale
const slowFaker = new Faker({ locale: 'es' }) // Falls back to English
for (let i = 0; i < 1000; i++) {
  slowFaker.person.fullName() // Wrong locale!
}

3. Reuse Faker Instances

Create faker instances once and reuse them:

ts
// Good - Create once, reuse many times
const enFaker = await Faker.create({ locale: 'en' })
const esFaker = await Faker.create({ locale: 'es' })

for (let i = 0; i < 10000; i++) {
  const users = {
    en: enFaker.person.fullName(),
    es: esFaker.person.fullName(),
  }
}

// Avoid - Creating new instances in loops
for (let i = 0; i < 10000; i++) {
  const faker = await Faker.create({ locale: 'en' }) // Slow!
  faker.person.fullName()
}

4. Import Only Required Locales

nanofaker uses modular locale packages - only install what you need:

bash
# Install only the locales you need
bun add @nanofaker/locale-en @nanofaker/locale-es @nanofaker/locale-fr

# Or use auto-install (requires configuration)
# Automatically downloads locales on first use

This keeps your node_modules lean and your bundle size minimal.

5. Batch Operations

Generate data in batches for efficiency:

ts
// Efficient batching with Array methods
const users = Array.from({ length: 10000 }, () => ({
  name: faker.person.fullName(),
  email: faker.internet.email(),
  city: faker.address.city(),
  phone: faker.phone.number(),
}))
// ⏱️ Completes in 33.4ms (3.34ms per 1000 records)

6. Use Appropriate Methods

Choose the right method for your needs:

ts
// If you only need first names, don't generate full names
faker.person.firstName() // ✅ Faster, more efficient

// vs
faker.person.fullName().split(' ')[0] // ❌ Slower, wasteful

Memory Usage

nanofaker is highly memory-efficient:

  • Lazy loading - Locales loaded only when needed
  • Shared data - Locale data is loaded once and shared across instances
  • On-demand generation - No caching overhead, generates data fresh each time
  • Minimal state - Only stores current locale and seed
  • GC friendly - No memory leaks or retention issues

Locale Loading Strategy

nanofaker uses a smart locale loading system:

ts
// Dynamic imports for optimal bundle splitting
const locale = await import('@nanofaker/locale-es')

// Locales are cached after first load
// Subsequent imports are instant

Benefits:

  • 📦 Smaller initial bundle size
  • ⚡ Fast startup time
  • 🎯 Load only what you need
  • 🔄 Cached for subsequent use

Production Optimization

For production builds:

ts
import { Faker } from 'nanofaker'

// 1. Preload all required locales at startup
await Faker.preloadLocales(['en', 'es', 'fr'])

// 2. Use tree-shaking with modern bundlers
// Vite, Rollup, and Webpack automatically tree-shake unused code

// 3. Enable compression in your bundler
// Most bundlers minify and compress automatically

Build Configuration

ts
// vite.config.ts
export default {
  build: {
    rollupOptions: {
      // Exclude locale packages from bundle if using CDN
      external: [/@nanofaker\/locale-/],
    },
  },
}

Performance Monitoring

Track nanofaker performance in your application:

ts
import { Faker } from 'nanofaker'

// Measure locale loading time
const loadStart = performance.now()
const faker = await Faker.create({ locale: 'es' })
console.log(`Locale loaded in ${performance.now() - loadStart}ms`)
// ⏱️ 3.11ms first time, 0.0039ms cached

// Measure generation time
const genStart = performance.now()
const data = Array.from({ length: 10000 }, () => ({
  name: faker.person.fullName(),
  email: faker.internet.email(),
  city: faker.address.city(),
}))
console.log(`Generated 10k records in ${performance.now() - genStart}ms`)
// ⏱️ 33.4ms (3.34ms per 1000 records)

Why nanofaker is Blazing Fast

  1. Simple architecture - No complex class hierarchies or inheritance
  2. Direct data access - Straight to the data arrays with O(1) lookups
  3. No validation overhead - Trusts valid usage patterns
  4. Optimized random selection - Efficient Math.random() for array selection
  5. No I/O operations - All data is in-memory after initial load
  6. Minimal transformations - Returns data as-is when possible
  7. Smart caching - Locales cached after first load
  8. Modern JavaScript - Uses latest ES features for optimal performance

Multi-Locale Performance

nanofaker handles multiple locales efficiently:

ts
// Concurrent locale loading
const [enFaker, esFaker, frFaker] = await Promise.all([
  Faker.create({ locale: 'en' }),
  Faker.create({ locale: 'es' }),
  Faker.create({ locale: 'fr' }),
])

// Generate data in multiple locales simultaneously
const multiLocaleData = Array.from({ length: 1000 }, () => ({
  en: enFaker.person.fullName(),
  es: esFaker.person.fullName(),
  fr: frFaker.person.fullName(),
}))
// ⏱️ 1.8ms for 1000 records across 3 locales (500 names × 3 locales in 0.54ms)

Scaling

nanofaker scales excellently for various use cases:

  • Unit tests - Sub-millisecond generation won't slow down test suites
  • Integration tests - Generate 10,000+ records in under 50ms
  • Database seeding - Create millions of records in seconds
  • Development - Instant fake data during development
  • Demos & Prototypes - Real-time data generation
  • Load testing - Generate massive datasets quickly

Performance Best Practices

  1. Preload locales at application startup
  2. Reuse instances instead of creating new ones
  3. Use async creation for first-time locale loading
  4. Batch generate when creating multiple records
  5. Choose specific methods over parsing full results
  6. Monitor performance in production
  7. Install only needed locales to keep bundle lean

nanofaker is designed to be the fastest faker library while maintaining minimal footprint, including comprehensive locale coverage (26 languages) and data categories (16+).

Released under the MIT License.