Volver al blog
BunAPIsProyecto Personal

Wikipedia local con Bun: lo que hay a 30 minutos de ti

24 de octubre de 2026·7 min de lectura·Diego Horvatti

Llevas años viviendo en el mismo barrio y seguramente no sabes la mitad de lo que hay en Wikipedia sobre él. Ed Jefferson lo resolvió con un proyecto pequeño y muy bien pensado: Local Wikipedia, una Wikipedia local que muestra solo artículos sobre cosas a media hora a pie de donde estás. Nada de guerras mundiales, nada de celebridades. Solo la plaza, la iglesia vieja, la estación abandonada y esa fábrica que acabó convertida en edificio de viviendas.

La idea es tan simple que dan ganas de hacer tu propia versión el fin de semana. Así que vamos a hacerla, con Bun.

Qué es la Wikipedia local de Ed Jefferson

El sitio toma tu ubicación y lista los artículos de Wikipedia que tienen coordenadas geográficas cerca de ti. El recorte es humano: lo que puedes alcanzar caminando unos 30 minutos. A 5 km/h, eso da algo en torno a 2,5 km.

Parece una tontería. No lo es. Wikipedia tiene cientos de miles de artículos con coordenadas, y la mayoría nunca te aparece porque nadie busca "el puente de hierro de la calle de atrás". El proyecto invierte la lógica: en lugar de ir tú detrás del contenido, el contenido llega desde el lugar donde ya estás.

Lo probé mentalmente con mi barrio y ya sé lo que va a pasar. Va a aparecer un artículo de tres líneas sobre una gasolinera que cerró en 1987. Y lo voy a leer entero.

Los mejores proyectos personales resuelven una curiosidad, no un mercado.

Cómo funciona por dentro: la API de geosearch

La parte técnica es casi toda de Wikimedia. La API de MediaWiki tiene un módulo llamado geosearch que recibe una coordenada y un radio y devuelve los artículos marcados en esa zona. Sin clave, sin registro.

Los parámetros que importan:

  • gscoord: latitud y longitud separadas por |.
  • gsradius: radio en metros, hasta 10.000.
  • gslimit: cuántos resultados, hasta 500.

Una llamada para el centro de São Paulo queda así:

https://es.wikipedia.org/w/api.php?action=query&list=geosearch&gscoord=-23.5505|-46.6333&gsradius=2500&gslimit=50&format=json

La respuesta trae título, pageid, coordenadas y la distancia en metros hasta el punto. O sea: el backend de una Wikipedia local ya existe. Solo necesitas una capa fina por encima.

Un detalle que mucha gente ignora: Wikimedia pide que todo cliente envíe un User-Agent identificable, con un contacto. Si lo olvidas, te pueden bloquear. Es educación básica con una API gratuita que sostiene a medio mundo.

Montando tu versión con Bun

Aquí Bun brilla, porque el proyecto entero cabe en un archivo, sin ninguna dependencia. fetch nativo, servidor HTTP nativo, TypeScript ejecutándose directamente.

const cache = new Map<string, { at: number; data: unknown }>()
const TTL = 1000 * 60 * 60 // 1 hora

async function nearby(lat: number, lon: number) {
  // ponytail: redondea a ~1 km, protege la privacidad y mejora la caché
  const key = `${lat.toFixed(2)}|${lon.toFixed(2)}`
  const hit = cache.get(key)
  if (hit && Date.now() - hit.at < TTL) return hit.data

  const url = new URL('https://es.wikipedia.org/w/api.php')
  url.search = new URLSearchParams({
    action: 'query',
    list: 'geosearch',
    gscoord: key,
    gsradius: '2500',
    gslimit: '100',
    format: 'json',
  }).toString()

  const res = await fetch(url, {
    headers: { 'User-Agent': 'wiki-local/1.0 (contacto@tudominio.com)' },
  })
  const data = (await res.json()).query.geosearch
  cache.set(key, { at: Date.now(), data })
  return data
}

Bun.serve({
  port: 3000,
  routes: {
    '/api/cerca': async (req) => {
      const { searchParams } = new URL(req.url)
      const lat = Number(searchParams.get('lat'))
      const lon = Number(searchParams.get('lon'))
      if (!Number.isFinite(lat) || !Number.isFinite(lon)) {
        return new Response('lat/lon inválidos', { status: 400 })
      }
      return Response.json(await nearby(lat, lon))
    },
  },
})

Se ejecuta con bun run server.ts y listo. En el front, un navigator.geolocation.getCurrentPosition llama a ese endpoint y tú renderizas una lista. Se puede hacer en HTML puro, sin framework.

¿Por qué tener un backend, si la API de Wikipedia acepta llamadas directas desde el navegador? Tres motivos prácticos:

  • Caché: diez personas en el mismo barrio se convierten en una sola llamada a Wikimedia.
  • User-Agent: el navegador no te deja controlar bien esa cabecera.
  • Privacidad: el servidor solo ve la coordenada redondeada, y Wikimedia ni eso.

El Map en memoria tiene un límite obvio: si reinicias el proceso, pierdes la caché, y además crece sin techo. Para un proyecto personal, no pasa nada. Si se vuelve algo serio, cámbialo por Redis o por una tabla en PostgreSQL con índice en las coordenadas redondeadas.

Por qué importa la privacidad de la ubicación

Este es el punto que separa un proyecto chulo de un proyecto responsable. La ubicación exacta es un dato sensible. Con cuatro decimales identificas la casa de alguien. Con dos, identificas un barrio.

Para una Wikipedia local, dos decimales bastan. Un error de unos 1,1 km en un radio de 2,5 km casi no cambia el resultado. Pero cambia bastante lo que se filtra en tu log de accesos.

Si vas a publicar algo así, también conviene:

  • No registrar lat y lon en bruto.
  • Pedir la ubicación solo cuando la persona pulse un botón, nunca al cargar la página.
  • Ofrecer un campo de búsqueda por dirección para quien no quiera compartir el GPS.

Es el tipo de cuidado que cuesta cinco minutos y te evita un dolor de cabeza enorme con el RGPD después.

Línea recta no es caminar

Aquí está la trampa. El gsradius mide la distancia en línea recta. Pero nadie camina en línea recta. Hay ríos, hay viaductos, hay avenidas sin paso de peatones.

En la práctica, un punto a 2 km en línea recta puede estar a 40 minutos a pie. Si quieres ser fiel a la promesa de "media hora andando", tienes dos caminos:

  1. Aproximación honesta: usa un radio menor, por ejemplo 2 km, y acepta la imprecisión.
  2. Ruta de verdad: pasa los resultados por un servicio de rutas como OSRM o Valhalla, con el perfil de peatón, y filtra por el tiempo real.

La segunda opción es mucho más cara. Cien artículos se convierten en cien cálculos de ruta, o en una llamada de matriz si el servicio lo permite. Para un proyecto de curiosidad, yo me quedaría con la primera. La gracia está en descubrir, no en cronometrar.

Si quieres ordenar por distancia por tu cuenta, la fórmula de haversine lo resuelve en pocas líneas, pero fíjate en que la propia API ya devuelve el campo dist. No reescribas lo que ya viene hecho.

Lo que este proyecto enseña a quien escribe código

Me gusta Local Wikipedia por un motivo que tiene poco que ver con la geografía. Es un recordatorio de que un buen producto puede ser un recorte, no una plataforma.

Ed no construyó una enciclopedia. Tomó una API pública, aplicó un filtro con significado humano y lo publicó. Sin cuenta, sin onboarding, sin notificaciones pidiéndote que vuelvas.

Los desarrolladores tenemos la manía de empezar un proyecto personal por el docker-compose.yml. Monorepo, autenticación, colas, panel de administración. Tres semanas después, ni una línea resuelve el problema que motivó la idea. Este proyecto es lo contrario, y Bun encaja bien con esa mentalidad: un archivo, cero npm install, arranca en milisegundos.

También hay una lección sobre datos abiertos. Wikipedia guarda coordenadas desde hace años, editadas por voluntarios, y casi nadie las usa de forma creativa. Hay muchos proyectos esperando a hacerse sobre APIs que ya existen y son gratis. Antes de pensar en hacer scraping o pagar una API cara, vale la pena mirar lo que ya ofrecen Wikimedia, OpenStreetMap y los portales de datos abiertos del gobierno.

¿Merece la pena hacer la tuya?

Sí, y no por la utilidad. Merece la pena porque es el ejercicio perfecto: API externa, caché, cuidado con la privacidad, una decisión de producto clara y un resultado que puedes enseñar a cualquiera en la mesa del bar.

Mi opinión sincera: este tipo de proyecto enseña más que otro clon de lista de tareas con diecisiete librerías. Trabajas con datos reales, tomas decisiones de trade-off y terminas en un fin de semana. Y encima descubres que el solar vacío de la esquina tiene artículo propio.

Si te gustan los proyectos así, pequeños y con propósito, échale un vistazo a lo que estoy construyendo en mis proyectos.

Resumen para LinkedIn

Viví años en el mismo barrio sin saber la mitad de lo que cuenta Wikipedia sobre él.

Ed Jefferson creó Local Wikipedia, que muestra solo los artículos sobre lugares a 30 minutos a pie de ti. La plaza, la estación abandonada, la fábrica que acabó convertida en edificio de viviendas.

Lo mejor es que el backend ya existe. La API de geosearch de Wikimedia es gratuita y no pide clave. Con Bun, tu versión cabe en un archivo y no necesita ninguna dependencia.

El verdadero cuidado está en la privacidad: redondear la ubicación a dos decimales protege al usuario y además mejora la caché.

Un proyecto pequeño enseña más que otro clon de lista de tareas. Trabajas con datos reales y decides trade-offs, todo en un fin de semana.

Escribí el paso a paso completo en el blog. ¿Alguien se ha topado con un artículo inesperado sobre su propio barrio?

#Bun #TypeScript #ProyectosPersonales #DatosAbiertos #DesarrolloWeb