npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ortho-earth/japan

v1.6.0

Published

Serverless, dependency-free 3D globe of Japan for any web page — GSI vector tiles and MLIT PLATEAU buildings drawn on a true sphere with WebGPU/WebGL2. No API keys, no billing, no servers.

Readme

ortho-japan

日本語版ドキュメント: README-ja.md

A serverless, dependency-free 3D globe of Japan for any web page. GSI optimized vector tiles and MLIT PLATEAU city models, drawn on a true sphere with WebGPU/WebGL2 — zoom out to a globe, zoom in and the buildings stand up. No API keys, no billing, no servers: public data is fetched directly by the visitor's browser and cached locally.

<link rel="stylesheet" href="/ortho-japan/ortho-japan.css">
<div id="here" style="width:640px;height:420px"></div>
<script type="module">
  import orthoJapan from "/ortho-japan/ortho-japan.js";
  await orthoJapan({ target: "#here", assetBase: "/ortho-japan-assets/" });
</script>

Install

npm — npm install @ortho-earth/japan. The package ships a prebuilt, self-contained ESM bundle (dist/lib/) and its runtime assets (assets/, ~230 KB). It declares zero runtime dependencies — check package.json, it's empty.

zip — grab ortho-japan-sdk-<version>.zip from GitHub Releases. Same artifact, plus a runnable example/.

Network footprint. Map data comes straight from the public providers (GSI, PLATEAU, JAXA). The one ortho-earth host the SDK talks to is api.ortho-earth.com: a few global base layers (world coastlines, lakes, borders, stars) and the URL proxy used when you pass a URL to geopbf() — if that proxy declines a host, the SDK falls back to a direct browser fetch (1.0.4+; the target must allow CORS). Your own data never leaves the browser otherwise.

Either way, deployment is the same: serve dist/lib/ (or the zip's lib/) and assets/ as static files on your site, import the entry by URL, and point assetBase at wherever you put the assets. There is no bundler step — workers and lazy chunks resolve relative to the module, so the SDK works at any path. (From npm, copy node_modules/@ortho-earth/japan/dist/lib and assets into your public directory, or wire up your bundler's static-copy plugin.)

From npm, the two copy commands are all you need:

cp -R node_modules/@ortho-earth/japan/dist/lib public/lib
cp -R node_modules/@ortho-earth/japan/assets  public/assets

then import orthoJapan from "./lib/ortho-japan.js" and assetBase: "./assets/".

A working sample ships in the zip (example/index.html): serve the unzipped folder over HTTP and open /example/. file:// will not work — ES modules.

orthoJapan(opts)

| option | default | description | |---|---|---| | target | auto | Where to embed (selector or element). The container's id is normalized to map while the map lives there and returned on destroy() | | view | last view | Initial view "#zoom/lat/lon/45t/30r/l=place.rail/c=dark" (t = tilt°, r = rotation°, l = layers, c = theme) | | theme | "mono" | Fixed color theme: "mono" (blank map), "dark", "gsi" (official GSI map colors), "sepia", or a custom theme object. Unset = selectable via the shared-URL c= token | | layers | — | Pin layers on/off: place, terrain, rail, road, facility. true = always on, false = always off (both hide the toggle chip); unset = user-toggleable | | chips | true | The layer/theme chip bar (top right) | | instruments | true | Bottom instrument bar. true = all, array = selective, false = none. Keys: pos, scale, attr (attribution), log | | mesh | true | 3D buildings (PLATEAU) master switch. false disables the catalog, workers, and auto-loading entirely — no multi-MB transfers ever start | | plateau | — | Deprecated alias of mesh (1.1.x name; still accepted, mesh wins if both are given). | | maxPitch | 75° | Tilt limit in radians. 0 = locked top-down | | lang | auto | UI language "ja" / "en". Unset = ?lang= → browser language. Applies to UI chrome only — map labels are part of the map data | | assetBase | "./" | Where the runtime assets live (see Install). Relative or absolute URL |

Returns map — the full surface is typed in dist/lib/ortho-japan.d.ts: view / flyTo (Promise) / on/off (load, move, settle, mesh — old name plateau still fires —, click) / projectLL, makeProjector, onFrame, requestDraw (DOM overlays) / unprojectXY / getHeight / gadget.* / the gint handles (applyGintData, paint, paintTable, onGintClick) / backend / destroy.

map.destroy() tears everything down — workers, listeners, render loop, timers, DOM — and returns the container as it was (id restored, children removed, SDK classes removed). IndexedDB caches (PLATEAU, elevation) survive as origin assets, so revisits stay fast. Re-create with view: map.view.hash to keep the viewpoint — that is also how you change lang or theme, which have no live-switch API. (1.0.3 and earlier: destroying within 20 s of a WebGPU boot left a watchdog that reloaded the host page — fixed in 1.0.4.)

In an embed (target given) the SDK does not touch the page URL; pass urlHash: true to keep the view hash in the address bar as the full site does. Elevation tiles for the terrain are fetched on demand from api.ortho-earth.com (tens of MB over a session) even with plateau: false.

Opt-in gadgets (map.gadget.*)

Only what you call gets mounted; call order = top-to-bottom placement.

map.gadget.search();    // place/address search (GSI API, no key)
map.gadget.compass();   // compass + reset (appears only in 3D)
map.gadget.zoom();      // zoom +/- buttons
map.gadget.palette();   // theme switcher with live previews
map.gadget.measure();   // geodesic distance / area measurement
map.gadget.shot();      // save the view as an image (attribution baked in)
map.gadget.print();     // paper-spec plan printing (true scale, A4/A3, graticule) → PDF
map.gadget.qr();        // share the current view as a QR code
map.gadget.equal({ zoom: [-99, 5] });   // to ortho-equal (Equal Earth): overlays /equal/ in an iframe (same URL) and unfolds from the same globe; map.gadget.equalHere() is the context-menu item
map.gadget.mesh();      // 3D building data manager (preload / delete) — old name map.gadget.plateau() still works
map.gadget.contextmenu();
map.gadget.dropFile();  // drag & drop GIS files (GeoJSON/Shapefile/KML/GPX/FGB/GML/GeoParquet/COG/glTF-GLB…)
map.gadget.hint();      // gesture help card
map.gadget("myGadget", function () { /* this = map */ });   // your own

Promises to the host page

Verified mechanically on every build (verify:lib):

  • Never touches your html/body — background, margins, overflow, fonts and scroll are identical before and after embedding
  • Renders only inside the div you provide (no full-screen takeover)
  • No window globals (debug handles appear only without target, or with debugGlobals: true)
  • destroy() restores the host completely

COOP/COEP not required. crossOriginIsolated only enables a SharedArrayBuffer fast path; without it the engine falls back to one extra copy and produces identical results.

One map per page (fixed element-id contract). Requirements: WebGL2 + OffscreenCanvas (Chrome / Edge / Firefox / Safari 17+). Unsupported browsers get a polite text explanation instead of a blank page.

Attribution (required)

The map data comes with attribution obligations. Displaying attribution is the embedder's duty.

The built-in attr instrument (bottom right) covers this by default. If you remove it, the obligation does not disappear — put an equivalent credit somewhere visible on your page:

Source: GSI Optimized Vector Tiles (experimental), GSI elevation tiles (DEM10B), MLIT PLATEAU, JAXA AW3D30 (created by processing these data sources)

Loading your own data (geopbf)

The SDK bundles the GeoPBF library and exports its ready-to-use loader as a named export (1.0.3+) — no second package, no bundler, no import map:

import orthoJapan, { geopbf } from "/ortho-japan/ortho-japan.js";
const map = await orthoJapan({ target: "#here", assetBase: "/ortho-japan-assets/" });
const pbf = await geopbf(featureCollection, { name: "myapp/data" });   // GeoJSON object / File / URL / ArrayBuffer — gint is baked by default
map.applyGintData(pbf, "mydata", true, { interactive: true });
map.onGintClick((fid, props) => console.log(props));

geopbf() reads GeoJSON, TopoJSON, FlatGeobuf, Shapefile (zip), KML/KMZ, GPX, CZML, GML, MOJ (zip) and GeoPBF itself (gzip OK) and writes them back out (pbf.geojsonFile(), pbf.shapeFile(), …). The workers it uses are the lazy chunks already in dist/lib/, so this works from a plain static HTML page. Do not call createGeopbf — the SDK has already initialised the instance (it is not exported). Types: GeoPBF in ortho-japan.d.ts.

The library is also published standalone on npm (geopbf, MIT) for use outside the globe. Do not mix the two on one page: the npm copy is a separate instance and you would ship the library twice. @ortho-earth/japan 1.0.2 and earlier did not export geopbf — upgrade.

Developing with AI agents

A one-page canon for AI coding agents (API surface, pitfall ledger, verification recipes) is served at https://www.ortho-earth.com/japan/llms.txt and bundled in the package. Drop the bundled sdk/skill/ortho-earth-sdk/ into your .claude/skills/ and Claude Code writes against the SDK idiomatically. TypeScript definitions: dist/lib/ortho-japan.d.ts (also served at https://www.ortho-earth.com/japan/lib/ortho-japan.d.ts). Data loading goes through the SDK's own geopbf export (previous section). sdk/verify-example.mjs is a zero-dependency real-time headless-Chrome checker (title PASS/FAIL, screenshot, 4xx ledger) for self-judging test pages.

License

GPL-3.0-or-later (LICENSE). A commercial license — without GPL obligations such as disclosing your site's source — is available: contact [email protected].


Development guide (build, verification harnesses, dev/prod dual structure): see README-ja.md. Live flagship: https://www.ortho-earth.com/japan/