
Tiny, dependency-free FSRS-5 implementation: pure, side-effect-free scheduler returning next memory state and interval from elapsed days and rating; configurable parameters and test-verified math.
A tiny, dependency-free Kotlin Multiplatform implementation of FSRS-5 (Free Spaced Repetition Scheduler) — the modern, open scheduling algorithm behind Anki's FSRS and many spaced-repetition apps.
commonMain pulls in nothing but the Kotlin stdlib.R(S, S) = 0.9,
interval at 0.9 retention = S), not hand-copied magic numbers.// settings.gradle.kts → dependencyResolutionManagement { repositories { mavenCentral() } }
dependencies {
implementation("ru.lorddarthart.fsrs:fsrs:0.1.0")
}import ru.lorddarthart.fsrs.Fsrs
import ru.lorddarthart.fsrs.Rating
val fsrs = Fsrs() // default weights + 0.9 desired retention
// First review of a brand-new card:
val first = fsrs.review(current = null, rating = Rating.Good)
println(first.memory) // MemoryState(stability=…, difficulty=…)
println(first.intervalDays) // days until it's next due
// A later review, given how many days actually elapsed:
val next = fsrs.review(current = first.memory, rating = Rating.Again, elapsedDays = 12.0)| Type | What it is |
|---|---|
Fsrs(parameters, desiredRetention) |
The scheduler. Everything is a pure function of its inputs. |
Rating |
Again / Hard / Good / Easy (the grade a learner gives). |
MemoryState(stability, difficulty) |
The two latent variables FSRS tracks per card. |
SchedulingResult(memory, intervalDays) |
What review(...) returns. |
FsrsParameters |
The 19 FSRS-5 weights; FsrsParameters.Default are the community defaults. |
fsrs.retrievability(elapsedDays, stability) and fsrs.nextInterval(stability) are
exposed too if you need the raw forgetting curve.
FSRS-5 with the power forgetting curve R(t, S) = (1 + FACTOR · t / S) ^ DECAY
(DECAY = -0.5, FACTOR = 19/81, so stability S is by definition the number of
days until retrievability decays to 90%). Difficulty uses FSRS-5 linear damping and
mean reversion; stability grows on recall and shrinks on lapse.
A tiny, dependency-free Kotlin Multiplatform implementation of FSRS-5 (Free Spaced Repetition Scheduler) — the modern, open scheduling algorithm behind Anki's FSRS and many spaced-repetition apps.
commonMain pulls in nothing but the Kotlin stdlib.R(S, S) = 0.9,
interval at 0.9 retention = S), not hand-copied magic numbers.// settings.gradle.kts → dependencyResolutionManagement { repositories { mavenCentral() } }
dependencies {
implementation("ru.lorddarthart.fsrs:fsrs:0.1.0")
}import ru.lorddarthart.fsrs.Fsrs
import ru.lorddarthart.fsrs.Rating
val fsrs = Fsrs() // default weights + 0.9 desired retention
// First review of a brand-new card:
val first = fsrs.review(current = null, rating = Rating.Good)
println(first.memory) // MemoryState(stability=…, difficulty=…)
println(first.intervalDays) // days until it's next due
// A later review, given how many days actually elapsed:
val next = fsrs.review(current = first.memory, rating = Rating.Again, elapsedDays = 12.0)| Type | What it is |
|---|---|
Fsrs(parameters, desiredRetention) |
The scheduler. Everything is a pure function of its inputs. |
Rating |
Again / Hard / Good / Easy (the grade a learner gives). |
MemoryState(stability, difficulty) |
The two latent variables FSRS tracks per card. |
SchedulingResult(memory, intervalDays) |
What review(...) returns. |
FsrsParameters |
The 19 FSRS-5 weights; FsrsParameters.Default are the community defaults. |
fsrs.retrievability(elapsedDays, stability) and fsrs.nextInterval(stability) are
exposed too if you need the raw forgetting curve.
FSRS-5 with the power forgetting curve R(t, S) = (1 + FACTOR · t / S) ^ DECAY
(DECAY = -0.5, FACTOR = 19/81, so stability S is by definition the number of
days until retrievability decays to 90%). Difficulty uses FSRS-5 linear damping and
mean reversion; stability grows on recall and shrinks on lapse.