What a page costs
The image is the cost. The text reply is one to two percent of it.
Images 40,445 to 125,578 bytes; text replies 692 to 1,393 bytes compressed, over four sampled pages.
A Quran reader for the web that shows the printed Mushaf itself: 604 page images, every ayah on them tappable, and pages that turn like a book.
A printed Mushaf is read by the page, so the reader shows the page by default rather than reflowed text, and does the work around it. It knows where every ayah sits on each image, turns pages without losing your place, and checks what is already in the browser before asking anyone else.
Plays the six stages below in order, about 55 seconds. Scroll or press Esc to stop.
Real output from the live site, October 2026. The tap session runs the reader's own hit-test code offline on the bundled geometry; the tap positions are illustrative.
Every way into the reader ends at the same address, /tabs/mushaf/page/n, with n from 1 to 604. The index, the search results, bookmarks and shared links all resolve to a page number first.
604 pages, 30 juz, one route
30 of 30 juz start pages match the bundled geometry
/tabs/mushaf/page/582Table lookup, no request/tabs/mushaf/page/300Inside 1 to 604, opensno changeOutside 1 to 604, the dialog just closes/tabs/mushaf/page/2Titled on the server: البقرة - صفحة 2The page is a picture, so the reader carries a map of it: one box per ayah per line, in the image's own 1260 px coordinates. The map loads once, when you first open a page in image view, and is used every time you tap.
Ayah keys like 1:7 stand in for the text here; the real page image carries the words.
Taps against the bundled geometry Illustrative input
Tap or click the page to run the same test.
ayahinfo.json. The hit test and the highlight maths are the reader's own, copied verbatim and run in this page, with page images taken as 1260 by 2038 px, the size measured on four sampled live pages. Tap positions are illustrative; the first four match an offline run of the same code.On a wide screen the reader shows two pages at once, paired as in print: the odd page on the right, the even page on the left. Open an even page and its odd partner becomes the main page.
replaceState, so turning pages adds no history entries and the URL always points at the page on screen.Side view of a turn from pages 3 and 4 Illustrative input
/tabs/mushaf/page/3Drag across the book to turn the page.
Before a text request leaves the browser, the reader's service worker looks in its own cache. A reply it already holds is served from there, with no network at all. Only a miss goes out to alquran.cloud.
performance: a cached reply up to 30 days old wins. Older ones are dropped and fetched again.The text cache through a reading session Illustrative input
/v1/page/1/quran-uthmaniSingle-page view: read pages 1 to 110 in order, go back to page 105, then back to page 4.
performance, 100 entries, 30 days, least recently used out first. On the live site, opening page 1 and pressing next left exactly two entries, /v1/page/1/quran-uthmani and /v1/page/2/quran-uthmani.Not in this browserAbove this line is what ships with the app or is already cached. Below it, the reader asks third parties: alquran.cloud for the text, quran.com's CDN for the page image.
One request per page, for the Uthmani text of exactly the ayahs on it. In two-page view, a second request fetches the facing page.
The reply, and what the reader keeps
GET api.alquran.cloud/v1/page/2/quran-uthmani
Failed to load pageand a Retry button
The page image is the default view: page001.png to page604.png, 1260 px wide, from quran.com's CDN, which serves them from its Hafs Madani set. The ayah boxes from stage 2 sit on top as highlights.
Page 1 opened on three screens, with ayah 1:7 highlighted Illustrative input
The repo documents no benchmarks. These are byte counts from the live site, its two third-party sources and the bundled data, taken in October 2026.
The image is the cost. The text reply is one to two percent of it.
Images 40,445 to 125,578 bytes; text replies 692 to 1,393 bytes compressed, over four sampled pages.
The geometry for all 604 pages is one JSON file, fetched once and kept.
346,322 bytes, sent as 121,179 with brotli. The service worker also prefetches the 95 files of the app shell.
The page list is prerendered. Each page is rendered on the server when asked, so a shared link arrives titled, with its own preview image.
A rendered page is about 40.5 kB of HTML. If server rendering takes over 10 seconds, the server sends the client-rendered shell instead.
/tabs/mushaf/page/1 to /tabs/mushaf/page/604.A first visit starts with a short welcome screen.