Back to the blog
BunAPIsSide Project

Local Wikipedia with Bun: what exists 30 minutes from you

October 24, 2026·7 min read·Diego Horvatti

You've lived in the same neighborhood for years and you probably don't know half of what Wikipedia has on it. Ed Jefferson solved this with a small and very well thought out project: Local Wikipedia, a local Wikipedia that only shows articles about things within a half-hour walk of where you are. No world wars, no celebrities. Just the square, the old church, the abandoned station and that factory that became a condo.

The idea is so simple that you want to build your own version over the weekend. So let's build it, with Bun.

What Ed Jefferson's local Wikipedia is

The site takes your location and lists the Wikipedia articles that have geographic coordinates near you. The cutoff is human: what you can reach on foot in about 30 minutes. At 5 km/h, that's somewhere around 2.5 km.

It sounds silly. It isn't. Wikipedia has hundreds of thousands of articles with coordinates, and most of them never show up for you because nobody searches for "the iron bridge on the street behind mine". The project flips the logic. Instead of you going after the content, the content comes from the place where you already are.

I tested it in my head with my own neighborhood and I already know what will happen. A three-line article about a gas station that closed in 1987 will show up. And I'll read the whole thing.

The best side projects solve a curiosity, not a market.

How it works under the hood: the geosearch API

The technical part is almost all Wikimedia's. The MediaWiki API has a module called geosearch that takes a coordinate and a radius and returns the articles tagged in that area. No key, no sign-up.

The parameters that matter:

  • gscoord: latitude and longitude separated by |.
  • gsradius: radius in meters, up to 10,000.
  • gslimit: how many results, up to 500.

A call for downtown São Paulo looks like this:

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

The response comes with the title, pageid, coordinates and the distance in meters to the point. In other words, the backend for a local Wikipedia already exists. You only need a thin layer on top.

One detail a lot of people ignore: Wikimedia asks every client to send an identifiable User-Agent with contact info. If you forget, you might get blocked. It's basic manners with a free API that holds up half the internet.

Building your version with Bun

This is where Bun shines, because the whole project fits in one file with no dependencies at all. Native fetch, native HTTP server, TypeScript running directly.

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

async function nearby(lat: number, lon: number) {
  // ponytail: round to ~1 km, protects privacy and improves the cache
  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://en.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': 'local-wiki/1.0 (contact@yourdomain.com)' },
  })
  const data = (await res.json()).query.geosearch
  cache.set(key, { at: Date.now(), data })
  return data
}

Bun.serve({
  port: 3000,
  routes: {
    '/api/nearby': 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('invalid lat/lon', { status: 400 })
      }
      return Response.json(await nearby(lat, lon))
    },
  },
})

Run it with bun run server.ts and you're done. On the front end, a navigator.geolocation.getCurrentPosition call hits this endpoint and you render a list. You can do it in plain HTML, no framework.

Why have a backend if the Wikipedia API accepts calls straight from the browser? Three practical reasons:

  • Cache: ten people in the same neighborhood become a single call to Wikimedia.
  • User-Agent: the browser doesn't really let you control this header.
  • Privacy: the server only sees a rounded coordinate, and Wikimedia doesn't even see that.

The in-memory Map has an obvious limit. Restart the process and the cache is gone, and it grows with no ceiling. For a side project, that's fine. If it turns into something serious, swap it for Redis or a PostgreSQL table with an index on the rounded coordinates.

Why location privacy matters

This is what separates a cool project from a responsible one. Exact location is sensitive data. With four decimal places you can identify someone's house. With two, you identify a neighborhood.

For a local Wikipedia, two decimal places are enough. An error of about 1.1 km within a 2.5 km radius barely changes the result. But it changes a lot about what leaks into your access logs.

If you're going to publish something like this, it's also worth it to:

  • Not log raw lat and lon.
  • Ask for the location only when the person clicks a button, never on page load.
  • Offer an address search field for people who don't want to share their GPS.

It's the kind of care that takes five minutes and saves you a huge headache with privacy laws like GDPR or Brazil's LGPD later.

A straight line isn't a walk

Here's the catch. gsradius measures straight-line distance. But nobody walks in a straight line. There are rivers, overpasses, avenues with no crosswalk.

In practice, a point 2 km away in a straight line can be a 40-minute walk. If you want to stay true to the "half an hour on foot" promise, you have two options:

  1. Honest approximation: use a smaller radius, like 2 km, and accept the imprecision.
  2. Real routing: run the results through a routing service like OSRM or Valhalla, on the pedestrian profile, and filter by real travel time.

The second option is much more expensive. A hundred articles become a hundred route calculations, or one matrix call if the service supports it. For a curiosity project, I'd go with the first. The fun is in discovering, not in timing.

If you want to sort by distance on your side, the haversine formula does it in a few lines. But notice that the API already returns a dist field. Don't rewrite what already comes ready.

What this project teaches people who write code

I like Local Wikipedia for a reason that has little to do with geography. It's a reminder that a good product can be a slice, not a platform.

Ed didn't build an encyclopedia. He took a public API, applied a filter with human meaning and shipped it. No account, no onboarding, no notification begging you to come back.

We developers have a habit of starting side projects with the docker-compose.yml. Monorepo, auth, queue, admin panel. Three weeks later, not a single line solves the problem that sparked the idea. This project is the opposite of that, and Bun fits this mindset well: one file, zero npm install, starts in milliseconds.

There's also a lesson about open data. Wikipedia has stored coordinates for years, edited by volunteers, and almost nobody uses that creatively. There are plenty of projects waiting to be built on top of APIs that already exist and are free. Before thinking about scraping a site or paying for an expensive API, take a look at what Wikimedia, OpenStreetMap and government open data portals already offer.

Is it worth building your own?

Yes, and not because it's useful. It's worth it because it's the perfect exercise: an external API, caching, privacy care, a clear product decision and a result you can show anyone at the bar.

My honest opinion: this kind of project teaches more than yet another to-do list clone with seventeen libraries. You work with real data, make trade-off decisions and finish in a weekend. And you also find out that the empty lot on the corner has its own article.

If you enjoy projects like this, small and with a purpose, take a look at what I've been building in my projects.

LinkedIn summary

I lived in the same neighborhood for years without knowing half of what Wikipedia says about it.

Ed Jefferson built Local Wikipedia, which shows only articles about places within a 30-minute walk of you. The square, the abandoned station, the factory that became a condo.

The best part is that the backend already exists. The Wikimedia geosearch API is free and needs no key. With Bun, your version fits in one file and needs zero dependencies.

The real care goes into privacy: rounding the location to two decimal places protects the user and even improves the cache.

A small project teaches more than yet another to-do list clone. You work with real data and make trade-offs, all in one weekend.

I wrote the full walkthrough on the blog. Have you ever stumbled on an unexpected article about your own neighborhood?

#Bun #TypeScript #SideProjects #OpenData #WebDevelopment