lmscn

Spaced Repetition

An SM-2 spaced-repetition review session with self-grading and computed next intervals.

Installation

npx shadcn@latest add https://lmscn.vercel.app/r/spaced-repetition.json

Required primitives: button, badge, card, progress

npx shadcn@latest add button badge card progress

Usage

import { SpacedRepetition } from "@/components/lms/spaced-repetition"
import type { SpacedRepetitionData, SpacedRepetitionResult } from "@/components/lms/spaced-repetition"

export function MySR() {
  return (
    <SpacedRepetition
      spacedRepetitionData={{
        title: "French Review",
        description: "Cards due today",
        totalCards: 120,
        dueCards: [
          { id: "1", front: "bonjour",   back: "hello",     interval: 3,  easeFactor: 2.5 },
          { id: "2", front: "merci",     back: "thank you", interval: 7,  easeFactor: 2.8 },
          { id: "3", front: "au revoir", back: "goodbye",   interval: 1,  easeFactor: 2.1 },
        ],
      }}
      onComplete={(result: SpacedRepetitionResult) => {
        // Persist result.sessions to your backend to update each card's schedule
        console.log(result.sessions)
      }}
    />
  )
}

Props

SpacedRepetitionProps

PropTypeRequiredDescription
spacedRepetitionDataSpacedRepetitionDataSession and card configuration
onComplete(result: SpacedRepetitionResult) => voidCalled after all due cards are graded
classNamestringAdditional CSS classes

Data shape

SpacedRepetitionData

FieldTypeDescription
titlestringSession title
descriptionstringSubtitle
dueCardsReviewCard[]Cards to review in this session
totalCardsnumberTotal deck size — shown as context in the header

ReviewCard

FieldTypeDescription
idstringUnique identifier
frontstringQuestion / prompt side
backstringAnswer side
tagsstring[]Category badges shown on the front face
nextReviewDatestringISO date string of the scheduled review (display only)
intervalnumberCurrent interval in days — used as input to the SM-2 algorithm
easeFactornumberSM-2 ease factor — defaults to 2.5 if omitted

Result

onComplete receives a SpacedRepetitionResult object:

FieldTypeDescription
sessionsReviewSession[]Per-card review records with computed scheduling data
hardCardIdsstring[]IDs of cards graded below 3 (need re-study)
interface ReviewSession {
  cardId: string
  grade: ReviewGrade       // the grade the learner chose
  nextInterval: number     // computed next interval in days
  nextEaseFactor: number   // updated ease factor
}

Persist nextInterval and nextEaseFactor to your database and schedule the card's next review as today + nextInterval days.

Grading scale

The component uses a simplified 4-button interface that maps to SM-2 quality values:

ButtonSM-2 gradeMeaning
Again1Complete blackout
Hard2Difficult recall
Good3Correct with effort
Easy4Recalled easily

Grade buttons are only shown after the card is flipped.

SM-2 algorithm

The interval and ease factor are computed with the standard SM-2 formula:

  • Grades < 3: interval resets to 1 day, ease factor decreases by 0.2 (minimum 1.3).
  • Grade 3+: interval grows by prev × easeFactor (first two repetitions use fixed intervals of 1 and 6 days).
  • Ease factor adjusts after every grade: it increases for easy responses and decreases for difficult ones.

ReviewGrade is typed as 0 | 1 | 2 | 3 | 4 | 5 to match the full SM-2 spec, though the UI currently exposes grades 1–4.

On this page