👉 ¿Hablamos de Frontend? Mira mis clases personalizadas en Perú 🧑‍💻
¡Link copiado!

Búsqueda difusa en cliente con Fuse.js

UX | | 5 min de lectura | 24 min de tutorial

¿Alguna vez escribiste mal una palabra al buscar en una web y no obtuviste ningún resultado? La búsqueda exacta es despiadada si el texto no coincide por algún carácter, simplemente no aparece.

Pero no tiene por qué ser así. Aquí es donde entra Fuse.js, una librería de JavaScript que permite realizar búsquedas difusas (fuzzy search) en el navegador, sin necesidad de un servidor.

❓¿Qué es la búsqueda difusa?

Es una forma de buscar que tolera errores de escritura, diferencias de formato o coincidencias parciales. Por ejemplo, si un usuario escribe krug y tú tienes Krüg Grande Cuvée, Fuse.js lo encuentra.

🤔 ¿Por qué usar Fuse.js?

  • Corre completamente en el navegador.
  • No necesitas un servicio externo como Algolia.
  • Se puede personalizar la búsqueda ajustando sensibilidad, campos a buscar, y más.
  • Súper rápido, incluso con cientos o miles de elementos.
  • Tiene documentación disponible en: fusejs.io

🤔 ¿Cuando usar Fuse.js?

Usa Fuse.js cuando tienes control total sobre el conjunto de datos y necesitas ofrecer una búsqueda rápida, flexible y tolerante a errores… sin depender de un backend.

¿La clave? Que los datos estén en el cliente, ya sea porque el volumen es pequeño o porque puedes cachearlos eficientemente.

Esto permite que las búsquedas se hagan sobre el total de datos en memoria, sin llamadas a servidores, sin latencias, y con una experiencia instantánea para el usuario.

❌ No lo uses si:

  • El volumen de datos es muy grande y no lo puedes manejar todo en el cliente.
  • No puedes controlar cómo o cuándo se cargan o actualizan los datos.
  • Necesitas paginación o consultas parciales dinámicas.

🤖 Ejemplo simple de Fuse.js

Vamos a explicar en pasos simples como utilizar la dependencia.

   // 1. Importamos la librería Fuse.js
import Fuse from 'fuse.js'

// 2. Definimos una lista de objetos (vinos)
const wines = [
	{ name: 'Krüg Grande Cuvée' },
	{ name: 'Moët & Chandon Brut' },
	{ name: 'Dom Pérignon 2012' }
]

/* 3. Creamos una instancia de Fuse. Le pasamos la data y
especificamos que queremos buscar por la key 'name' */
const fuse = new Fuse(wines, {
	keys: ['name']
	// threshold: 0.4 // sensibilidad, 0 = exacto y 1 = no estricto
})

// 4. Realizamos una búsqueda con la palabra 'kru'
const result = fuse.search('kru')

// 5. Mostramos el resultado en consola
console.log(result)
/*
  Resultado esperado:
  [
    {
      "item":{"name":"Krüg Grande Cuvée"}, // el objeto encontrado
      "refIndex":0 // posición del ítem original en el array
    }
  ]
*/

🙌 Código del ejemplo interactivo

   <!doctype html>
<html lang="es">
	<head>
		<meta charset="UTF-8" />
		<title>Buscador de vinos con Fuse.js</title>
		<script src="https://cdn.jsdelivr.net/npm/fuse.js@6.6.2"></script>
		<style>
			body {
				font-family: sans-serif;
				padding: 20px;
			}
			input {
				padding: 8px;
				width: 300px;
				font-size: 16px;
				margin-bottom: 8px;
			}
			ul {
				margin-top: 10px;
				padding-left: 0;
			}
			li {
				list-style: none;
				margin-bottom: 5px;
			}
		</style>
	</head>
	<body>
		<h2>Buscar vino</h2>
		<input type="text" id="searchInput" placeholder="Escribe para buscar..." />
		<ul id="results"></ul>

		<script>
			const wines = [
				{ name: 'Krüg Grande Cuvée' },
				{ name: 'Moët & Chandon Brut' },
				{ name: 'Dom Pérignon 2012' },
				{ name: 'Ruinart Rosé' },
				{ name: 'Veuve Clicquot Brut' },
				{ name: 'Baron B Extra Brut' }
			]

			const fuse = new Fuse(wines, {
				keys: ['name'],
				threshold: 0.4
			})

			const input = document.getElementById('searchInput')
			const resultsList = document.getElementById('results')

			function renderResults(data) {
				resultsList.innerHTML = ''
				data.forEach((item) => {
					const name = item.name || item.item?.name
					const li = document.createElement('li')
					li.textContent = name
					resultsList.appendChild(li)
				})
			}

			renderResults(wines)

			input.addEventListener('input', () => {
				const query = input.value.trim()
				const results = query ? fuse.search(query) : wines
				renderResults(results)
			})
		</script>
	</body>
</html>

Array wines con más propiedades

   const wines = [
	{
		name: 'Krüg Grande Cuvée',
		category: 'Champagne',
		year: 2015,
		cellars: ['Bodega Krug', 'Francia', 'Metodo tradicional']
	},
	{
		name: 'Moët & Chandon Brut',
		category: 'Champagne',
		year: 2018,
		cellars: ['Bodega Moët & Chandon', 'Francia', 'Brut']
	},
	{
		name: 'Dom Pérignon 2012',
		category: 'Champagne',
		year: 2012,
		cellars: ['Bodega Dom Pérignon', 'Francia', 'Vintage']
	},
	{
		name: 'Ruinart Rosé',
		category: 'Rosé',
		year: 2020,
		cellars: ['Bodega Ruinart', 'Francia', 'Rosé']
	},
	{
		name: 'Veuve Clicquot Brut',
		category: 'Champagne',
		year: 2016,
		cellars: ['Bodega Veuve Clicquot', 'Francia', 'Brut']
	},
	{
		name: 'Baron B Extra Brut',
		category: 'Sparkling',
		year: 2019,
		others: [
			{
				label: 'cellar',
				value: 'La bodega'
			},
			{
				label: 'year',
				value: '2019'
			}
		]
	}
]

Mostrar más información en el listado

   const renderResults = (results) => {
	resultsList.innerHTML = ''
	results.forEach((item) => {
		const li = document.createElement('li')
		li.textContent = `${item.name} - ${item.category} - Año: ${item.year}` // AJUSTAMOS
		resultsList.appendChild(li)
	})
}

Buscar sobre un valor numérico

   const fuse = new Fuse(wines, {
	keys: [
		{
			name: 'year',
			getFn: (obj) => obj.year.toString()
		}
	],
	threshold: 0.3
})

Buscar sobre un sub array de string

   const fuse = new Fuse(wines, {
	keys: ['cellars'],
	threshold: 0.3
})

Buscar sobre un sub array de objetos

   const fuse = new Fuse(wines, {
	keys: [
		{
			name: 'cellar',
			getFn: (obj) => {
				return obj?.others?.find((o) => o.label === 'year')?.value
			}
		}
	],
	threshold: 0.3
})

✅ Conclusión

Implementar búsqueda difusa en el cliente con Fuse.js es una forma rápida y efectiva de mejorar la experiencia del usuario si tienes el control del conjunto total de datos en clientes.

Permite encontrar resultados relevantes incluso con errores de escritura o coincidencias parciales.

Es ligera, configurable y perfecta para aplicaciones modernas que buscan ofrecer búsquedas más humanas y tolerantes.

¡Gracias por leer!

Si te ha gustado este artículo, ¡compártelo con tus amigos y seguidores! Tu apoyo me motiva a llegar a más personas y a seguir creando contenido increíble para ti.