Skip to content

Person names

randino generates names people carry, such as Emma Clover and Jack Reeves, in nine languages, each in its own script and with its English pronunciation alongside. They are for sample data: forms, seeds, mockups, fixtures.

javascript
import { randName } from 'randino';

randName({ language: 'en', count: 3 });
// ['Christina Mills', 'Jack Reeves', 'Brian Wallace']
dart
import 'package:randino/randino.dart';

randName(language: NameLanguage.en, count: 3);
// ['Christina Mills', 'Jack Reeves', 'Brian Wallace']
python
from randino import rand_name

rand_name(language="en", count=3)
# ['Christina Mills', 'Jack Reeves', 'Brian Wallace']

What is in the box

FunctionReturns
randNameThe names as strings, or a detail per name
nameLengthRangeThe natural length range of a full name in a language
nameSupportsMiddleNameWhether a language has a middle part at all
nameSupportsRomanWhether romanizing changes anything

How the options behave

Most of randName's options are the ones every generator takes. These are the ones whose behaviour is worth knowing before you reach for them.

realism — real names, or invented ones

At 'real', the default, every part is drawn from a curated pool of names in use, and stays there: when the length range leaves room for more than one given-name length, the length is chosen from the ones the pool can actually serve rather than rolled first and invented around.

At 'invented' the names are built instead. Latin and Cyrillic scripts come from syllable templates, and Korean, Japanese and Chinese from given-name characters combined freely. 'mixed' decides per name and per part, so one batch, and sometimes one name, holds both.

javascript
randName({ language: 'en', realism: 'invented', count: 3 });
// ['Deder Kuvoun', 'Jaihil Brouvinn', 'Thoowoun Wiatou']
dart
randName(language: NameLanguage.en, realism: RandRealism.invented, count: 3);
// ['Deder Kuvoun', 'Jaihil Brouvinn', 'Thoowoun Wiatou']
python
rand_name(language="en", realism="invented", count=3)
# ['Deder Kuvoun', 'Jaihil Brouvinn', 'Thoowoun Wiatou']

Surnames are weighted where the distribution is steep

Korean, Chinese and Vietnamese surnames are drawn in proportion to how common they are, because a handful of them cover most of the population. About a fifth of the Korean names come back a 김 and two Vietnamese names in five a Nguyễn, the way a real roster reads. An even draw over the pool would make 김 one name in seventy-five, and the output would stop reading as Korean.

The other six languages have a long enough tail that an even draw is already within the right order of magnitude, so they do not carry a frequency table.

Length is counted in the native form

minLengthminLengthmin_length and maxLengthmaxLengthmax_length count characters of the native form, spaces between parts included. The structure you asked for always wins: a range too narrow for the requested parts is answered with the closest name the generator can build, never by dropping a surname or middle name you asked for.

For space-separated languages the range is satisfied by re-drawing from the pools, and a range no draw landed inside is answered by drawing each part from the lengths that still can. So a maximum the pools can write a name inside is met; one they cannot reach at all is answered with a name short of the minimum rather than past the maximum. Korean, Japanese and Chinese hit the range exactly, because their given names are composed a syllable at a time.

Leave both out and each language falls back to its own range, which is what nameLengthRangenameLengthRangename_length_range reports. That fallback is resolved per language, so mixing languages does not stretch a Korean name to fill a Spanish name's range.

startsWith applies to the whole name

That means the surname for family-first languages, and the given name otherwise, or whenever the surname is switched off. A character that no real name starts with still returns names rather than nothing: Latin and Cyrillic scripts invent one (QQivu Railooth), and CJK scripts use the character as a name part of its own ( + 지수앙지수).

Only the first character of whatever you pass is used, and the match is case-insensitive.

unique is off by default

So that the count you asked for is the count you get. Turn it on to deduplicate; because the pools are finite, a large count then returns fewer names rather than looping forever.

Gender

gender picks which pools the given name is drawn from. In most languages that is all it does, and the result is not observable from the outside, since a Korean given name does not announce which pool it came from. Russian is the exception: its patronymic and its surname both inflect, so Иванов becomes Иванова and Николаевич becomes Николаевна.

Leave it out and a gender is picked per name. The detail output reports which one was used.

Released under the MIT License