Cómo construir un contador de palabras con estadísticas en JavaScript
Contar palabras parece trivial hasta que aparecen los casos límite: espacios múltiples, saltos de línea, párrafos vacíos. Aquí está la implementación mínima que los maneja todos.

Contar palabras en JavaScript parece una tarea de una línea. Y casi lo es —pero los detalles marcan la diferencia entre un contador que falla con espacios dobles o tabulaciones y uno que funciona con cualquier texto real.
Contar palabras con una expresión regular
La forma robusta es buscar secuencias de caracteres no-espacio, no dividir por espacios:
function contarPalabras(texto) {
var m = texto.match(/\S+/g);
return m ? m.length : 0;
}
\S+ captura cualquier secuencia de caracteres que no sean espacio en blanco —incluyendo tabulaciones, saltos de línea y espacios múltiples entre palabras quedan automáticamente excluidos. Si el texto está vacío, match() devuelve null, de ahí el operador ternario.
Caracteres con y sin espacios
var conEspacios = texto.length;
var sinEspacios = texto.replace(/\s/g, '').length;
\s incluye espacios, tabulaciones, saltos de línea y retornos de carro. String.length en JavaScript devuelve el número de unidades de código UTF-16, no de puntos de código Unicode —los emoji y algunos caracteres CJK cuentan como 2. Para un contador de texto normal es comportamiento aceptable; para procesamiento lingüístico preciso habría que usar el operador spread ([...texto].length).
Contar párrafos
La definición más útil de párrafo para un escritor es: bloque de texto separado de otros por una o más líneas en blanco. Un simple split no funciona porque genera entradas vacías cuando hay múltiples saltos:
function contarParrafos(texto) {
var lineas = texto.split(/\n/);
var parrafos = 0;
var enParrafo = false;
for (var i = 0; i < lineas.length; i++) {
if (lineas[i].trim().length > 0) {
if (!enParrafo) { parrafos++; enParrafo = true; }
} else {
enParrafo = false;
}
}
return parrafos;
}
La máquina de estados es la solución más clara: entramos en un párrafo al encontrar la primera línea no vacía y salimos al encontrar una línea vacía. Tres líneas en blanco consecutivas siguen contando como un único separador.
Tiempo de lectura
La velocidad media de lectura en español está entre 180 y 220 palabras por minuto para texto informativo. Con 200 wpm:
function tiempoLectura(palabras) {
if (palabras === 0) return '—';
var minutos = palabras / 200;
if (minutos < 0.5) return '< 1 min';
return Math.round(minutos) + ' min';
}
El umbral de < 0.5 evita mostrar «0 min» para textos muy cortos. Los estudios de Nielsen Norman Group sobre lectura en pantalla sugieren valores algo menores —alrededor de 200–250 wpm para texto digital—, pero la diferencia práctica entre 200 y 250 wpm en la estimación final es de menos de un minuto por cada mil palabras.
Actualizar en tiempo real
El evento input dispara en cada pulsación de tecla, pegado de texto y cualquier cambio en el valor del campo:
textarea.addEventListener('input', function () {
var texto = textarea.value;
mostrarPalabras(contarPalabras(texto));
mostrarChars(texto.length);
mostrarCharsNs(texto.replace(/\s/g, '').length);
mostrarParrafos(contarParrafos(texto));
mostrarLectura(tiempoLectura(contarPalabras(texto)));
});
No hace falta debounce: las operaciones son O(n) sobre el texto y en cualquier texto de tamaño razonable —incluso un libro completo— terminan en menos de un milisegundo.
A continuación puedes probar la herramienta completa.
Contador de palabras
Pega o escribe tu texto. Las estadísticas se actualizan al instante.


