Skip to main content

Overview

Open Mushaf Native provides instant access to authentic Tafseer (Quranic commentary) from renowned Islamic scholars. Simply tap any verse to view its explanation in a bottom sheet popup with multiple commentary sources.

Available Commentaries

The app includes 11 comprehensive Tafseer sources:

تفسير ابن كثير

Ibn Katheer - Classical Tafseer focusing on authentic narrations

تفسير الطبري

Al-Tabari - Comprehensive early Tafseer with historical context

تفسير القرطبي

Al-Qurtubi - Focus on legal rulings and jurisprudence

تفسير السعدي

As-Sa’di - Modern, concise, and clear explanations

التفسير الميسر

Al-Muyassar - Simplified Tafseer for easy understanding

تفسير البغوي

Al-Baghawi - Moderate approach between narration and reasoning

معاني القرآن

Meanings of the Quran - Linguistic and grammatical explanations

إعراب القرآن

Quranic Grammar - Detailed grammatical analysis

أسباب النزول

Asbab an-Nuzul (Al-Wahidi) - Reasons and context of revelation

التحرير والتنوير

At-Tahrir wa At-Tanwir - Modern comprehensive commentary

الوسيط

Al-Waseet - Moderate middle-ground approach

How to Use Tafseer

1

Tap a Verse

Touch any verse on the Mushaf page to open the Tafseer popup
2

View Commentary

The bottom sheet displays the commentary for that specific verse
3

Switch Sources

Tap different tabs to switch between various Tafseer sources
4

Resize Sheet

Drag the handle to resize the popup (40%, 70%, or 90% screen height)
5

Close

Swipe down or tap the backdrop to close the Tafseer

Tafseer Popup Component

Bottom Sheet Implementation

components/TafseerPopup.tsx
<BottomSheet
  ref={bottomSheetRef}
  index={1}
  snapPoints={['40%', '70%', '90%']}
  onChange={handleSheetChange}
  backdropComponent={renderBackdrop}
  handleComponent={renderHandle}
  enablePanDownToClose
  backgroundStyle={{ backgroundColor }}
>
  <BottomSheetScrollView>
    <Tafseer aya={aya} surah={surah} opacity={opacity} />
  </BottomSheetScrollView>
</BottomSheet>
The popup opens at 70% height by default and can be resized to 40% or 90% by dragging the handle.

Tafseer Tab System

Tab Labels

components/Tafseer.tsx
const tabLabels: Partial<Record<TafseerTabs, string>> = {
  katheer: 'إبن كثير',
  maany: 'معاني القرآن',
  earab: 'إعراب القرآن',
  baghawy: 'البغوي',
  muyassar: 'الميسر',
  qortoby: 'القرطبي',
  tabary: 'الطبري',
  saady: 'السعدي',
  wahidy: 'أسباب النزول',
  tanweer: 'التحرير و التنوير',
  waseet: 'الوسيط',
};

Dynamic Tab Loading

The app intelligently loads Tafseer content:
components/Tafseer.tsx
switch (selectedTabValue) {
  case 'baghawy':
    tafseerJSON = await import('@/assets/tafaseer/baghawy.json');
    break;
  case 'katheer':
    tafseerJSON = await import('@/assets/tafaseer/katheer.json');
    break;
  case 'saady':
    tafseerJSON = await import('@/assets/tafaseer/saady.json');
    break;
  // ... more cases
}
Tafseer data is loaded on-demand only when you select a tab, reducing initial app load time.

Content Availability

Smart Tab Indicators

Not all Tafseers contain commentary for every verse. The app shows which sources have content:
const hasContent = !hasNoTafseerContent({
  tafseerData: data,
  surah,
  aya,
});

setTabsWithContent((prev) => ({
  ...prev,
  [tab]: hasContent,
}));
Tabs without content appear:
  • Dimmed (opacity: 0.5)
  • With strikethrough text decoration
Some Tafseer sources don’t provide commentary for certain verses, particularly short verses or specific types of content. This is normal and reflects the original scholarly works.

Tafseer Content Hook

Formatting HTML

hooks/useTafseerContent.ts
export function useTafseerContent({
  tafseerData,
  surah,
  aya,
}: UseFormattedTafseerParams): string {
  const ayaTafseer = tafseerData?.find(
    (t) => t.sura === surah && t.aya === aya,
  );

  let tafseerText = '';
  if (!ayaTafseer?.text || ayaTafseer?.text === '<p></p>') {
    tafseerText = '<p>لا يوجد تفسير.</p>';
  } else {
    tafseerText = `<div>${ayaTafseer.text}</div>`;
  }
  return tafseerText;
}

Checking Content Availability

export function hasNoTafseerContent({
  tafseerData,
  surah,
  aya,
}: UseFormattedTafseerParams): boolean {
  const ayaTafseer = tafseerData?.find(
    (t) => t.sura === surah && t.aya === aya,
  );

  if (
    !ayaTafseer?.text ||
    ayaTafseer.text.trim() === '' ||
    ayaTafseer.text === '<p></p>'
  ) {
    return true; // No tafseer content
  }
  return false; // Tafseer content exists
}

Persistent Selection

Your last selected Tafseer tab is remembered:
jotai/atoms.ts
export const tafseerTab = createAtomWithStorage<TafseerTabs>(
  'TafseerTab',
  'katheer', // Default to Ibn Katheer
);
The app remembers your preferred Tafseer source across sessions, opening the same tab next time.

Styling and Display

HTML Rendering

Tafseer content uses HTMLView for proper Arabic text rendering:
<HTMLView
  value={formattedTafseerHtml}
  stylesheet={{
    div: {
      color: textColor,
      fontFamily: 'Tajawal_400Regular',
      fontSize: 16,
      lineHeight: 24,
    },
    p: {
      color: textColor,
      fontFamily: 'Tajawal_400Regular',
      fontSize: 16,
      lineHeight: 24,
    },
  }}
/>

Visual Features

  • Right-to-left text direction for Arabic
  • Custom Arabic font (Tajawal)
  • Optimized line height for readability
  • Theme-aware text colors
  • Smooth scrolling for long commentaries

Performance Optimization

Lazy Loading

Tafseer files are only loaded when their tab is selected

Content Checking

Pre-checks all sources to show which have content before you click

Opacity Animation

Smooth opacity transition during sheet resizing for better UX

Mounted State

Prevents memory leaks when switching verses quickly

Build docs developers (and LLMs) love