ts-fsrs 6.0.0
Published: 2026-10-28 14:10:26 UTC
This is a major update with breaking changes. ts-fsrs v6 introduces FSRS-7, the default model for DefaultScheduler; see the quick start to get started. For existing integrations, we recommend following the migration guide and using llms.txt as the documentation entry point for AI-assisted migration.
Breaking Changes
- Change
FSRSVersionfromv${version} using FSRS-6.0tov${version}. This export remains supported and reports only the package version; update code that parses the old suffix. Read the selected model name fromscheduler.definition.model.name. (#576) Thanks @ishiko732! - Move algorithm operations to explicit model entries. Import models and parameter helpers from
ts-fsrs/models/fsrs-3,fsrs-4,fsrs-4dot5,fsrs-5,fsrs-6, orfsrs-7. The rootFSRSAlgorithm,computeDecayFactor,clipParameters,migrateParameters, andforgetting_curveexports and the legacy facade'snext_state,next_interval, andget_retrievabilitymethods are removed. The inherited algorithm API, includinginterval_modifier,calculate_interval_modifier,apply_fuzz, and theseedsetter, is no longer available onFSRS. Use modelstep,nextInterval,forgettingCurve, andforward;retrievabilityreturns a number, so format percentages at the call site.FSRS,IFSRS, andfsrs()remain exported but deprecated and use FSRS-6. (#377, #375, #356) Thanks @ishiko732! - Remove
afterHandlercallbacks fromcreateEmptyCard,repeat,next,rollback, andforget, and removerecordLogHandlerfrom legacyreschedule. Transform returned results at the call site. (#374) Thanks @ishiko732 and @Copilot! - Remove global
Date.prototypeextensions and deprecatedfixDate,fixState, andfixRatinghelpers. Use standalone date helpers andTypeConvert.time/state/ratingfor legacy integrations. RemoveCard.elapsed_daysandReviewLog.elapsed_days/last_elapsed_days; derive elapsed time from actual review timestamps, not the scheduled due date. (#341, #342) Thanks @ishiko732! - Replace Alea with FNV-1a and Mulberry32, changing fuzzed interval sequences. The new scheduler seeds fuzzing with
cardId + reps; the legacy scheduler still derives its seed from review time, repetition count, difficulty, and stability. RemoveDefaultInitSeedStrategy,GenSeedStrategyWithCardId,StrategyMode.SEED, andTSeedStrategy. UseschedulerFuzzingMiddlewareorcreateSchedulerFuzzingMiddleware({ fuzzingRange, rng }). (#409) Thanks @ishiko732! - Require Node.js 24 or later. (#406) Thanks @ishiko732!
- Replace
BasicLearningStepsStrategywithcalculateLearningStepsandTLearningStepsStrategywithLearningStepsResolver. CustomStrategyMode.LEARNING_STEPShandlers now receive camelCaselearningSteps/relearningStepsconfig and returnscheduledMinutes/nextStepinstead ofscheduled_minutes/next_step. Replacedefault_learning_stepsanddefault_relearning_stepsimports withdefaultLearningStepsanddefaultRelearningSteps. (#407) Thanks @ishiko732! - Replace the numeric TypeScript enums
RatingandStatewith frozen constant objects and numeric union types. Numeric values remain unchanged, but reverse lookups such asRating[3]andState[2]no longer work; replace enum-member type annotations such asRating.Goodwithtypeof Rating.Good. (#457) Thanks @ishiko732! - Rename
FSRSReview.delta_ttodeltaTand narrow itsratingtoGrade(Again through Easy, excluding Manual). Custom legacy schedulers now receive(card, now, model, parameters, strategies)instead of(card, now, algorithm, strategies); subclasses must use the model and separate parameters rather thanthis.algorithm. (#377) Thanks @ishiko732! - Change declaration files from
dist/index.d.tsto format-specific.d.mts/.d.ctsfiles and remove theumdpackage-export condition. Use package imports for declaration resolution and update tooling that hard-codes the old declaration path; the UMD bundle is still built. (#346) Thanks @ishiko732!
Deprecations
- Add explicit
@deprecatedannotations and replacement guidance to legacy card/parameter helpers,AbstractScheduler, strategy APIs,FSRS/IFSRSmembers, and legacy card, review-log, config, and scheduling types. These exports remain available for compatibility. UseDefaultSchedulerordefineScheduler, model-specific parameter helpers, inferred scheduler types, andReschedulefromts-fsrs/reschedulefor new integrations. (#576) Thanks @ishiko732! - Deprecate
TypeConvertand its methods, legacy date helpers,Grades, andCLAMP_PARAMETERS. Use explicit input conversion and schemas, the selected scheduler's chrono, application-level date formatting,gradesfrom srs-kit, and model-specific parameter helpers. Replacements are not universally interchangeable: preserve date units, rounding, output formats, and the New-card retrievability boundary when migrating. (#576) Thanks @ishiko732!
New Features
- Add the asynchronous
DefaultScheduler(options)factory backed by@open-spaced-repetition/srs-kit. It defaults to FSRS-7; selectversion: 'FSRS-6'to retain the previous model. The new API usesnewCard,preview,review,rollback,forget,retrievability, andnextInterval, with camelCase card/config fields and{ card, revlog }review results. (#451, #531, #526) Thanks @ishiko732! - Add FSRS-3, FSRS-4, FSRS-4.5, FSRS-5, and FSRS-7 model entries alongside FSRS-6. FSRS-7 uses 34 weights, a
stabilityFastmemory field, and fractional-day intervals. Its standalonecurvereturns retrievability and total mixture weight; parameter bounds are also exported. (#401, #400, #399, #378, #520, #541, #556) Thanks @ishiko732! - Expose
defineModel,defineScheduler,defineChrono,defineMiddleware, chrono presets, scheduling schemas, and srs-kit types for custom integrations. Built-in middleware is available from the root andts-fsrs/middlewares, including desired retention, fuzzing, statistics, scheduled days, learning steps, maximum/monotonic intervals, leech suspension, and Cost ADR. Leech suspension usesscheduleStatus: 'suspended'; Cost ADR and leech middleware are opt-in. (#445, #469, #509, #539, #412, #461, #528) Thanks @ishiko732! - Support per-grade desired retention and direct
nextIntervalqueries through interval middleware. AddgraduatingIntervalandallowModelOverrideto learning-step scheduling.DefaultSchedulerdefaults to learning steps['1m', '10m'], relearning steps['10m'], and model override enabled only for FSRS-7. Disabling explicit learning steps does not disable FSRS-7's intrinsic fast trace. (#527, #526, #561) Thanks @ishiko732! - Add
Rescheduleatts-fsrs/reschedulefor replaying review history into memory states or rescheduling cards and review logs. (#426, #439) Thanks @ishiko732 and @Eijnewgnaw! - Separate parameter migration, clipping, and validation, and accept readonly parameter arrays. (#398, #492, #515) Thanks @ishiko732 and @Luc-Mcgrady!
Fixes
- Enforce maximum intervals independently of fuzzing, preserve explicit learning steps and second precision, and keep graduation intervals monotonic. Correct FSRS-7 sub-day scheduling states. (#454, #456, #484, #540) Thanks @ishiko732!
- Clamp FSRS-4.5 through FSRS-6 initial stability to configured bounds, and validate numeric bounds and learning-step inputs. (#477, #549) Thanks @ishiko732!
- Preserve pre-review chronology during rollback, improve inferred card/revlog type displays, and avoid redundant interval calculations. (#522, #473, #443) Thanks @ishiko732!
Build and Tooling
- Replace Rollup/esbuild with tsdown (Rolldown), and stop emitting source maps and minified bundles. (#346) Thanks @ishiko732!
- Add the build-time
TS_FSRS_DISABLE_ROUNDINGswitch for custom builds. Published builds keep rounding enabled; this is not a runtime environment setting. (#547) Thanks @ishiko732! - Migrate the repository's root TypeScript toolchain to TypeScript 7 (tsgo).
srs-kitretains its package-local TypeScript 6 development dependency. This is a development-toolchain change, not a new TypeScript 7 requirement for consumers. (#403) Thanks @zi-gae!
Migration
Upgrading the package and upgrading the model are separate operations. Keep FSRS-6 explicitly when migrating an existing FSRS-6 integration. To move learned cards to FSRS-7, use FSRS-7 weights and rebuild memory from complete review history since creation or the latest memory reset; do not reuse FSRS-6 weights or invent stabilityFast. Select the post-reset history explicitly: replay() filters Manual records but does not interpret reset events. Use Reschedule.replay() to rebuild memory while preserving existing due dates, learning progress, counters, and historical logs; reschedule() instead replays scheduling policy and can change the schedule. The new scheduler's forget clears statistics by default; set clearStatsOnForget: false when those statistics must be retained.
When adopting the new scheduler, migrate due/last_review to dueAt/lastReviewAt, learning_steps to learningStep, and { card, log } to { card, revlog }; persist scheduleStatus and retain a stable cardId. Date-based inputs require valid Date objects after deserialization. Review logs distinguish the pre-review lastReviewAt, pre-review dueAt, and actual reviewTime; do not blindly rename old log.due or use old-model logs for FSRS-7 rollback. Learned cards without complete history must remain on FSRS-6 rather than receiving an invented FSRS-7 state.
See the v6 and FSRS-7 migration guide for card/config mappings and rollback timestamp requirements. (#543) Thanks @ishiko732!