R bindings for fsrs-rs, the Rust implementation of the Free Spaced Repetition Scheduler (FSRS) algorithm.
FSRS is a modern spaced repetition algorithm based on the DSR (Difficulty, Stability, Retrievability) model of memory. It uses 21 optimizable parameters to predict optimal review intervals more accurately than traditional algorithms like SM-2.
- Full FSRS-6 implementation via Rust bindings
- Parameter optimization — train custom parameters from your review history
- SM-2 migration — convert from Anki's default algorithm
- High performance — Rust-powered core with R6 convenience classes
# Install Rust first: https://rustup.rs
# From GitHub
remotes::install_github("open-spaced-repetition/r-fsrs")
# From r-universe
install.packages("rfsrs", repos = "https://chrislongros.r-universe.dev")library(rfsrs)
# Create a scheduler
scheduler <- Scheduler$new(desired_retention = 0.9)
# Create and review a card
card <- Card$new()
result <- scheduler$review_card(card, Rating$Good)
print(card)Train custom parameters from your review history for better scheduling accuracy:
# Prepare your review data
reviews <- data.frame(
card_id = c(1, 1, 1, 2, 2, 2, ...),
rating = c(3, 3, 4, 2, 3, 3, ...), # 1=Again, 2=Hard, 3=Good, 4=Easy
delta_t = c(0, 1, 3, 0, 2, 5, ...) # Days since previous review
)
# Optimize parameters
result <- fsrs_optimize(reviews)
if (result$success) {
# Use optimized parameters
my_scheduler <- Scheduler$new(parameters = result$parameters)
}# With the ankiR package
library(ankiR)
revlog <- anki_revlog() # auto-detects the default profile
reviews <- fsrs_anki_to_reviews(revlog)
# Optimize
result <- fsrs_optimize(reviews)
# Compare accuracy
default_metrics <- fsrs_evaluate(reviews, NULL)
custom_metrics <- fsrs_evaluate(reviews, result$parameters)
cat("Default log_loss:", default_metrics$log_loss, "\n")
cat("Custom log_loss:", custom_metrics$log_loss, "\n")scheduler <- Scheduler$new(
parameters = NULL, # Custom params or NULL for defaults
desired_retention = 0.9, # Target recall probability
maximum_interval = 36500, # Max days between reviews
enable_fuzzing = FALSE # Add randomness to intervals
)
scheduler$review_card(card, rating) # Review and update card
scheduler$preview_card(card) # Preview all 4 outcomes
scheduler$get_card_retrievability(card) # Current recall probabilitycard <- Card$new()
card$stability # Days until 90% recall
card$difficulty # Learning difficulty (1-10)
card$state # New/Learning/Review/Relearning
card$get_retrievability()
card$clone_card()| Function | Description |
|---|---|
fsrs_optimize(reviews) |
Train custom parameters from review history |
fsrs_evaluate(reviews, params) |
Evaluate parameter accuracy |
fsrs_anki_to_reviews(revlog) |
Convert Anki revlog to required format |
| Function | Description |
|---|---|
fsrs_parameters() |
Get 21 default FSRS-6 parameters |
fsrs_new_card_state(rating, params) |
Initial state for a new card |
fsrs_next_memory_state(S, D, elapsed, rating, retention, params) |
State after a review |
fsrs_interval(S, retention, params) |
Optimal next-review interval |
fsrs_recall_probability(S, elapsed) |
Recall probability (scalar) |
fsrs_recall_probability_vec(S, elapsed) |
Recall probability (vectorized) |
fsrs_migrate_sm2(ease, interval, retention, params) |
Convert an SM-2 card to FSRS |
fsrs_simulate(ratings, params, retention) |
Step through a rating sequence |
fsrs_version() |
Algorithm version string |
These are validated R wrappers around Rust. The underlying unchecked
bindings (rfsrs:::fsrs_*_raw) are internal and not a stable API.
FSRS models memory with three variables:
- Stability (S): Days until recall probability drops to 90%
- Difficulty (D): How hard the material is (1-10)
- Retrievability (R): Current probability of recall
Forgetting curve (as implemented in fsrs-rs):
factor = 0.9^(1/-decay) - 1
R(t) = (1 + factor · t/S)^(-decay)
decay is the 21st parameter. With FSRS-6 defaults (decay = 0.1542)
factor ≈ 0.9804; with FSRS-5 defaults (decay = 0.5) factor ≈ 0.2346.
Either way R(S) = 0.9, i.e. stability is the interval at which recall
falls to 90%.
MIT © 2026 Christos Longros
Based on fsrs-rs by the Open Spaced Repetition project.