日本語: README.md
A JavaScript library for looking up Japanese addresses by postal code. Designed for use cases like form address autofill — works in the browser or Node.js with no external API server required.
Versions follow the MAJOR.MINOR.YYYYMM format, where YYYYMM is the year and month of the bundled dataset. The npm version badge above therefore doubles as a data-freshness indicator (e.g. 1.0.202607 ships the July 2026 dataset).
- 🔄 Auto-updated monthly — A new version is automatically published to npm whenever the upstream jpostcode-data refreshes
- 🌐 Official CDN — Library script and postal data are served from Cloudflare Pages
- ⚡ No API server required — Runs entirely in the browser
- 📖 Kana readings — Returns kana for prefecture, city, and town
- 🏢 Office postal codes — Includes large-office (jigyosyo) postal codes with office name and street
- 🔀 Multiple addresses — Returns every address as an array when a postal code maps to more than one
- 🧩 TypeScript ready — Full type definitions included
- 📦 Node / bundlers / browsers — Works in Node.js, and in Vite / webpack projects via
jpostcode/web
| Format | How to load | API | Data source |
|---|---|---|---|
jpostcode (Node.js) |
require / import |
synchronous | JSON bundled in the package, read from disk |
jpostcode/web (bundlers / browsers) |
import |
Promise | fetched from the CDN per leading 3 digits |
| CDN script | <script> |
Promise | same as above |
| CDN bundle | <script> |
synchronous | all data inlined (~55MB) |
Copy and paste — it just works.
<script src="https://jpostcode-js.pages.dev/dist/jpostcode-web.js"></script>
<script>
Jpostcode.find('1000001').then(addresses => {
console.log(addresses[0]?.prefecture); // 東京都
});
</script>Both the library and postal code data are distributed via Cloudflare Pages. Data is fetched from the official CDN by default; call Jpostcode.setBaseUrl('/data/json/') to serve it yourself (see Self-hosting the data).
- Re-deployed automatically whenever upstream data is updated
- Served from Cloudflare's global edge (including Tokyo) for low latency
- Served with gzip / brotli compression — each lookup fetches one file per upper-3-digit block, a few KB to a few tens of KB over the wire
- JSON responses ship with
s-maxage=2592000(30 days at the edge) /max-age=86400(1 day in browsers)
When a 7-digit postal code is entered, prefecture / city / town fields are filled automatically.
<input id="zip" placeholder="Postal code (e.g. 1000001)">
<input id="prefecture" placeholder="Prefecture">
<input id="city" placeholder="City">
<input id="town" placeholder="Town">
<script src="https://jpostcode-js.pages.dev/dist/jpostcode-web.js"></script>
<script>
document.getElementById('zip').addEventListener('input', async (e) => {
const zip = e.target.value.replace(/[^0-9]/g, '');
if (zip.length !== 7) return;
const [address] = await Jpostcode.find(zip);
if (!address) return;
document.getElementById('prefecture').value = address.prefecture;
document.getElementById('city').value = address.city;
document.getElementById('town').value = address.town;
});
</script>npm install jpostcodeconst { Jpostcode } = require('jpostcode');
const addresses = Jpostcode.find('0010000');
for (const address of addresses) {
console.log(`${address.prefecture} ${address.city} ${address.town}`);
console.log(`(Kana: ${address.prefectureKana} ${address.cityKana} ${address.townKana})`);
}import { Address, Jpostcode } from 'jpostcode';
const addresses: Address[] = Jpostcode.find('0010000');
console.log(addresses[0]?.prefecture);Import jpostcode/web. The client itself is a few kilobytes; postal data is fetched from the official CDN per leading 3 digits of the postal code (fetched files are cached in memory).
import { Jpostcode } from 'jpostcode/web';
const addresses = await Jpostcode.find('1000001'); // Promise<Address[]>
console.log(addresses[0]?.prefecture); // 東京都Autofilling a form in React:
import { Jpostcode } from 'jpostcode/web';
function AddressForm() {
const [address, setAddress] = useState({ prefecture: '', city: '', town: '' });
const onZipChange = async (e: ChangeEvent<HTMLInputElement>) => {
const zip = e.target.value.replace(/[^0-9]/g, '');
if (zip.length !== 7) return;
const [found] = await Jpostcode.find(zip);
if (found) setAddress({ prefecture: found.prefecture, city: found.city, town: found.town });
};
return (
<>
<input onChange={onZipChange} placeholder="Postal code" />
<input value={address.prefecture} readOnly />
<input value={address.city} readOnly />
<input value={address.town} readOnly />
</>
);
}To serve the data yourself, see Self-hosting the data.
This build inlines the entire dataset in a single file. The file is large (~55MB, ~4MB over gzip transfer), but once loaded the API is synchronous and needs no network access.
<script src="https://unpkg.com/jpostcode@latest/dist/jpostcode-web-bundle.js"></script>
<script>
const addresses = Jpostcode.find('1000001'); // synchronous, not a Promise
console.log(addresses[0]?.prefecture);
</script>Load the bundle from unpkg — the file exceeds jsDelivr's 50MB size limit. For typical form use cases the fetch-based variants (CDN script or jpostcode/web) are recommended.
By default the fetch-based variants load data from the official CDN (jpostcode-js.pages.dev), which means the first 3 digits of the entered postal code are sent to the CDN as a request. To avoid this, or to keep distribution under your own control, you can host the dataset yourself.
-
Copy the dataset bundled in the npm package (951 JSON files, about 56MB) into your static assets directory
cp -r node_modules/jpostcode/dist/jpostcode-data/data/json public/data/json
-
Point the library at it
Jpostcode.setBaseUrl('/data/json/');
- Only one file (a few KB to a few hundred KB) is fetched per lookup, corresponding to the first 3 digits of the entered postal code
- The JSON compresses well (56MB total → about 3.8MB gzipped), so with gzip / brotli enabled on the server each file transfers as a few KB to a few tens of KB. Most static hosts and CDNs compress by default
- When serving from a different origin than the page, the server must send an
Access-Control-Allow-Originheader (not needed for same-origin) - Data updates ship with the monthly npm package updates; re-copy after
npm update jpostcode
Example nginx configuration. Note that nginx does not gzip JSON by default, so gzip_types is required:
location /data/json/ {
gzip on;
gzip_types application/json;
expires 1d;
add_header Cache-Control "public";
# Only when referenced from a page on a different origin
# add_header Access-Control-Allow-Origin "https://example.com";
}- Pass a 7-digit postal code string; hyphenated input (
'100-0001') is also accepted - Returns an array of
Addressobjects, since one postal code can map to multiple addresses (multiple towns, business postal codes, etc.). Returns an empty array if the postal code does not exist - The Node.js entry (
jpostcode) returnsAddress[]synchronously; the web entries (jpostcode/web/ CDN script) returnPromise<Address[]> - In the web entries, the Promise rejects when fetching data fails (network errors, HTTP 5xx, etc.) — distinct from "no matching address" (an empty array)
| Property | Type | Example |
|---|---|---|
zipCode |
string |
'1000001' |
prefecture |
string |
'東京都' |
prefectureKana |
string |
'トウキョウト' |
prefectureCode |
number |
13 (JIS prefecture code) |
city |
string |
'千代田区' |
cityKana |
string |
'チヨダク' |
town |
string |
'千代田' |
townKana |
string |
'チヨダ' |
street |
string | null |
building/floor detail (business postal codes only) |
officeName |
string | null |
company name (business postal codes only) |
officeNameKana |
string | null |
kana reading of the company name |
street / officeName / officeNameKana are populated for individual business postal codes and are null for regular addresses. JSON.stringify(address) produces a JSON object with the property names above.
Japan Post updates the postal code dataset every month, so data freshness is the practical differentiator (based on npm metadata as of July 2026).
| Library | Last release | Data delivery | Types |
|---|---|---|---|
| jpostcode | monthly (auto-published on upstream data updates) | bundled in package + official CDN | yes |
| jposta | 2026-06 | bundled (as of release) | yes |
| jp-zipcode-lookup | 2025-06 | bundled (as of release) | yes |
| japan-postal-code-oasis | 2023-12 | requires self-hosted data | no |
| japan-postal-code | 2023-07 | fetched from an external site | no |
| yubinbango-core2 | 2022-05 | fetched from yubinbango.github.io (data last updated 2026-05) | no |
Returned fields also differ (based on each library's documented return values and type definitions).
| Library | Kana | Office postal codes | Multiple addresses per code |
|---|---|---|---|
| jpostcode | prefecture / city / town | office name and street | all, as an array |
| jposta | no | no | single result only |
| jp-zipcode-lookup | prefecture / city only | no | all, as an array |
| japan-postal-code-oasis | no | no | single result only |
| japan-postal-code | no | no | single result only |
| yubinbango-core2 | no | no | single result only |
- The upstream jpostcode-data ingests Japan Post's latest dataset every month
- This library uses GitHub Actions to detect upstream updates and auto-publish a new version to npm and the CDN
- The
YYYYMMportion of theMAJOR.MINOR.YYYYMMversion indicates when the data was sourced (e.g.1.0.202607is the July 2026 dataset) - npm users just bump the dependency; CDN users get the latest automatically
Live demo: https://matzlika.github.io/jpostcode-js/
To run locally:
npm install
npm run build
mkdir -p docs/dist && cp -r dist/* docs/dist/
npx http-server docs -p 8000npm install
npm run build # builds CommonJS / ESM / jpostcode/web / browser variants
npm testIssues and pull requests are welcome.
This library uses data from jpostcode-data (Copyright 2023 SmartHR, Inc., MIT License). Many thanks to its maintainers and contributors.