Upgrading to v9 
This is the migration guide for upgrading from v8 to v9.
Not the version you are looking for?
v9 has not yet been released. This page contains a work-in-progress list of breaking changes in v9.
General Breaking Changes 
Node 14 and 16 No Longer Supported 
Support for Node.js versions 14 and 16 has been discontinued as these versions have reached their end-of-life. Faker.js 9.0 requires a minimum of Node.js version 18.
Upgrade to TypeScript v5 
We now use TypeScript v5 for our project (previously v4). While generally not breaking for users, this might have small side effects on our types.
Usage of TypeScript 5 Features 
The helpers module now uses TS5 features, so if you are using Faker with TypeScript, you must use TS5.
// v8
faker.helpers.arrayElement([1, 2, 3]); // number
faker.helpers.arrayElement([1, 2, 3] as const); // 1 | 2 | 3
// v9
faker.helpers.arrayElement([1, 2, 3]); // 1 | 2 | 3If you are unable to upgrade to TS5, you have to keep using Faker v8.
Fix Tree Shaking 
Prior to this version, users had to resort to workarounds by importing specific faker instances from dedicated paths to overcome tree shaking issues.
import { faker } from '@faker-js/faker/locale/de';With the implementation of this fix, such workarounds should no longer be necessary. That means that you should be able to import different localized faker instances from the root of your package.
import { fakerDE, fakerES, fakerFR } from '@faker-js/faker';The dedicated import paths will still stay for now, to allow a gradual migration for our users.
While the implementation of this change does not constitute as breaking according to semantic versioning guidelines, it does impact the behavior of users bundlers.
Use High Precision RNG by default 
TLDR: Many Faker methods will return a different result in v9 compared to v8 for the same seed.
In v9 we switch from a 32 bit random value to a 53 bit random value. We don't change the underlying algorithm much, but we now consume two seed values each step instead of one. This affects generated values in two ways:
- In large lists or long numbers the values are spread more evenly. This also reduces the number of duplicates it generates. For faker.number.int()this reduces the number of duplicates from1 / 10_000to less than1 / 8_000_000.
- If you start with the same initial seed to generate a value, you might see some changes in the results you get. This is because we're now working with a higher precision, which affects how numbers are rounded off. As a result, the methods we use might produce slightly different outcomes. And since we are now using two seed values each time subsequent results appear to skip a value each time.
import {
  SimpleFaker,
  generateMersenne32Randomizer,
  generateMersenne53Randomizer,
} from '@faker-js/faker';
// < v9 default
const f32 = new SimpleFaker({ randomizer: generateMersenne32Randomizer() });
f32.seed(123);
const r32 = f32.helpers.multiple(() => f32.number.int(10), { count: 10 });
// > v9 default
const f53 = new SimpleFaker({ randomizer: generateMersenne53Randomizer() });
f53.seed(123);
const r53 = f53.helpers.multiple(() => f53.number.int(10), { count: 5 });
diff(r32, r53);
//[
//  7,
//  7,
//  3,
//  4,
//  2,
//  7,
//  6,
//  7,
//  7,
//  5,
//]Adoption 
If you don't have any seeded tests and just want some random values, then you don't have to change anything.
If you have seeded tests, you have to update most test snapshots or similar comparisons to new values.
If you are using vitest, you can do that using pnpm vitest run -u.
Keeping the old behavior 
You can keep the old behavior, if you create your own Faker instance and pass a Randomizer instance from the generateMersenne32Randomizer() function to it.
import {
  Faker,
  generateMersenne32Randomizer, // < v9 default
  generateMersenne53Randomizer, // > v9 default
} from '@faker-js/faker';
const faker = new Faker({
  randomizer: generateMersenne32Randomizer(),
  ...
});Using tsup for the build process 
We only support exports defined via package.json but after the switch to tsup, there are now complete restructures in the dist folder resulting it minified and chunked files for cjs.
Removals of Deprecated Code 
A large number of methods which were deprecated in v8 are completely removed in v9. To prepare for the upgrade, it is recommended to first upgrade to the latest version of v8 (e.g. npm install --save-dev faker@8) and fix any deprecation warnings issued by your code.
The following sections will contain more information about these changes.
Constructor and JS Backwards-Compatibility Methods 
Removed deprecated faker constructor, so it is not possible anymore to just pass a locale string identifier.
Also removed the accessors and method that were only for JS backwards compatibility.
- get/set locales
- get/set locale
- get/set localeFallback
- setLocale
To use the new constructor, you need to pass a locale object like:
import { Faker, es, base } from '@faker-js/faker';
// A custom faker instance that does not have any fallbacks
const customEsFakerWithoutFallback = new Faker({ locale: es });
// A custom faker instance that has only base-data as fallback, but not english data
const customEsFakerWithFallback = new Faker({ locale: [es, base] });Commerce Module 
Removed deprecated commerce methods
| old | replacement | 
|---|---|
| faker.commerce.price(min, max, dec, symbol) | faker.commerce.price({ min, max, dec, symbol }) | 
Company Module 
Removed deprecated company methods
| old | replacement | 
|---|---|
| faker.company.suffixes | Part of faker.company.name | 
| faker.company.companySuffix | Part of faker.company.name | 
| faker.company.bs | faker.company.buzzPhrase | 
| faker.company.bsAdjective | faker.company.buzzAdjective | 
| faker.company.bsBuzz | faker.company.buzzVerb | 
| faker.company.bsNoun | faker.company.buzzNoun | 
Datatype Module 
Removed deprecated datatype methods
| old | replacement | 
|---|---|
| faker.datatype.number() | faker.number.int()orfaker.number.float() | 
| faker.datatype.float() | faker.number.float() | 
| faker.datatype.datetime({ min, max }) | faker.date.between({ from, to })orfaker.date.anytime() | 
| faker.datatype.string() | faker.string.sample() | 
| faker.datatype.uuid() | faker.string.uuid() | 
| faker.datatype.hexadecimal() | faker.string.hexadecimal()orfaker.number.hex() | 
| faker.datatype.json() | your own function to generate complex objects | 
| faker.datatype.array() | your own function to build complex arrays | 
| faker.datatype.bigInt() | faker.number.bigInt() | 
Date Module 
Removed deprecated date methods
| old | replacement | 
|---|---|
| faker.date.past(years, refDate) | faker.date.past({ years, refDate }) | 
| faker.date.future(years, refDate) | faker.date.future({ years, refDate }) | 
| faker.date.between(from, to) | faker.date.between({ from, to }) | 
| faker.date.betweens(from, to, count) | faker.date.betweens({ from, to, count }) | 
| faker.date.recent(days, refDate) | faker.date.recent({ days, refDate }) | 
| faker.date.soon(days, refDate) | faker.date.soon({ days, refDate }) | 
| faker.date.month({ abbr }) | faker.date.month({ abbreviated }) | 
| faker.date.weekday({ abbr }) | faker.date.weekday({ abbreviated }) | 
Finance Module 
Removed deprecated finance methods
| old | replacement | 
|---|---|
| faker.finance.account | faker.finance.accountNumber | 
| faker.finance.mask | faker.finance.maskedNumber | 
| faker.finance.amount(min, max, dec, symbol, autoFormat) | faker.finance.amount({ min, max, dec, symbol, autoFormat }) | 
| faker.finance.iban(formatted, countryCode) | faker.finance.iban({ formatted, countryCode }) | 
Git Module 
Removed deprecated git methods
| old | replacement | 
|---|---|
| faker.git.shortSha() | faker.git.commitSha({ length: 7 }) | 
Helpers Module 
Removed deprecated helpers methods
| old | replacement | 
|---|---|
| faker.helpers.replaceSymbolWithNumber | string.replace(/#+/g, (m) => faker.string.numeric(m.length)) | 
| faker.helpers.regexpStyleStringParse | faker.helpers.fromRegExp | 
| faker.helpers.unique | import { UniqueEnforcer } from 'enforce-unique'; | 
Note these are not exact replacements:
faker.helpers.replaceSymbolWithNumber 
The replaceSymbolWithNumber method was deprecated in Faker 8.4 and removed in 9.0. The method parsed the given string symbol by symbol and replaces the # symbol with digits (0 - 9) and the ! symbol with digits >=2 (2 - 9). This was primarily used internally by Faker for generating phone numbers. If needed, you can use a simple string replace combined with faker.string.numeric to replace this
// old
faker.helpers.replaceSymbolWithNumber('#####-##'); // '04812-67'
// new
'#####-##'.replace(/#+/g, (m) => faker.string.numeric(m.length));
// old
faker.helpers.replaceSymbolWithNumber('!#####'); // '123152'
// new
'!#####'
  .replace(/#+/g, (m) => faker.string.numeric(m.length))
  .replace(/!+/g, (m) =>
    faker.string.numeric({ length: m.length, exclude: ['0', '1'] })
  );faker.helpers.regexpStyleStringParse 
The regexpStyleStringParse method in faker.helpers was deprecated in Faker 8.1 and removed in 9.0. A likely replacement is the more powerful faker.helpers.fromRegExp.
faker.helpers.regexpStyleStringParse('a{3,6}'); // aaaaa
faker.helpers.fromRegExp('a{3,6}'); // aaaaaHowever, please note that faker.helpers.fromRegExp is not an exact replacement for faker.helpers.regexpStyleStringParse as fromRegExp cannot handle numeric ranges. This will now need to be handled separately.
faker.helpers.regexpStyleStringParse('a{3,6}[1-100]'); // "aaaa53", etc.
faker.helpers.fromRegExp('a{3,6}') + faker.number.int({ min: 1, max: 100 });faker.helpers.unique 
Prior to v9, Faker provided a faker.helpers.unique() method which had a global store to keep track of duplicates. This was removed in v9.
Please see the unique values guide for alternatives.
For example, many simple use cases can use faker.helpers.uniqueArray. Or you can migrate to a third party package such as enforce-unique:
Basic example:
// OLD
const name = faker.helpers.unique(faker.person.firstName);
// NEW
import { UniqueEnforcer } from 'enforce-unique';
//const { UniqueEnforcer } = require("enforce-unique") // CJS
const enforcerName = new UniqueEnforcer();
const name = enforcerName.enforce(faker.person.firstName);With parameters:
// OLD
const stateCode = faker.helpers.unique(faker.location.state, [
  {
    abbreviated: true,
  },
]);
// NEW
import { UniqueEnforcer } from 'enforce-unique';
const enforcerState = new UniqueEnforcer();
const stateCode = enforcerState.enforce(() =>
  faker.location.state({
    abbreviated: true,
  })
);With options:
// OLD
const city = faker.helpers.unique(faker.location.city, [], {
  maxRetries: 100,
  maxTime: 1000,
});
// NEW
import { UniqueEnforcer } from 'enforce-unique';
const enforcer = new UniqueEnforcer();
const city = enforcer.enforce(faker.location.city, {
  maxRetries: 100,
  maxTime: 1000,
});Note
enforce-unique does not support the exclude or store options. If you were previously using these, you may wish to build your own unique logic instead.
Image Module 
Removed deprecated image methods
| old | replacement | 
|---|---|
| faker.image.image() | faker.image.url() | 
| faker.image.imageUrl() | faker.image.url() | 
| faker.image.abstract() | faker.image.urlLoremFlickr({ category: 'abstract' })orfaker.image.url() | 
| faker.image.animals() | faker.image.urlLoremFlickr({ category: 'animals' })orfaker.image.url() | 
| faker.image.business() | faker.image.urlLoremFlickr({ category: 'business' })orfaker.image.url() | 
| faker.image.cats() | faker.image.urlLoremFlickr({ category: 'cats' })orfaker.image.url() | 
| faker.image.city() | faker.image.urlLoremFlickr({ category: 'city' })orfaker.image.url() | 
| faker.image.food() | faker.image.urlLoremFlickr({ category: 'food' })orfaker.image.url() | 
| faker.image.nightlife() | faker.image.urlLoremFlickr({ category: 'nightlife' })orfaker.image.url() | 
| faker.image.fashion() | faker.image.urlLoremFlickr({ category: 'fashion' })orfaker.image.url() | 
| faker.image.people() | faker.image.urlLoremFlickr({ category: 'people' })orfaker.image.url() | 
| faker.image.nature() | faker.image.urlLoremFlickr({ category: 'nature' })orfaker.image.url() | 
| faker.image.sports() | faker.image.urlLoremFlickr({ category: 'sports' })orfaker.image.url() | 
| faker.image.technics() | faker.image.urlLoremFlickr({ category: 'technics' })orfaker.image.url() | 
| faker.image.transport() | faker.image.urlLoremFlickr({ category: 'transport' })orfaker.image.url() | 
image providers 
Removed deprecated image providers from faker.image. They already returned broken image URLs anyways.
| old | replacement | 
|---|---|
| faker.image.lorempicsum.image | faker.image.urlPicsumPhotos | 
| faker.image.lorempicsum.imageGrayscale | faker.image.urlPicsumPhotos({ grayscale: true }) | 
| faker.image.lorempicsum.imageBlurred | faker.image.urlPicsumPhotos({ blur: 4 }) | 
| faker.image.lorempicsum.imageRandomSeeded | faker.image.urlPicsumPhotos | 
| faker.image.lorempicsum.imageUrl | faker.image.urlPicsumPhotos | 
| faker.image.placeholder.imageUrl | faker.image.urlPlaceholder | 
| faker.image.placeholder.randomUrl | faker.image.urlPlaceholder | 
| faker.image.unsplash.image | faker.image.url | 
| faker.image.unsplash.imageUrl | faker.image.url | 
| faker.image.unsplash.food | faker.image.urlLoremFlickr({ category: 'food' }) | 
| faker.image.unsplash.people | faker.image.urlLoremFlickr({ category: 'people' }) | 
| faker.image.unsplash.nature | faker.image.urlLoremFlickr({ category: 'nature' }) | 
| faker.image.unsplash.technology | faker.image.urlLoremFlickr({ category: 'technology' }) | 
| faker.image.unsplash.objects | faker.image.urlLoremFlickr({ category: 'objects' }) | 
| faker.image.unsplash.buildings | faker.image.urlLoremFlickr({ category: 'buildings' }) | 
Internet Module 
Removed deprecated internet methods
| old | replacement | 
|---|---|
| faker.internet.avatar() | faker.image.avatarLegacy()orfaker.image.avatar() | 
| faker.internet.email(firstName, lastName, provider, options) | faker.internet.email({ firstName, lastName, provider, ... }) | 
| faker.internet.exampleEmail(firstName, lastName, options) | faker.internet.exampleEmail({ firstName, lastName, ... }) | 
| faker.internet.userName(firstName, lastName) | faker.internet.userName({ firstName, lastName }) | 
| faker.internet.displayName(firstName, lastName) | faker.internet.displayName({ firstName, lastName }) | 
| faker.internet.color(redBase, greenBase, blueBase) | faker.internet.color({ redBase, greenBase, blueBase }) | 
| faker.internet.password(length, memorable, pattern, prefix) | faker.internet.password({ length, memorable, pattern, prefix }) | 
Location Module 
Removed deprecated location methods
| old | replacement | 
|---|---|
| faker.location.zipCodeByState | faker.location.zipCode({ state }) | 
| faker.location.cityName | faker.location.city | 
| faker.location.streetName | faker.location.street | 
| faker.location.stateAbbr() | faker.location.state({ abbreviated: true }) | 
| faker.location.latitude(max, min, precision) | faker.location.latitude({ max, min, precision }) | 
| faker.location.longitude(max, min, precision) | faker.location.longitude({ max, min, precision }) | 
| faker.location.direction(abbreviated) | faker.location.direction({ abbreviated }) | 
| faker.location.cardinalDirection(abbreviated) | faker.location.cardinalDirection({ abbreviated }) | 
| faker.location.ordinalDirection(abbreviated) | faker.location.ordinalDirection({ abbreviated }) | 
| faker.location.nearbyGPSCoordinate(coordinate, radius, isMetric) | faker.location.nearbyGPSCoordinate({ origin, radius, isMetric }) | 
Removed Definitions 
The faker.definitions.location.default_country definition has been removed, as they were not used by any public method, and were not useful for locales which don't correspond directly to a single country, like ar.
Number Module 
Removed deprecated number parameter
| old | replacement | 
|---|---|
| faker.number.float({ precision }) | faker.number.float({ multipleOf }) | 
Person Module 
Changed Definitions 
The locale definitions used by faker.person.jobTitle(), faker.person.jobDescriptor(), faker.person.jobArea() and faker.person.jobType() have been reorganized and are no longer nested under definitions.person.title. If you are using the public methods, no changes are required. You only need to change your code if you are accessing the raw definitions e.g. in faker.helpers.fake().
| Before | After | 
|---|---|
| person.title.descriptor | person.job_descriptor | 
| person.title.level | person.job_area | 
| person.title.job | person.job_type | 
Phone Module 
Removed deprecated phone methods
| old | replacement | 
|---|---|
| faker.phone.number(format) | faker.phone.number(),faker.string.numeric()orfaker.helpers.fromRegExp() | 
Random Module 
Removed deprecated random module
| old | replacement | 
|---|---|
| faker.random.alpha() | faker.string.alpha() | 
| faker.random.alphaNumeric() | faker.string.alphanumeric() | 
| faker.random.locale() | faker.helpers.objectKey(allLocales/allFakers) | 
| faker.random.numeric() | faker.string.numeric() | 
| faker.random.word() | faker.lorem.word()orfaker.word.sample() | 
| faker.random.words() | faker.lorem.words()orfaker.word.words() | 
Locale Aliases 
Removed deprecated locale aliases
| old | replacement | 
|---|---|
| import { faker } from '@faker-js/faker/locale/cz' | import { faker } from '@faker-js/faker/locale/cs_CZ' | 
| import { faker } from '@faker-js/faker/locale/en_IND' | import { faker } from '@faker-js/faker/locale/en_IN' | 
| import { faker } from '@faker-js/faker/locale/ge' | import { faker } from '@faker-js/faker/locale/ka_GE' | 
| import { faker } from '@faker-js/faker/locale/global' | import { faker } from '@faker-js/faker/locale/base' | 
Type Aliases 
Removed deprecated type aliases
| old | replacement | 
|---|---|
| AddressDefinitions | LocationDefinition | 
| AirlineDefinitions | AirlineDefinition | 
| AnimalDefinitions | AnimalDefinition | 
| ColorDefinitions | ColorDefinition | 
| CommerceDefinitions | CommerceDefinition | 
| CommerceProductNameDefinitions | CommerceProductNameDefinition | 
| CompanyDefinitions | CompanyDefinition | 
| DatabaseDefinitions | DatabaseDefinition | 
| DateDefinitions | DateDefinition | 
| FinanceDefinitions | FinanceDefinition | 
| HackerDefinitions | HackerDefinition | 
| InternetDefinitions | InternetDefinition | 
| LoremDefinitions | LoremDefinition | 
| MusicDefinitions | MusicDefinition | 
| NameDefinitions | PersonDefinition | 
| PhoneNumberDefinitions | PhoneNumberDefinition | 
| ScienceDefinitions | ScienceDefinition | 
| SystemDefinitions | SystemDefinition | 
| SystemMimeTypeEntryDefinitions | SystemMimeTypeEntryDefinition | 
| VehicleDefinitions | VehicleDefinition | 
| WordDefinitions | WordDefinition | 
| CSSFunction | CssFunctionType | 
| CSSSpace | CssSpaceType | 
| AddressModule | LocationModule | 
| NameModule | PersonModule | 
Breaking Changes to Specific Methods 
Changed Default Mode from Birthdate 
Previously, the method had defaults that were unclear in their specific impact. Now, the method requires either none or all of the min, max and mode options.
We also improved the error messages in case of invalid min/max age/year ranges.
Fail on Invalid Dates 
Various methods in the faker.date module allow you to pass a Date-ish value: that is, either a Javascript Date, or a timestamp number or string that can be converted to a Date via the new Date() constructor.
Previously, if you passed something which could not be parsed to a Date, it would fall back to the current reference date. Now, this throws an error raising awareness of that bad value.
This affects the refDate parameter of the anytime(), birthdate(), past(), future(), recent() and soon(), methods as well as the from and to parameters of between() and betweens().
Prices now return more price-like values 
The faker.commerce.price method now produces values, that also return fractional values.
Old price: 828.00 New price: 828.59
The last digit of the price will adjusted to be more price-like:
- 50% of the time: 9
- 30% of the time: 5
- 10% of the time: 0
- 10% of the time: a random digit from 0to9
We plan to rethink this method some more in the future: #2579
Randomized Image Option Defaults 
faker.image.url() now returns an image url with a random width and height by default. To obtain the previous behavior, pass {width: 640, height: 480}.
faker.image.urlLoremFlickr() now returns an image url with a random width and height by default. To obtain the previous behavior, pass {width: 640, height: 480}.
faker.image.urlPicsumPhotos() now returns an image url with a random width and height by default, additionally images may be converted to grayscale and blurred at random. To obtain the previous behavior, pass {width: 640, height: 480, blur: 0, grayscale: false}
faker.image.dataUri() now returns an image url with a random width and height by default, additionally the type of the image is now random. To obtain the previous behavior, pass {width: 640, height: 480, type: 'svg-uri'}.
Require from and to in faker.date.between() and betweens() 
Previously, in faker.date.between() and faker.date.betweens() if the from or to parameter was omitted (in Javascript) or an invalid date (in Javascript or Typescript), they would default to the current date or reference date. Now, both boundaries must now be given explictly. If you still need the old behavior, you can pass Date.now() or the reference date for from or to.
Stricter Checking for Function Signature passed to faker.helpers.multiple Method 
The faker.helpers.multiple method takes a function reference as its first parameter. Previously you may have written code like this to generate multiple values.
faker.helpers.multiple(faker.date.past, { count: 2 });However this code has a bug - faker.helpers.multiple passes the loop index as the second parameter to the method, which in this case would set the refDate of the faker.date.past() call to 0, making all dates before 1970.
Instead you should generally use a lambda function like
faker.helpers.multiple(() => faker.date.past(), { count: 2 });to get the desired behavior. In v9.0, we use stricter type-checking in Typescript to detect when a function is called which is not compatible with (v: unknown, index: number) which can cause compile-time errors in places where previously there were potential runtime errors.
Bad
faker.helpers.multiple(faker.person.firstName, ...); // ❗
// In Typescript, this is now a compile time error
// Argument of type '(sex?: "female" | "male" | undefined) => string'
// is not assignable to parameter of type '(v: unknown, index: number) => unknown'.Good
faker.helpers.multiple(() => faker.person.firstName(), ...); // ✔The new types also allow for easier use-cases where the index is part of the generated data e.g. as id.
faker.helpers.multiple((_, index) => ({ id: index, ...}), ...); // [{id: 0, ...}, ...]Stricter Enum Value Usage 
Some methods would previously fallback to a default value for an option when an unknown value was passed for a enum parameter. Now, these methods will return undefined instead. This only affects usage in Javascript, as in Typescript this usage would already throw a compile-time error.
For example:
faker.color.rgb({ format: 'unexpectedvalue' });
// in Faker v8, is [110, 82, 190] like { format: "decimal" }
// in Faker v9, is undefinedThis affects:
- The formatproperty offaker.color.rgb()must be one of'binary' | 'css' | 'decimal' | 'hex'if provided
- The formatproperty offaker.color.cmyk(),faker.color.hsl(),faker.color.hwb(),faker.color.lab(),faker.color.lch()must be one of'binary' | 'css' | 'decimal'if provided
- The variantproperty offaker.location.countryCode()must be one ofalpha-2,alpha-3,numericif provided
- The casingproperty offaker.string.alpha()andfaker.string.alphanumeric()must be one of'upper' | 'lower' | 'mixed'if provided
faker.phone.number style replaces explicit format 
faker.phone.number() generates a phone number for the current locale. However, previously there was little control over the generated number, which might or might not include country codes, extensions, white space and punctuation.
If you wanted more control over the number, it was previously necessary to pass an explicit format parameter. This has now been removed. Instead, you can consider one of two options:
- The new styleparameter has convenient options for common use cases. There are three possible values.- 'human': (default, existing behavior) A human-input phone number, e.g.- 555-770-7727or- 555.770.7727 x1234
- 'national': A phone number in a standardized national format, e.g.- (555) 123-4567.
- 'international': A phone number in a E.123 standard international format with country code, e.g.- +15551234567
 
The styles are locale-aware, so for example if you use pt_PT, phone numbers suitable for Portugal would be generated.
- If none of the styles match your needs, you can usefaker.string.numeric()orfaker.helpers.fromRegExp()to create a custom pattern.