name-capitalize
v2.3.0
Published
Lightweight, zero-dependency utility for smart capitalization of person names. Optimized for Latin scripts, handling compound surnames, particles (de, del, la), and Unicode characters.
Maintainers
Readme
name-capitalize
Lightweight, zero-dependency utility for smart capitalization of person names. Handles particles (de, van, von…), hyphenated names, apostrophes, and the messy Unicode that real-world input is full of.
Looking for the legacy version? See the
v1branch for Node 16 / Angular 12 compatibility (npm install name-capitalize@legacy).
Install
npm install name-capitalizeRequires Node 18 or higher.
Usage
import { capitalizeName } from 'name-capitalize';
capitalizeName('JUAN DE LA MAZA') // → 'Juan de la Maza'
capitalizeName('ludwig van beethoven') // → 'Ludwig van Beethoven'
capitalizeName("bernardo o'higgins") // → "Bernardo O'Higgins"
capitalizeName('JEAN-PIERRE DUPONT') // → 'Jean-Pierre Dupont'
capitalizeName('gabriel garcía márquez') // → 'Gabriel García Márquez'namecase is exported as an alias of capitalizeName — identical behavior, shorter name:
import { namecase } from 'name-capitalize';
namecase('JUAN DE LA MAZA') // → 'Juan de la Maza'Options
capitalizeName accepts an optional second argument. Omitting it keeps the default
behavior (and costs nothing — the built-in particle set is reused, not rebuilt).
capitalizeName(text, {
particles, // string[] | Set<string> — replace the built-in particle list entirely
extraParticles, // string[] | Set<string> — add particles on top of the defaults
ignoreParticles, // string[] | Set<string> — remove particles from the defaults
mcPrefix, // boolean — capitalize the letter after "Mc" (default false)
particlesAfterHyphen, // boolean — apply particle rules after a hyphen too (default false)
strict, // boolean — throw on non-string input (default false, will change)
})// Treat a default particle as a normal word (e.g. English "Van Dyke"):
capitalizeName('dick van dyke', { ignoreParticles: ['van'] }) // → 'Dick Van Dyke'
// Add domain-specific particles:
capitalizeName('joan sa costa', { extraParticles: ['sa'] }) // → 'Joan sa Costa'
// Opt into Mc handling:
capitalizeName('ronald mcdonald', { mcPrefix: true }) // → 'Ronald McDonald'
// Keep particles lowercase inside a hyphenated surname:
capitalizeName('jean-de-la-maza') // → 'Jean-De-La-Maza'
capitalizeName('jean-de-la-maza', { particlesAfterHyphen: true }) // → 'Jean-de-la-Maza'All three particle options are case-insensitive and accept either an array or a Set.
mcPrefix only handles Mc (via a rule); Mac is left untouched because it needs an
exception list (Macey, Mackay, Machado…) — see the limitations below.
Handling invalid input
capitalizeName is lenient: anything that is not a string becomes ''.
capitalizeName(null) // → ''
capitalizeName(42) // → ''That is convenient in a UI and dangerous in a data pipeline, where a null silently
becoming '' is lost data rather than a harmless no-op. Opt into throwing instead:
capitalizeName('juan de la maza', { strict: true }) // → 'Juan de la Maza'
capitalizeName('', { strict: true }) // → '' (a string, just an empty one)
capitalizeName(null, { strict: true }) // → throws TypeErrorDeprecation notice.
strictdefaults tofalsetoday and will default totruein a future release. Passing a statically-nullish value is flagged in your editor via a@deprecatedoverload. Set the option explicitly to lock in the behavior you want across the change.
Behavior
- Particles (
de,del,van,von,di,da,bin…) stay lowercase unless they are the first word. - Multi-word particles (
van der,de la,de los…) work because each of their words is treated as a particle (Otto van den Berg). - Words after a hyphen or apostrophe are capitalized (
Jean-Pierre,O'Higgins). - Leading/trailing whitespace is trimmed; interior spacing is preserved exactly.
Unicode
Separators are matched by Unicode class rather than by literal ASCII characters, so the text people actually paste works:
| Input contains | Example | Result |
| --- | --- | --- |
| Typographic apostrophe ’ (iOS/macOS/Word autocorrect) | o’higgins | O’Higgins |
| Non-breaking space (pasted from Word/Excel/PDF) | maría josé | María José |
| En/em dash, non-breaking hyphen | mary–jane | Mary–Jane |
| Tabs and newlines | juan\tperez | Juan\tPerez |
| Leading punctuation | (juan) perez | (Juan) Perez |
Capitalization uses Unicode titlecase, not toUpperCase(), which can turn one
character into several:
| Input | toUpperCase() would give | name-capitalize gives |
| --- | --- | --- |
| florian | FLorian | Florian |
| ßern | SSern | Ssern |
| dzeljko | DZeljko | Dzeljko |
Accents, ñ, ü, Cyrillic, Greek and astral-plane letters are handled natively.
Known limitation: intra-word capitals
The input is lowercased before re-capitalizing, so casing inside a word is not preserved. Names that carry a capital after the first letter come out normalized:
capitalizeName('RONALD MCDONALD') // → 'Ronald Mcdonald' (not 'McDonald')
capitalizeName('DeShawn') // → 'Deshawn'Only the first letter of each name segment is capitalized. Mc can be enabled with
{ mcPrefix: true }, but Mac prefixes and camel-cased names (DeShawn, LaToya)
are out of scope by design — distinguishing MacArthur from Machado needs an
exception dictionary, which would trade the library's small footprint for coverage.
Changelog
See CHANGELOG.md.
Contributing
Release process (including the manual npm approval step): RELEASING.md.
License
MIT © Gabriel Galilea
