sahih-muslim
The complete Sahih Muslim — 7,563 hadiths, full Arabic & English.
One repo · one dataset · published on both npm and PyPI.
✨ Features at a Glance
| Feature | Details | |
|---|---|---|
| 📚 | Complete Collection | All 7,563 authentic hadiths from Sahih Muslim |
| 🌐 | Bilingual | Full Arabic text + English translation for every hadith |
| 📝 | Chapters | 2,200+ chapters with Arabic & English names |
| ⚡ | Tiny Install | ~3KB package — data loaded from CDN on demand |
| 🔍 | Full-text Search | Search English text and narrator names instantly |
| 🖥️ | CLI | Terminal access with Arabic/English/both flags |
| ⚛️ | React Hook | One command generates useMuslim() in your project |
| 🐍 | Python | Identical API — same method names as the npm package |
| 📘 | TypeScript | Full type definitions, zero @types package needed |
| 🔧 | Zero Config | Works out of the box everywhere |
| 🗄️ | One Dataset | bin/muslim.json shared by both JS and Python |
🚀 Installation
| JavaScript / Node.js | Python |
# local (for projects)
npm install sahih-muslim
# global (for CLI)
npm install -g sahih-muslim
|
# local (for projects)
pip install sahih-muslim
# global CLI is included automatically
|
🟨 JavaScript / Node.js
CommonJS & ESM
// CommonJS — require()
const muslim = require("sahih-muslim");
// ESM — import
import muslim from "sahih-muslim";
// Get by ID
muslim.get(1); // → Hadith
// Get by chapter
muslim.getByChapter(1); // → Hadith[]
// Full-text search
muslim.search("prayer"); // → Hadith[]
// Random
muslim.getRandom(); // → Hadith
// Index access
muslim[0]; // → Hadith (first)
muslim.length; // → 7563
// Metadata
muslim.metadata; // → { title, author, ... }
muslim.chapters; // → Chapter[]
Hadith object shape
{
id: 1,
chapterId: 1,
arabic: "حَدَّثَنِي يَحْيَى بْنُ يَحْيَى...",
english: {
narrator: "Yahya bin Yahya",
text: "It is narrated on the authority of Amir al-Mu'minin..."
}
}
Native array methods — all work
muslim.find((h) => h.id === 23);
muslim.filter((h) => h.chapterId === 1);
muslim.map((h) => h.english.narrator);
muslim.forEach((h) => console.log(h.id));
muslim.slice(0, 10);
⚛️ React / Vue / Vite
Run this once inside your React project:
cd my-react-app
muslim --react
This auto-generates src/hooks/useMuslim.js. Then use it anywhere:
import { useMuslim } from "../hooks/useMuslim";
function HadithOfTheDay() {
const muslim = useMuslim();
if (!muslim) return <p>Loading...</p>;
const h = muslim.getRandom();
return (
<div>
<p>
<strong>{h.english.narrator}</strong>
</p>
<p>{h.english.text}</p>
</div>
);
}
// Search example
function HadithSearch() {
const muslim = useMuslim();
const [results, setResults] = useState([]);
if (!muslim) return <p>Loading...</p>;
return (
<>
<input
placeholder="Search hadiths..."
onChange={(e) => setResults(muslim.search(e.target.value, 10))}
/>
{results.map((h) => (
<p key={h.id}>{h.english.text}</p>
))}
</>
);
}
Data is fetched from jsDelivr CDN once and cached globally. All components share the same request — no duplicates.
🐍 Python
The Python API is identical to the npm package — same camelCase method names, same behaviour.
from sahih_muslim import Muslim
muslim = Muslim() # reads bin/muslim.json if in repo, else fetches from CDN
# Exact same API as JS
muslim.get(1) # Hadith | None
muslim.getByChapter(1) # list[Hadith]
muslim.search("prayer") # list[Hadith]
muslim.search("prayer", limit=5) # list[Hadith] — top 5
muslim.getRandom() # Hadith
# Index access & iteration
muslim[0] # first hadith
muslim.length # 7563
len(muslim) # 7563
for h in muslim: print(h.id)
# Array-style methods (matches JS prototype)
muslim.find(lambda h: h.id == 23)
muslim.filter(lambda h: h.chapterId == 1)
muslim.map(lambda h: h.narrator)
muslim.slice(0, 10)
# Metadata
muslim.metadata.english # {"title": ..., "author": ...}
muslim.chapters # list[Chapter]
Custom data path
# Use your own muslim.json at any path
muslim = Muslim(data_path="/absolute/path/to/muslim.json")
muslim = Muslim(data_path=Path(__file__).parent / "muslim.json")
Flask API example
from flask import Flask, jsonify, request
from sahih_muslim import Muslim
app = Flask(__name__)
muslim = Muslim()
@app.get("/api/hadith/<int:hadith_id>")
def get_hadith(hadith_id):
h = muslim.get(hadith_id)
return jsonify(h.to_dict()) if h else ("Not found", 404)
@app.get("/api/search")
def search():
return jsonify([h.to_dict() for h in muslim.search(request.args.get("q", ""), limit=20)])
🖥️ CLI
The same muslim command works whether installed via npm or pip.
# By ID
muslim 1
muslim 2345
# Within a chapter
muslim 23 34
# Language flags
muslim 2345 # English only (default)
muslim 2345 -a # Arabic only
muslim 2345 --arabic # Arabic only
muslim 2345 -b # Arabic + English
muslim 2345 --both # Arabic + English
# Search
muslim --search "prayer"
muslim --search "fasting" --all # show all results (default: top 5)
# Chapter listing
muslim --chapter 5
# Random
muslim --random
muslim --random -b
# React hook generator (JS only — run inside your React project)
muslim --react
# Info
muslim --version
muslim --help
Example output
════════════════════════════════════════════════════════════
Hadith #1 | Chapter: 1 — Faith
════════════════════════════════════════════════════════════
Narrator: Yahya bin Yahya
It is narrated on the authority of Amir al-Mu'minin, Abu Hafs
Umar ibn al-Khattab, who said: I heard the Messenger of Allah
(ﷺ) say: "Actions are judged by intentions..."
════════════════════════════════════════════════════════════
🗄️ Monorepo Structure
sahih-muslim/
│
├── bin/
│ ├── muslim.json ← 🔑 SHARED — single source of truth for JS + Python
│ └── index.js ← JS CLI entry
│
├── chapters/ ← 🔑 SHARED — generated by `node build.mjs`
│ ├── meta.json used by CDN loader (JS browser) + Python CDN fallback
│ ├── 1.json
│ └── ...
│
├── sahih_muslim/ ← Python package
│ ├── __init__.py
│ ├── muslim.py ← auto-reads bin/muslim.json
│ └── cli.py
│
├── index.js ← JS ESM (browser-safe)
├── index.cjs ← JS CommonJS
├── index.node.js ← JS Node ESM
├── index.browser.js ← JS browser / CDN (auto-generated)
├── index.d.ts ← TypeScript definitions
├── build.mjs ← generates chapters/ from bin/muslim.json
│
├── package.json ← npm config
├── pyproject.toml ← Python / Poetry config
├── MANIFEST.in ← Python sdist: include data, exclude JS
└── .npmignore ← npm publish: exclude Python files
Shared data — how it works
| File | Used by |
|---|---|
bin/muslim.json |
JS Node (CJS + ESM) · Python (auto-detected from repo root) |
chapters/ |
JS browser CDN fetch · Python CDN fallback |
You never duplicate data. Both packages read the exact same file.
📊 API Reference
Methods
| Method | JS | Python | Returns |
|---|---|---|---|
get(id) |
✅ | ✅ | Hadith | undefined/None |
getByChapter(id) |
✅ | ✅ | Hadith[] |
search(query, limit?) |
✅ | ✅ | Hadith[] |
getRandom() |
✅ | ✅ | Hadith |
find(predicate) |
✅ | ✅ | Hadith | undefined/None |
filter(predicate) |
✅ | ✅ | Hadith[] |
map(fn) |
✅ | ✅ | any[] |
forEach(fn) |
✅ | ✅ | void/None |
slice(start, end) |
✅ | ✅ | Hadith[] |
Properties
| Property | Type | Description |
|---|---|---|
length |
number / int |
Total hadiths — 7,563 |
metadata |
Metadata |
Title, author, introduction |
chapters |
Chapter[] |
All chapters |
💡 Examples
Seed a MongoDB database (Node.js)
import { MongoClient } from "mongodb";
import muslim from "sahih-muslim";
const client = new MongoClient(process.env.MONGO_URI);
await client.connect();
await client
.db("islam")
.collection("hadiths")
.insertMany([...muslim]);
await client.close();
console.log("Seeded", muslim.length, "hadiths");
Seed a database (Python)
from sahih_muslim import Muslim
muslim = Muslim()
records = [h.to_dict() for h in muslim]
# Insert into any DB
print(f"Seeded {len(records)} hadiths")
Thematic search
from sahih_muslim import Muslim
muslim = Muslim()
topics = ["prayer", "charity", "fasting", "knowledge", "patience"]
for topic in topics:
count = len(muslim.search(topic))
print(f"{topic:12} → {count} hadiths")
Express.js REST API
import express from "express";
import muslim from "sahih-muslim";
const app = express();
app.get("/api/hadith/random", (_, res) => res.json(muslim.getRandom()));
app.get("/api/hadith/:id", (req, res) => {
const h = muslim.get(parseInt(req.params.id));
h ? res.json(h) : res.status(404).json({ error: "Not found" });
});
app.get("/api/search", (req, res) =>
res.json(muslim.search(req.query.q || "")),
);
app.get("/api/chapter/:id", (req, res) =>
res.json(muslim.getByChapter(parseInt(req.params.id))),
);
app.listen(3000, () => console.log("Running on :3000"));
🔧 Development
git clone https://github.com/SENODROOM/sahih-muslim.git
cd sahih-muslim
npm install
# Regenerate chapters/ from bin/muslim.json
node build.mjs
# Publish to npm
npm publish
# Publish to PyPI
pip install build twine
python -m build
python -m twine upload dist/*
🤝 Contributing
Contributions are welcome!
- Fork the repository
- Create a branch:
git checkout -b feature/my-feature - Commit:
git commit -m 'Add my feature' - Push:
git push origin feature/my-feature - Open a Pull Request
📄 License
Licensed under the GNU Affero General Public License v3.0 (AGPL-3.0) — see LICENSE for details.
🙏 Acknowledgments
- 📖 Source — Sahih Muslim, one of the most authentic hadith collections in Islam
- 👨🏫 Translations — By reputable Islamic scholars
- 💚 Inspiration — The global Muslim community seeking knowledge
Metadata
Release files for sahih-muslim 1.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sahih_muslim-1.1.2.tar.gz | 2.3 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sahih_muslim-1.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 4.7 MB
Release files / sahih_muslim-1.1.2.tar.gz
| Download URL | sahih_muslim-1.1.2.tar.gz |
|---|---|
| Size | 2.3 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3bb1db5601d63adee49a85ffdd1ca1b516c901d6d474a3477aa58b75e72fe885
|
|
BLAKE2b-256 checksum How to use checksums |
f012a41f321e745ac7cee92a5185451c6e5ff70f420f62a05b86d8ab06e86e26
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / sahih_muslim-1.1.2-py3-none-any.whl
| Download URL | sahih_muslim-1.1.2-py3-none-any.whl |
|---|---|
| Size | 2.3 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d962f014bf77dcb27fd936ee86c9c02673bb1e9eb87bc2d422d3ffc7e5701b51
|
|
BLAKE2b-256 checksum How to use checksums |
95b0cee0463ec032f8ab6dbe44f64cc0e02ba6b3dc4bd97e6fd10c74cb333388
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|