Extenso.js
Números por extenso em português para JavaScript.
npm install extensoConverte números, valores monetários, percentuais, frações e medidas em texto. Cobre localidades lusófonas e Macau, aceita BigInt, escalas curta e longa e moedas personalizadas — sem dependências.
Por que este projeto existe?
Escrever valores em palavras é uma necessidade recorrente em sistemas financeiros, educativos e administrativos — especialmente em cheques, faturas, contratos e outros documentos formais.
O Extenso.js reúne essas regras em uma API pequena e previsível, para evitar que cada aplicação implemente sua própria versão da conversão e para manter o resultado consistente entre diferentes contextos de uso.
Nesta página
Apoie a manutenção
O projeto não gera receita direta. Uma contribuição ajuda a financiar manutenção, testes e evolução da biblioteca.
Funcionalidades
- Números de até duodecilhões (10³⁹ na escala curta ou 10⁷² na escala longa).
- Números negativos e decimais.
- Múltiplas moedas, incluindo BRL, EUR e USD.
- Localidades de países lusófonos e Macau.
- BigInt para números extremamente grandes.
- Escalas curta e longa.
- Personalização de gênero gramatical.
- Ponto ou vírgula como separador decimal.
- Percentuais, frações comuns e unidades de medida.
- Escrita abreviada, capitalização e saída sem acentos.
- API de metadados para moedas e limites de escala.
- Zero dependências.
Instalação
Instale o pacote pelo npm. As definições de tipo para TypeScript já fazem parte da distribuição.
npm install extensoa Para Yarn, utilize yarn add extenso.
Uso
A função padrão recebe o valor a ser convertido e, opcionalmente, um objeto de configuração.
import extenso from 'extenso'
extenso(123)
//=> 'cento e vinte e três'3.1. CommonJS
const extenso = require('extenso')
extenso(123)
//=> 'cento e vinte e três'extenso('16', { locale: 'pt' })
//=> 'dezasseis'
extenso('1500000', { mode: 'abbreviated' })
//=> '1,5 mi'Sintaxe e entradas
extenso(number[, options]) → string4.1. number
Aceita valores dos tipos string, number ou bigint. Entradas number finitas, inclusive em notação científica, são aceitas e normalizadas. Para inteiros maiores que Number.MAX_SAFE_INTEGER, use string ou BigInt a fim de preservar a precisão. BigInt aceita somente inteiros.
Strings preservam todos os dígitos fornecidos. O sinal negativo só pode aparecer no início; agrupamentos devem ter um primeiro grupo de um a três dígitos e os demais com exatamente três. O separador decimal precisa ser seguido por dígitos.
4.2. options
Objeto opcional que controla idioma, escala, formato numérico e moeda. Na ausência desse argumento, a saída segue o português do Brasil e a escala curta.
Opções
A tabela abaixo resume as configurações principais. As subseções seguintes documentam o comportamento de cada opção.
| Opção | Tipo | Padrão | Descrição |
|---|---|---|---|
mode | number | currency | digit | abbreviated | fraction | measurement | percentage | 'number' | Formato do texto retornado. |
locale | ao | br | cv | gw | mo | mz | pt | st | 'br' | Localidade usada no vocabulário. |
scale | 'short' | 'long' | 'short' | Escala curta ou longa. |
decimalSeparator | 'point' | 'comma' | 'point' | Separador decimal da entrada. |
removeAccents | boolean | false | Remove sinais diacríticos. |
textCase | 'lower' | 'upper' | 'title' | — | Capitalização do resultado. |
currency | CurrencyOptions | BRL | Moeda incorporada ou personalizada. |
unit | MeasurementUnit | — | Unidade usada no modo measurement. |
5.1. options.mode
Define o modo de escrita: number, currency, digit, abbreviated, percentage, fraction ou measurement.
extenso('123')
//=> 'cento e vinte e três'
extenso('123', { mode: 'currency' })
//=> 'cento e vinte e três reais'
extenso('123', { mode: 'digit' })
//=> 'um dois três'
extenso('1500000', { mode: 'abbreviated' })
//=> '1,5 mi'extenso('12.5', { mode: 'percentage' })
//=> 'doze inteiros e cinco décimos por cento'
extenso('3/4', { mode: 'fraction' })
//=> 'três quartos'
extenso('2.5', {
mode: 'measurement',
unit: { singular: 'quilograma', plural: 'quilogramas', gender: 'male' }
})5.2. options.scale
A escala curta (short) é usada no Brasil e é o padrão. A escala longa (long) é usada no restante dos países de língua portuguesa. A escrita diverge em valores iguais ou superiores a 10⁹ e nos denominadores decimais correspondentes.
extenso('2,000,000,001', { scale: 'short' })
//=> 'dois bilhões e um'
extenso('2,000,000,001', { scale: 'long' })
//=> 'dois mil milhões e um'
extenso('0.000000000001', { scale: 'long' })
//=> 'um bilionésimo'5.3. options.decimalSeparator
O ponto é o separador decimal padrão (point) e a vírgula separa milhares. Use comma para inverter a interpretação. Essa opção é especialmente importante para entradas fornecidas como string.
extenso('3.14')
//=> 'três inteiros e quatorze centésimos'
extenso('3,14', { decimalSeparator: 'comma' })
//=> 'três inteiros e quatorze centésimos'5.4. options.locale
Define o vocabulário da localidade. São aceitos ao, br, cv, gw, mo, mz, pt e st. O Brasil é o padrão; as demais usam atualmente as formas numéricas não brasileiras. locale controla o vocabulário, enquanto scale controla a escala numérica.
extenso('16', { locale: 'br' })
//=> 'dezesseis'
extenso('16', { locale: 'pt' })
//=> 'dezasseis'
extenso('1,000,000,000', { locale: 'pt' })
//=> 'um bilião'5.5. options.removeAccents
Quando true, remove acentos e outros sinais diacríticos do resultado. Pode ser combinada com qualquer modo ou localização.
extenso('123', { removeAccents: true })
//=> 'cento e vinte e tres'
extenso('3.14', { removeAccents: true })
//=> 'tres inteiros e quatorze centesimos'5.6. options.textCase
Controla a capitalização final: lower usa minúsculas, upper usa maiúsculas e title capitaliza as palavras principais, preservando conectivos como “e”, “de” e “por”. Sem essa opção, a capitalização original é mantida.
extenso('123', { textCase: 'upper' })
//=> 'CENTO E VINTE E TRÊS'
extenso('123', { textCase: 'title' })
//=> 'Cento e Vinte e Três'5.7. options.currency
Configura uma moeda incorporada ou personalizada. Informar currency ativa automaticamente o modo monetário, exceto quando outro modo é definido explicitamente. Um objeto vazio usa BRL.
| Código | Moeda | Observação |
|---|---|---|
BRL | Real brasileiro | padrão |
AOA | Kwanza angolano | — |
CVE | Escudo cabo-verdiano | — |
XOF | Franco CFA de África Ocidental | — |
MZN | Metical moçambicano | — |
EUR | Euro | — |
STN | Dobra de São Tomé e Príncipe | — |
USD | Dólar americano | — |
MOP | Pataca de Macau | — |
extenso('42', { currency: { code: 'EUR' } })
//=> 'quarenta e dois euros'
extenso('2.01', {
currency: {
singular: 'crédito', plural: 'créditos', gender: 'male',
subunit: { singular: 'ficha', plural: 'fichas', gender: 'female' }
}
})
//=> 'dois créditos e uma ficha'Em uma moeda personalizada, informe os nomes singular e plural e o gênero (male ou female) da unidade e da subunidade. code não pode ser combinado com uma definição personalizada.
5.8. Formatação monetária
currency.rounding define o tratamento das casas excedentes: reject (padrão), truncate ou half-up. showZeroUnit e showZeroSubunit permitem exibir unidades zeradas. Em moedas personalizadas, fractionDigits aceita de 0 a 1.000 casas e usa 2 por padrão.
5.9. options.number.gender
O gênero feminino flexiona unidades, dezenas e centenas, inclusive no grupo dos milhares. Nomes de escala como milhão e bilhão permanecem masculinos.
extenso('42', { number: { gender: 'female' } })
//=> 'quarenta e duas'
extenso('322000', { number: { gender: 'female' } })
//=> 'trezentas e vinte e duas mil'5.10. options.number.ordinal
Escreve números inteiros na forma ordinal. A opção de gênero também flexiona todos os componentes do ordinal.
extenso('11', { number: { ordinal: true } })
//=> 'décimo primeiro'
extenso('42', { number: { ordinal: true, gender: 'female' } })
//=> 'quadragésima segunda'
extenso('1000', { number: { ordinal: true } })
//=> 'milésimo'TypeScript
O pacote exporta a interface ExtensoOptions e os tipos BuiltInCurrencyOptions, CurrencyDefinition, CurrencyFormattingOptions, CurrencyOptions, CurrencyRounding, CurrencyMetadata, MeasurementUnit, NumberOptions, ScaleLimit, ExtensoMode, ExtensoLocale, ExtensoScale, ExtensoGender, CurrencyCode, DecimalSeparator e TextCase.
import extenso, { type ExtensoOptions } from 'extenso'
const options: ExtensoOptions = { mode: 'number' }
const result: string = extenso(123, options)Valores monetários
No modo currency, moedas incorporadas aceitam zero, uma ou duas casas decimais. Uma casa é completada com zero à direita: 1.1 representa um real e dez centavos em BRL. Mais casas são rejeitadas por padrão; currency.rounding permite truncamento ou arredondamento decimal exato. Moedas personalizadas podem alterar a precisão com currency.fractionDigits.
A subunidade da dobra de São Tomé e Príncipe (STN) é o cêntimo.
extenso('0.01', { currency: { code: 'STN' } })
//=> 'um cêntimo'Códigos e símbolos podem aparecer antes ou depois do valor. Marcadores de moedas diferentes na mesma entrada são ambíguos e geram erro. currency.code tem prioridade sobre uma única moeda detectada.
No modo number, casas decimais formadas somente por zeros não criam uma fração: 1.00 equivale a 1 e -0.00 equivale a 0. O modo digit preserva todos os dígitos fornecidos.
Metadados
A função exportada também oferece consultas sobre as moedas incorporadas e os limites das escalas. Elas funcionam da mesma forma em ESM, CommonJS e UMD.
extenso.listCurrencies()
//=> metadados das 9 moedas incorporadas
extenso.getCurrency('BRL')
//=> { code: 'BRL', singular: 'real', plural: 'reais', ... }
extenso.getScaleLimit('long')
//=> { scale: 'long', largestNamedExponent: 72, maximumDigits: 75, ... }Os resultados são cópias dos metadados. Códigos de moeda e escalas inválidos geram TypeError.
Validação e migração
Validação e erros
mode, locale, scale, decimalSeparator, removeAccents, textCase, opções numéricas, formatação monetária e todos os campos de moedas e unidades personalizadas são validados em runtime.
A biblioteca rejeita opções number e currency com tipos inválidos, entrada vazia, sinal isolado, agrupamento inválido, decimal incompleto, ordinais decimais, NaN, infinitos, moedas conflitantes, valores acima da escala escolhida e strings com mais de 1.000 caracteres.
Migração da versão 2.x
A versão 3 contém mudanças incompatíveis. CommonJS passa a retornar a função diretamente (const extenso = require('extenso')), o pacote requer Node.js 22.20 ou mais recente e entradas e opções inválidas deixam de usar comportamentos permissivos.
Moedas incorporadas mantêm duas casas decimais e rejeitam casas excedentes por padrão. Para aceitar esses valores, escolha explicitamente truncate ou half-up em currency.rounding.
Idioma padrão
O idioma padrão do Extenso.js é o português brasileiro. A escolha considera os seguintes fatores:
- Origem do projeto. O Extenso.js foi criado no Brasil, onde a conversão de números para texto é comum em diversas aplicações.
- População falante. O Brasil possui a maior população de falantes de português.
- Moeda utilizada. O real é a moeda mais utilizada entre falantes de português.
- Separador decimal. A opção
decimalSeparatorpermite escolher ponto ou vírgula sem alterar o dialeto de saída.
Esses fatores fazem com que a configuração padrão atenda à maioria dos usuários. As localidades ao, cv, gw, mo, mz, pt e st permanecem disponíveis por opção.
Contribuições e licença
Você é de Portugal, Angola, Moçambique ou de outro país onde se fala português? Se identificou diferenças na escrita dos números, abra uma issue para discutirmos como adaptar a biblioteca.
Também é possível contribuir relatando sugestões ou problemas, enviando um pull request ou comentando diretamente no trecho de código que pode ser aprimorado. Toda contribuição é bem-vinda.
Mantido por Matheus Alves e distribuído sob a licença MIT.