{"_id":"qibla-compass","_rev":"3-4f669587eeefe561620c8990aa3f034f","name":"qibla-compass","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"qibla-compass","version":"1.0.0","keywords":["qibla","compass","bearing","kaaba","islamic","prayer","geodesic","vincenty","magnetic-declination"],"author":{"name":"Alkarar Tech","email":"haydar.alkararllc@gmail.com"},"license":"MIT","_id":"qibla-compass@1.0.0","maintainers":[{"name":"alkarartech","email":"haydar.alkararllc@gmail.com"}],"homepage":"https://github.com/alkarartech/qibla-compass#readme","bugs":{"url":"https://github.com/alkarartech/qibla-compass/issues"},"dist":{"shasum":"07cb36fd61168f2841151ffc3a849ea32bf54fd3","tarball":"https://registry.npmjs.org/qibla-compass/-/qibla-compass-1.0.0.tgz","fileCount":24,"integrity":"sha512-4c8eCWzM7XO53s4hxggRIROmSQBElbqRwZe8bkzX1Ycmht+5oa6D4CQFHsetfY4jrXjUy5sCLCPUfzbjrTGTQA==","signatures":[{"sig":"MEUCICRWm0sfd5Knn8VnT1Zo1/DOf4/rbGqQA97NAz+9mJ7+AiEAoEhXBKYLWvSMRO2jpXI+D/rZZK1jm3wYaeLDRtSHZlI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":28832},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.js"}},"gitHead":"8165ac3e66fee222908a4e3983af5e0c3f57cd81","scripts":{"test":"node --experimental-vm-modules node_modules/jest/bin/jest.js","build":"tsc","prepublishOnly":"npm run build"},"_npmUser":{"name":"alkarartech","email":"haydar.alkararllc@gmail.com"},"repository":{"url":"git+https://github.com/alkarartech/qibla-compass.git","type":"git"},"_npmVersion":"11.5.1","description":"Accurate Qibla bearing and compass utilities for JavaScript/TypeScript (React Native, Expo, web)","directories":{},"_nodeVersion":"20.19.1","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","ts-jest":"^29.1.2","typescript":"^5.3.3","@types/jest":"^29.5.12","@types/react":"^18.2.0"},"peerDependencies":{"react":">=17.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/qibla-compass_1.0.0_1773570560819_0.32276192264713166","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"qibla-compass","version":"1.0.1","keywords":["qibla","compass","bearing","kaaba","islamic","prayer","geodesic","vincenty","magnetic-declination"],"author":{"name":"Alkarar Tech","email":"haydar.alkararllc@gmail.com"},"license":"MIT","_id":"qibla-compass@1.0.1","maintainers":[{"name":"alkarartech","email":"haydar.alkararllc@gmail.com"}],"homepage":"https://github.com/alkarartech/qibla-compass#readme","bugs":{"url":"https://github.com/alkarartech/qibla-compass/issues"},"dist":{"shasum":"99f044a039f375a5710a84cca65e76eaf40a551c","tarball":"https://registry.npmjs.org/qibla-compass/-/qibla-compass-1.0.1.tgz","fileCount":24,"integrity":"sha512-djbKPIe+JBQ7+CNbe1sZGFXpu6Fmwah7zYb9VO6Ap/ixM5J8AsmJIvWWk1Yxf6xuK/8/Pc9AFPj7VUkY26X4cQ==","signatures":[{"sig":"MEQCIBz+WP+hTH4FHgIURZoFlyDkjwlfiusqdrK/QhGPNREFAiBQrsWeYG6wj9lx7jr+/Wvtm9R8luMWymoGhLoJwz/Zww==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":31521},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.js"}},"gitHead":"fd575bd1080b96a36530432a1d943b651aab5c6f","scripts":{"test":"node --experimental-vm-modules node_modules/jest/bin/jest.js","build":"tsc","prepublishOnly":"npm run build"},"_npmUser":{"name":"alkarartech","email":"haydar.alkararllc@gmail.com"},"repository":{"url":"git+https://github.com/alkarartech/qibla-compass.git","type":"git"},"_npmVersion":"11.5.1","description":"Accurate Qibla bearing and compass utilities for JavaScript/TypeScript (React Native, Expo, web)","directories":{},"_nodeVersion":"20.19.1","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","ts-jest":"^29.1.2","typescript":"^5.3.3","@types/jest":"^29.5.12","@types/react":"^18.2.0"},"peerDependencies":{"react":">=17.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/qibla-compass_1.0.1_1773572143159_0.5252580725761211","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2026-03-15T10:29:20.818Z","modified":"2026-11-05T09:05:56.766Z","1.0.0":"2026-03-15T10:29:20.973Z","1.0.1":"2026-03-15T10:55:43.331Z"},"bugs":{"url":"https://github.com/alkarartech/qibla-compass/issues"},"author":{"name":"Alkarar Tech","email":"haydar.alkararllc@gmail.com"},"license":"MIT","homepage":"https://github.com/alkarartech/qibla-compass#readme","keywords":["qibla","compass","bearing","kaaba","islamic","prayer","geodesic","vincenty","magnetic-declination"],"repository":{"url":"git+https://github.com/alkarartech/qibla-compass.git","type":"git"},"description":"Accurate Qibla bearing and compass utilities for JavaScript/TypeScript (React Native, Expo, web)","maintainers":[{"email":"haydar.alkararllc@gmail.com","name":"karartech"}],"readme":"# qibla-compass\n\nAccurate **Qibla** (and multi-destination) bearing and compass utilities for JavaScript/TypeScript apps: React Native, Expo, and web.\n\n- **True bearing** from any (lat, lon) to the Kaaba (and optionally Madinah, Karbala, Najaf) using a **geodesically accurate** method (Vincenty on WGS84) with spherical fallback.\n- **Magnetic declination** helper (with caching and fallback) so your compass can display **true North** and the Qibla direction correctly.\n- **Framework-agnostic** core; optional React hook.\n\nAll angles are in **degrees**; bearings are **0–360° from true North, clockwise**.\n\n---\n\n## Install\n\n```bash\nnpm install qibla-compass\n```\n\n---\n\n## Quick usage\n\n```ts\nimport {\n  getQiblaDirection,\n  getBearingToTarget,\n  getCardinalFromBearing,\n  getMagneticDeclination,\n  SITES,\n  TARGET_KEYS,\n} from 'qibla-compass';\n\n// Direction to the Kaaba (default)\nconst { bearing, cardinal } = getQiblaDirection(40.7128, -74.006);\n// e.g. { bearing: 58.4, cardinal: 'ENE' }\n\n// Bearing only (0–360 from true North)\nconst deg = getBearingToTarget(40.7128, -74.006, 'kaaba');\n\n// Cardinal from any bearing\ngetCardinalFromBearing(90); // 'E'\n\n// Magnetic declination for compass correction (see below)\nconst declination = await getMagneticDeclination(40.7128, -74.006);\n```\n\n---\n\n## True North vs magnetic North (why declination matters)\n\nA device compass usually reports **magnetic heading** (angle to magnetic North). Qibla bearing from this package is **true bearing** (angle to geographic North).\n\nTo show the correct Qibla direction on a compass UI:\n\n- **True heading = magnetic heading + magnetic declination**\n- **Declination** is in degrees; **East is positive**, West is negative.\n\nSo:\n\n1. Get **true Qibla bearing**: `getQiblaDirection(lat, lon).bearing`.\n2. Get **magnetic declination** at the user’s location: `await getMagneticDeclination(lat, lon)`.\n3. In your compass view: turn the “Qibla needle” or overlay so that when the device reports **magnetic heading = true Qibla bearing − declination**, the needle points up (or align your compass ring so that **true North** is at angle `-declination` from magnetic North).\n\nExample (conceptual):\n\n```ts\nconst { bearing: trueQibla } = getQiblaDirection(lat, lon);\nconst declination = await getMagneticDeclination(lat, lon);\n// Magnetic heading that corresponds to “user facing Qibla”:\nconst magneticQibla = trueQibla - declination;\n// Then compare device compass heading to magneticQibla to rotate the needle.\n```\n\n---\n\n## API\n\n### Direction (synchronous)\n\n- **`getQiblaDirection(lat, lon, targetKey?)`**  \n  Returns `{ bearing, cardinal }`.  \n  `bearing`: 0–360 from true North, clockwise.  \n  `cardinal`: e.g. `\"NE\"`, `\"SSW\"`.  \n  `targetKey` defaults to `'kaaba'`. Use `'madina'` for Madinah (alias for `'madinah'`).\n\n- **`getBearingToTarget(lat, lon, targetKey?)`**  \n  Returns only the true bearing in degrees (0–360). Accepts `'madina'` as alias for `'madinah'`.\n\n- **`getCardinalFromBearing(degrees)`**  \n  Returns cardinal/intercardinal string for any bearing (0–360).\n\n### Targets\n\n- **`SITES`** – Object of coordinates and names: `kaaba`, `madinah`, `karbala`, `najaf`.\n- **`TARGET_KEYS`** – `['kaaba', 'madinah', 'karbala', 'najaf']`.\n- **`DEFAULT_TARGET`** – `'kaaba'`.\n\nKaaba coordinates used: **21.422508°N, 39.826183°E** (WGS84).\n\n### Magnetic declination (async)\n\n- **`getMagneticDeclination(lat, lon, options?)`**  \n  Returns declination in degrees (East positive). Uses an optional API (e.g. NOAA) with in-memory cache and fallback (0 or coarse static table) on failure.\n\n  `options`:\n\n  - `apiUrl` – Custom endpoint.\n  - `fetch` – Custom `fetch` (e.g. with API key in headers).\n  - `useStaticFallback` – If `false`, skip static fallback and use 0 on failure (default: true).\n\n- **`getCachedDeclination(lat, lon, useStaticFallback?)`**  \n  Synchronous: returns cached value or static/0 fallback. Use after at least one `getMagneticDeclination` call if you need sync values.\n\n- **`clearDeclinationCache()`**  \n  Clears the in-memory declination cache.\n\n**Note:** NOAA’s geomagnetic API may require registration. Use `options.fetch` or `options.apiUrl` with your own key/endpoint if needed.\n\n### Lower-level bearing\n\n- **`getBearing(fromLat, fromLon, toLat, toLon)`**  \n  True bearing between two WGS84 points (Vincenty with great-circle fallback).\n- **`bearingVincenty(...)`** – Vincenty only; returns `null` if no convergence.\n- **`bearingGreatCircle(...)`** – Spherical bearing.\n\n---\n\n## React hook\n\nOptional hook (import from the `react` subpath):\n\n```ts\nimport { useQiblaDirection } from 'qibla-compass/react';\n\nfunction Compass({ lat, lon }) {\n  const { bearing, cardinal } = useQiblaDirection(lat, lon, { targetKey: 'kaaba' });\n  return (\n    <div>\n      Qibla: {bearing.toFixed(1)}° ({cardinal})\n    </div>\n  );\n}\n```\n\n---\n\n## Usage in Node, React, React Native / Expo\n\n- **Node / any JS env:** Use the main entry point; call `getQiblaDirection`, `getMagneticDeclination`, etc. Use a polyfill for `fetch` in Node if needed (e.g. `node-fetch` or Node 18+ built-in).\n- **React (web):** Same; use `useQiblaDirection` from `qibla-compass/react` if you want a hook.\n- **React Native / Expo:** Use the same API. For declination, ensure `fetch` is available or pass a custom `fetch` in options. No React Native–specific code is required in the core.\n\n---\n\n## Integration (compass apps)\n\n- **Coordinates:** All lat/lon are in **decimal degrees (WGS84)**. Do not pass radians or DMS.\n- **Target keys:** Package uses `'kaaba'`, `'madinah'`, `'karbala'`, `'najaf'`. If your app uses `'madina'` for Madinah, pass `'madina'` — it is accepted as an alias and normalized to `'madinah'`. Use `TARGET_KEY_ALIASES` or `normalizeTargetKey()` for custom mapping.\n- **Compass heading:** Device compass gives **magnetic** heading. Use **true heading = magnetic heading + declination** (declination East is positive). Then compare true heading to `getQiblaDirection(lat, lon).bearing` for the needle angle, or use **magnetic Qibla = true Qibla − declination** and compare to the raw magnetic heading.\n- **Convention:** All bearings are **0° = North, 90° = East**, clockwise. Use the same convention for the compass needle (e.g. 0° at top, clockwise).\n\n---\n\n## Bundle size\n\nCore is plain JS/TS with no heavy geo dependency; Vincenty and great-circle are implemented in-place. Declination uses `fetch` and optional static fallback only.\n\n---\n\n## License\n\nMIT.\n","readmeFilename":"README.md"}