Fast, daily-rebuilt IP to country databases.
IPv4 + IPv6 to two-letter ISO-3166 country code.
Merged from IPFire, DB-IP, IP2Location and iptoasn. Reserved/unknown to ZZ.
Latest release ships three files:
| File | Size | Best for |
|---|---|---|
country.bin |
~1.8MB | fastest, mmap-friendly binary |
country.csv |
~7.5MB | lossless text, sorted, bisectable |
country-small.csv |
~2.6MB | smallest, lossy (coarsened) text |
curl -LO https://github.com/tn3w/ip2c/releases/latest/download/country.binTwo zero-dependency modules in golf/. load once, then lookup:
import { readFileSync } from "node:fs"
import { load, lookup } from "./golf/bin"
const db = load(readFileSync("country.bin"))
lookup(db, "8.8.8.8") // "US"
lookup(db, "2606:4700:4700::1111") // "US"import { readFileSync } from "node:fs"
import { load, lookup } from "./golf/csv"
const db = load(readFileSync("country.csv", "utf8"))
lookup(db, "1.1.1.1") // "CN"CLI: npm run lookup country.bin 8.8.8.8 2606:4700:4700::1111
The CSV splits at the 6 marker line. load fills only the section kept; the other
family returns ZZ.
sed '/^6$/Q' country.csv > country-v4.csv # 3.2MB
sed -n '/^6$/,$p' country.csv > country-v6.csv # 4.4MBOptional. country.bin bundles into a Worker for sub-millisecond, zero-subrequest
lookups.
GET /?ip=1.1.1.1 {"ip":"1.1.1.1","country":"CN"}
GET / country of the caller (CF-Connecting-IP)Live instance: ip2c.tn3w.dev.
Deploy your own:
npm install
npm run build && npx wrangler deploypublish.ymldaily: builds the files, cuts a Release (keeps the latest 5), redeploys the Worker.deploy.ymlonsrc/**push: redeploys the Worker with the latest releasedcountry.bin.
Deploys need repo secrets CLOUDFLARE_API_TOKEN (Workers Scripts: Edit) and
CLOUDFLARE_ACCOUNT_ID; without them they no-op.
scripts/build.ts merges the sources by priority into per-family breakpoint tables,
then emits the three files. Lookup is a binary search over sorted range starts.
.csv4/6marker lines, then<start><CC>rows; each start owns the range up to the next. v4 drops trailing.0, v6 is the /64 upper-64..binmagicIPC2, little-endian. Per family: block keys + offsets + varint body; bisect keys, seek, walk up to 64 rows. Layout insrc/lib/build.ts.