← Martin Kocisky playground / onsen-guide
Onsen Guide icon
Side project Web · Next.js

Onsen Guide 温泉ガイド

A guide to Japanese hot springs that tries to be right rather than comprehensive. Every fact that can be cited is cited, every entry shows when a human last checked it, and the map shows the mountains — because that is where onsen are.

Cited facts Last-verified dates 10 泉質 PostGIS + MapLibre Bilingual search Installable PWA
Onsen Guide home screen on a phone
01The site

Start from the water, and the rest follows

Japanese law recognises ten kinds of hot spring, and every legal onsen posts its own on the analysis certificate by the changing room. The site is built around that fact rather than around a list of places to stay.

Onsen Guide home page
Map view

Map

Facilities plotted over 国土地理院 relief tiles, with a hillshade under the terrain.

Water types index

Water types

The ten legally recognised 泉質, each with its own page and colour.

An onsen entry

An entry

Springs, individual baths, and what each of them does to the water.

02What it solves

Right, rather than comprehensive

There is no shortage of onsen listings. What there is a shortage of, in English especially, is anything that models Japanese hot springs the way Japan actually does — as water first, and buildings second.

Water first, buildings second

A source may feed several facilities and a facility may tap several sources, so they are modelled many-to-many — and every bath individually, because 鶴の湯 has 白湯, 黒湯 and 中の湯 fed differently.

Cited, or visibly not

A source marker beside a price means someone read that price off a sign and recorded where. No marker means nobody has. The contrast is visible on purpose — a page that cited nothing would prove nothing.

Dated, not just confident

Every entry shows when a human last verified it. Onsen close, prices rise, and the 混浴 bath your guidebook promised became women-only in 2019. A date you can see beats a confident page that is quietly four years stale.

Bilingual, properly

English and Japanese throughout, with slugs derived from kana rather than kanji — because kanji readings are genuinely ambiguous and no library gets them right. 白骨温泉 is しらほね, not はっこつ.

Onsen are in the mountains

So the map shows the mountains. 淡色地図 under a hillshade, from Japan's Geospatial Information Authority — a 秘湯 at the head of a valley reads as being at the head of a valley.

Researched, never scraped

No commercial onsen directories, not once, and no Wikipedia prose — structured facts only. Nothing reaches a published entry without passing through a review queue and a human.

03Data & trust

The part that is actually hard

Anyone can list onsen. The claim here is narrower and harder: that each fact is attributable, each change is recoverable, and the licence position holds up.

Provenance

Every import shows its working

Each batch records the actual Overpass QL or SPARQL query it ran, its licence and its attribution text. The credits page is generated by querying those rows, never hand-maintained.

Licensing

Wikidata over OSM, deliberately

Wikidata is CC0. OpenStreetMap is ODbL, whose share-alike is contagious at the database level and could make the whole thing a Derivative Database — a decision worth making before the first import, not after.

Honesty

Nothing 404s because it closed

A closed facility keeps its page and gains a closure banner. Inbound links survive and the reader gets the truth: finding out is the point.

04Under the hood

How it's built

Next.js on the App Router, with content authored through a first-party studio into Postgres. The map endpoint assembles its whole FeatureCollection inside the database — json_build_object over a GiST-indexed geography column — so a viewport pan costs one round trip. Search runs trigram matching over a precomputed bilingual keyword bag, because to_tsvector cannot tokenise Japanese; queries are expanded through the same romanisation table used to build the index, so "Kusatu" typed in Kunrei matches a row whose romaji is the Hepburn "Kusatsu". Every entity mutation writes a revision row and rebuilds its search document in one transaction, and axe-core accessibility checks run across the public routes in CI.

Next.js React TypeScript Tailwind Drizzle ORM Postgres PostGIS MapLibre GL next-intl Better Auth Serwist PWA Playwright & Vitest
The corpus is deliberately small and deep rather than large and thin — the ten 泉質, all 47 prefectures and 1,912 municipalities are complete; the onsen entries are still being written. Map data 出典:国土地理院. A personal side project, not a booking site, and not affiliated with anyone.