If you don't speak Portuguese, check out the English version of this README here.
Caso queira uma consultoria particular, entre em contato comigo aqui.
O projeto Extenso.js foi criado com o objetivo de fornecer uma solução simples e eficiente para a conversão de números para texto em português.
A motivação por trás deste projeto é atender a uma necessidade comum em diversas aplicações financeiras, educativas e administrativas, onde é frequentemente necessário converter valores numéricos em palavras para fins de documentação, cheques, faturas e outros documentos formais.
Nossa ambição com o Extenso.js é tornar esta biblioteca uma referência para desenvolvedores que precisam dessa funcionalidade em suas aplicações, promovendo a padronização e simplificação do processo de conversão de números para texto.
- Suporte a números de até duodecilhões (10³⁹ ou 10⁷²).
- Suporte a números negativos e decimais.
- Suporte a múltiplas moedas (BRL, EUR, USD e mais).
- Localidades para todos os países lusófonos e Macau.
- Suporte a BigInt para números extremamente grandes.
- Suporte à escala curta e longa de números.
- Suporte à personalização de gênero gramatical.
- Suporte à formatação flexível (vírgula ou ponto como separador decimal).
- Suporte à escrita abreviada de números.
- Suporte à escrita de percentuais.
- Suporte à escrita de frações comuns.
- Suporte a unidades de medida personalizadas.
- Suporte à escrita sem acentos.
- Formatação do texto em minúsculas, maiúsculas ou título.
- API de metadados para moedas e limites de escala.
- Zero dependências.
NOTA: Observe que 10³⁹ é o limite para a escala curta enquanto que 10⁷² é o limite para a escala longa.
npm install extensoOu se preferir, com Yarn:
yarn add extensoESM:
import extenso from 'extenso'
extenso(123)
//=> 'cento e vinte e três'CommonJS:
const extenso = require('extenso')
extenso(123)
//=> 'cento e vinte e três'TypeScript:
import extenso, { type ExtensoOptions } from 'extenso'
const options: ExtensoOptions = { mode: 'number' }
const result: string = extenso(123, options)Também são exportados os tipos BuiltInCurrencyOptions, CurrencyDefinition,
CurrencyFormattingOptions, CurrencyOptions, CurrencyRounding,
CurrencyMetadata, MeasurementUnit, NumberOptions, ScaleLimit,
ExtensoMode, ExtensoLocale, ExtensoScale, ExtensoGender, CurrencyCode,
DecimalSeparator e TextCase.
O pacote requer Node.js 22.20 ou mais recente.
extenso(number[, options])O valor que deverá ser escrito por extenso (obrigatório).
Entradas number finitas, inclusive quando o JavaScript as representa em notação científica, são aceitas e normalizadas antes da conversão. O valor já precisa ser representável com a precisão desejada pelo tipo number: para inteiros maiores que Number.MAX_SAFE_INTEGER, use string ou bigint. bigint aceita somente inteiros.
Strings preservam todos os dígitos fornecidos. O sinal - só pode aparecer no início. Quando houver agrupamento, o primeiro grupo deve ter de um a três dígitos e os demais exatamente três. O separador decimal precisa ser seguido por dígitos; entradas incompletas como 1. são rejeitadas.
Opções de escrita (opcional).
mode[string]scale[string]locale[string]currency[object]removeAccents[boolean]textCase[string]currency.code[string]currency.rounding[string]currency.showZeroUnit[boolean]currency.showZeroSubunit[boolean]currency.fractionDigits[number]unit[object]number.gender[string]number.ordinal[boolean]decimalSeparator[string]
Define o modo de escrita do número.
Opções disponíveis:
number[default] - Escrever somente o número por extenso.currency- Escrever o número como valor monetário.digit- Escrever cada dígito individualmente por extenso.abbreviated- Escrever o número em formato abreviado.fraction- Escrever uma fração no formatonumerador/denominador.measurement- Escrever uma quantidade com unidade de medida.percentage- Escrever o número como percentual.
O modo abbreviated arredonda para uma casa decimal nos valores a partir de mil.
Quando o arredondamento ultrapassa o último sufixo disponível, ele é mantido:
o maior valor da escala curta ou longa é escrito como 1000 duodec.
Exemplos:
extenso('123')
//=> 'cento e vinte e três'
extenso('123', { mode: 'number' })
//=> '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('1500', { mode: 'abbreviated' })
//=> '1,5 mil'
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'
}
})
//=> 'dois inteiros e cinco décimos de quilograma'O modo fraction aceita numeradores inteiros e denominadores inteiros positivos.
A fração é escrita exatamente como informada, sem simplificação automática.
Denominadores de 2 a 10 usam seus nomes usuais; potências de dez usam formas
como centésimo e milésimo; os demais são escritos com avos.
Denominadores compostos flexionam todos os componentes no plural:
extenso('2/10000', { mode: 'fraction' }) retorna dois décimos milésimos.
Isso também vale para decimais na escala longa:
extenso('0.000000002', { scale: 'long' }) retorna dois milésimos milionésimos.
Define a unidade usada pelo modo
measurement.
Informe os nomes no singular e plural e o gênero gramatical (male ou
female). A unidade é obrigatória no modo measurement. Valores com parte
fracionária não nula usam de seguido da unidade no singular: 0.2 metro é
escrito como dois décimos de metro. A unidade informada é mantida, sem
conversão automática para centímetros ou outras unidades. Casas decimais
formadas somente por zeros mantêm a escrita inteira (1.00 resulta em
um metro). Múltiplos exatos de um milhão recebem a preposição de antes
da unidade no plural.
extenso('1000000', {
mode: 'measurement',
unit: {
singular: 'tonelada',
plural: 'toneladas',
gender: 'female'
}
})
//=> 'um milhão de toneladas'Define a escala de escrita (curta ou longa).
As escalas curta e longa são dois sistemas de escrita dos números. A escala curta é a utilizada no Brasil, enquanto a escala longa é utilizada no restante dos países de língua portuguesa.
A escrita diverge em números iguais ou superiores a um milhar de milhões (≥10⁹) e nos denominadores decimais correspondentes (≤10⁻⁹). As frações respeitam a escala selecionada.
Mais informações aqui [Wikipédia].
short[default] - Para escrever o número utilizando a escala curta.long- Para escrever o número utilizando a escala longa.
Exemplos:
extenso('2,000,000,001')
//=> 'dois bilhões e um'
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('1000000000', { scale: 'long', locale: 'pt' })
//=> 'mil milhões'
extenso('0.000000000001', { scale: 'short' })
//=> 'um trilionésimo'
extenso('0.000000000001', { scale: 'long' })
//=> 'um bilionésimo'Define o separador de inteiro e decimal.
Por padrão, o ponto é o separador decimal (point) e a vírgula é o separador de milhares. Use comma para inverter essa interpretação. A opção é especialmente importante para strings, pois entradas number são normalizadas diretamente da representação do JavaScript.
Observe que caso o separador decimal seja point (.) então o separador de milhar automaticamente será comma (,) e vice-versa.
point[default] - Para usar ponto como separador (ex.:3.14).comma- Para usar vírgula como separador (ex.:3,14).
Exemplos:
extenso('3.14')
//=> 'três inteiros e quatorze centésimos'
extenso('3,14', { decimalSeparator: 'comma' })
//=> 'três inteiros e quatorze centésimos'
extenso('3.14', { decimalSeparator: 'point' })
//=> 'três inteiros e quatorze centésimos'Define a localização (dialeto) para a escrita.
A escrita de alguns números pode variar de país para país (e talvez até de região para região); por exemplo, o número 16 é escrito dezesseis no Brasil, enquanto em Portugal é escrito dezasseis. A configuração dessas diferenças é feita aqui.
São reconhecidas as localidades ao, br, cv, gw, mo, mz, pt e
st. Exceto pelo Brasil, elas usam atualmente as formas numéricas não
brasileiras (dezasseis, dezassete, dezanove, bilião etc.). As diferenças
regionais mais específicas serão incorporadas conforme houver referências
linguísticas verificáveis.
br[default] - Para escrever no dialeto do Brasil.ao- Angola.cv- Cabo Verde.gw- Guiné-Bissau.mo- Macau.mz- Moçambique.pt- Portugal.st- São Tomé e Príncipe.
locale controla o vocabulário, enquanto scale controla a escala numérica.
Use scale: 'long' com as localidades não brasileiras quando quiser a escala
longa adotada nesses países e territórios.
A adaptação dos nomes de escala reconhece palavras completas da lista de
escalas. Nomes personalizados com terminações semelhantes, como grilhão e
grilhões, mantêm sua grafia em todas as localidades.
Exemplos:
extenso('16')
//=> 'dezesseis'
extenso('16', { locale: 'br' })
//=> 'dezesseis'
extenso('16', { locale: 'pt' })
//=> 'dezasseis'
extenso('1,000,000,000', { locale: 'br' })
//=> 'um bilhão'
extenso('1,000,000,000', { locale: 'pt' })
//=> 'um bilião'Remove os acentos e outros sinais diacríticos do texto retornado.
false[default] - Mantém a acentuação normal.true- Retorna o número por extenso sem acentos.
Esta opção funciona em todos os modos de escrita e pode ser combinada com qualquer localização.
Exemplos:
extenso('123')
//=> 'cento e vinte e três'
extenso('123', { removeAccents: true })
//=> 'cento e vinte e tres'
extenso('3.14', { removeAccents: true })
//=> 'tres inteiros e quatorze centesimos'Aplica capitalização ao texto final.
lower- Converte todo o texto para minúsculas.upper- Converte todo o texto para maiúsculas.title- Capitaliza as palavras principais e preserva conectivos comoe,deeporem minúsculas.
Quando a opção não é informada, a capitalização original é preservada.
extenso('123', { textCase: 'upper' })
//=> 'CENTO E VINTE E TRÊS'
extenso('123', { textCase: 'title' })
//=> 'Cento e Vinte e Três'Configura uma moeda incorporada ou uma definição de moeda personalizada.
Informar currency, com um código ou uma definição personalizada, ativa
automaticamente o modo currency, exceto quando outro mode é definido
explicitamente. Um objeto vazio (currency: {}) usa a moeda padrão BRL.
Define o código ISO da moeda em que o número deverá ser escrito.
São suportadas 9 moedas usadas em países e territórios lusófonos ou relevantes para suas relações econômicas. A seleção contempla membros da CPLP (Comunidade dos Países de Língua Portuguesa) e Macau, onde o português também é língua oficial.
As moedas suportadas são:
| Código | Moeda |
|---|---|
BRL [default] |
Real brasileiro |
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 |
Exemplos:
extenso('42', { mode: 'currency' })
//=> 'quarenta e dois reais'
extenso('42', { mode: 'currency', currency: { code: 'BRL' } })
//=> 'quarenta e dois reais'
extenso('42', { mode: 'currency', currency: { code: 'EUR' } })
//=> 'quarenta e dois euros'
extenso('42', { mode: 'currency', currency: { code: 'CVE' } })
//=> 'quarenta e dois escudos'
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'Para uma moeda personalizada, informe os nomes no singular e plural e o gênero
gramatical (male ou female) da unidade e da subunidade. code não pode ser
combinado com uma definição personalizada. A presença da definição ativa
automaticamente o modo currency.
Define como tratar casas decimais além da precisão da moeda.
reject[default] - Rejeita o valor sem modificá-lo.truncate- Descarta as casas excedentes.half-up- Arredonda para o valor mais próximo; empates são afastados de zero.
O cálculo é decimal exato e não converte o valor para ponto flutuante.
Se o valor monetário resultante for zero, o sinal negativo é omitido:
extenso('-0.004', { currency: { rounding: 'half-up' } }) retorna zero reais.
Escreve a unidade mesmo quando ela é zero. O padrão é
false.
Escreve a subunidade mesmo quando ela é zero. O padrão é
false.
Ativar as duas opções sempre inclui unidade e subunidade:
extenso('0', {
currency: {
code: 'BRL',
showZeroUnit: true,
showZeroSubunit: true
}
})
//=> 'zero reais e zero centavos'Define a quantidade de casas da subunidade de uma moeda personalizada.
Aceita inteiros de 0 a 1000 e usa 2 por padrão. Moedas incorporadas mantêm duas
casas decimais. Esta opção não pode ser combinada com currency.code.
Quando a quantidade de subunidades é um múltiplo exato de um milhão, usa-se
de, como na unidade principal. Por exemplo, 0.1 com fractionDigits: 7
e subunidade ficha/fichas é escrito como um milhão de fichas.
extenso('1.2345', {
currency: {
fractionDigits: 3,
rounding: 'half-up',
singular: 'crédito',
plural: 'créditos',
gender: 'male',
subunit: {
singular: 'ficha',
plural: 'fichas',
gender: 'female'
}
}
})
//=> 'um crédito e duzentas e trinta e cinco fichas'Define a flexão de gênero do número que será escrito.
O gênero feminino flexiona unidades, dezenas e centenas (uma, duas, duzentas, trezentas etc.), inclusive no grupo dos milhares. Os nomes de escala como milhão e bilhão permanecem masculinos.
male[default] - Para escrever no modo masculino.female- Para escrever no modo feminino.
Exemplos:
extenso('42')
//=> 'quarenta e dois'
extenso('42', { number: { gender: 'male' } })
//=> 'quarenta e dois'
extenso('42', { number: { gender: 'female' } })
//=> 'quarenta e duas'
extenso('322000', { number: { gender: 'female' } })
//=> 'trezentas e vinte e duas mil'Define se o número será escrito na forma ordinal.
Esta opção é válida no modo number e aceita somente valores inteiros. A opção
number.gender também flexiona todos os componentes do ordinal.
false[default] - Para escrever o número na forma cardinal.true- Para escrever o número na forma ordinal.
Exemplos:
extenso('1', { number: { ordinal: true } })
//=> 'primeiro'
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'No modo currency, moedas incorporadas aceitam zero, uma ou duas casas
decimais. Uma casa é completada com zero à direita: 1.1 representa uma
unidade e dez subunidades — em BRL, um real e dez centavos. Mais casas são
rejeitadas por padrão; currency.rounding permite truncamento ou arredondamento
explícito. 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 considerados 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
continua preservando todos os dígitos fornecidos.
O export padrão oferece funções de consulta que funcionam igualmente 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, ... }listCurrencies() e getCurrency() retornam cópias dos metadados, incluindo
nomes, gênero, subunidade, símbolos e quantidade de casas decimais.
getScaleLimit() retorna a maior potência nomeada, a quantidade máxima de
dígitos aceita e o maior valor exato representável como string. Códigos e
escalas inválidos geram TypeError.
mode, locale, scale, decimalSeparator, removeAccents, textCase,
number.gender, number.ordinal, currency.code, as opções de formatação
monetária e todos os campos de uma moeda personalizada são validados em runtime.
A biblioteca também 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
1000 caracteres.
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 aceitam no máximo duas casas decimais por
padrão; currency.rounding permite truncamento ou arredondamento explícito.
Revise os exemplos de uso e as regras de validação antes de atualizar.
O idioma padrão do Extenso.js é o Português Brasileiro. Esta escolha se deve a vários fatores:
- Origem do Projeto: O Extenso.js foi criado no Brasil, onde a necessidade de converter números para texto em português é bastante comum em diversas aplicações.
- População Falante: O Brasil possui a maior população de falantes de português no mundo, o que torna o Português Brasileiro a variante mais amplamente utilizada do idioma.
- Moeda Utilizada: Embora o Euro seja uma moeda importante globalmente, o Real (BRL) é a moeda mais utilizada pelos falantes de português, especialmente no Brasil.
- Separador Decimal: A opção
decimalSeparatorpermite escolher explicitamente ponto ou vírgula sem alterar o dialeto de saída.
Esses fatores contribuem para que o Português Brasileiro seja o idioma padrão do Extenso.js, garantindo que a biblioteca atenda às necessidades da maioria dos seus usuários.
Você é de Portugal, Angola, Moçambique ou de qualquer outro país onde se fala português? Percebeu alguma diferença na forma como os números são escritos no seu país? Caso tenha identificado variações, abra uma issue para discutirmos como adaptar essas características ao projeto e torná-lo mais completo.
Se encontrou algum erro ou algo que possa ser aprimorado, há diferentes formas de contribuir:
- Abrindo uma issue para relatar sugestões ou problemas.
- Enviando um pull request com melhorias.
- Comentando diretamente no trecho do código que pode ser aprimorado.
Toda contribuição é bem-vinda.
A biblioteca não tem dependências de runtime. Em 20 de outubro de 2026,
as atualizações compatíveis corrigiram os alertas de @humanfs/node e
brace-expansion e atualizaram js-yaml para 3.15.2 e AVA para 8.1.0.
Lint, TypeScript, os 147 testes com cobertura de 100% e os testes do pacote
instalado passaram após a atualização.
O npm audit ainda registra 9 alertas de desenvolvimento (5 altos e 4
moderados), derivados de duas dependências sem versão corrigida publicada:
braces— GHSA-vfj7-8cjw-p6xm, pela cadeia AVA →globby→fast-glob/micromatch→braces. Padrões com aninhamento excessivo podem esgotar a pilha. Use somente padrões de testes e filtros de linha de comando confiáveis.sprintf-js— GHSA-hp3w-g68c-fv3c, pela cadeia AVA →supertap→js-yaml→argparse→sprintf-js. Formatos com precisão excessiva podem lançar erros.argparseé usado pela CLI dejs-yaml; o relatório TAP do AVA usa a serializaçãosafeDump.
Esses riscos residuais foram aceitos para manter o AVA. Não afetam a árvore
de dependências de produção, cujo audit não registra vulnerabilidades.
Atualize esta avaliação quando houver correções upstream. Não force um
downgrade do AVA nem substitua js-yaml por uma versão incompatível:
supertap depende da API safeDump da versão 3.
Criado e mantido por Matheus Alves.
Licenciado sob a licença MIT © 2015-2026