For AI agents: the complete documentation index is available at https://open-spaced-repetition.github.io/ts-fsrs/ja-JP/llms.txt, the full documentation bundle is available at https://open-spaced-repetition.github.io/ts-fsrs/ja-JP/llms-full.txt, and this page is available as Markdown at https://open-spaced-repetition.github.io/ts-fsrs/ja-JP/index.md.
ts-fsrs
間隔反復を、自由に組み立てる。

TypeScript のための型安全なスケジューラーフレームワーク。FSRS-7 から始めて、API ファミリーを切り替えることなく、モデル・クロノ・ミドルウェアを組み合わせられます。

npm
yarn
pnpm
bun
deno
npm install ts-fsrs
import { 
function DefaultScheduler<Version extends DefaultSchedulerVersion = "FSRS-7">(options?: DefaultSchedulerOptions<Version>): Promise<DefaultScheduler<Version>>
type DefaultScheduler<Version extends DefaultSchedulerVersion = "FSRS-7"> = (Version extends "FSRS-7" ? Omit<SchedulerCore<SchedulerCoreEnv<SchedulerEnvFor<FSRS7DefaultSchedulerModel, Chrono<{
    readonly time: SRSSchema<{
        input: Date;
        output: Date;
    }>;
    readonly config: SRSSchema<{
        input: {
            readonly fractionalDays?: boolean | undefined;
        };
        output: {
            readonly fractionalDays: boolean;
        };
    }>;
    readonly fields: {
        readonly card: SRSSchema<{
            input: {
                dueAt: Date;
                lastReviewAt?: (Date | null) | undefined;
            };
            output: {
                dueAt: Date;
                lastReviewAt: Date | null;
            };
        }>;
        readonly revlog: SRSSchema<{
            input: {
                dueAt: Date;
                lastReviewAt?: (Date | null) | undefined;
                reviewTime: Date;
            };
            output: {
                dueAt: Date;
                lastReviewAt: Date | null;
                reviewTime: Date;
            };
        }>;
    };
}>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>, "definition"> : Omit<...> & {
    ...;
}) & {
    ...;
}
DefaultScheduler
} from 'ts-fsrs'
const createdAt = new Date('2026-01-01T00:00:00.000Z') export const now = new Date('2026-01-02T09:30:00.000Z') export const
const scheduler: DefaultScheduler<"FSRS-7">
scheduler
= await
DefaultScheduler<"FSRS-7">(options?: DefaultSchedulerOptions<"FSRS-7"> | undefined): Promise<DefaultScheduler<"FSRS-7">>
DefaultScheduler
({
DefaultSchedulerOptions<Version extends DefaultSchedulerVersion = DefaultSchedulerVersion>.desiredRetention?: number | undefined
desiredRetention
: 0.9,
}) export const
const card: {
    cardId: string | number;
    stabilityFast: number;
    stability: number;
    difficulty: number;
    dueAt: Date;
    lastReviewAt: Date | null;
    reps: number;
    lapses: number;
    scheduledDays: number;
    learningStep: number;
    state: State;
    scheduleStatus: "review" | "new" | "learning";
}
card
=
const scheduler: DefaultScheduler<"FSRS-7">
scheduler
.
newCard: (options?: ({
    readonly cardId?: string | number | undefined;
} & {
    readonly now?: Date | undefined;
}) | undefined) => {
    cardId: string | number;
    stabilityFast: number;
    stability: number;
    difficulty: number;
    dueAt: Date;
    lastReviewAt: Date | null;
    reps: number;
    lapses: number;
    scheduledDays: number;
    learningStep: number;
    state: State;
    scheduleStatus: "review" | "new" | "learning";
}
newCard
({
cardId: 'landing-demo', now: createdAt, }) // One `{ grade, card, revlog }` row per grade — the panel renders exactly this. export const
const outcomes: PreviewResult<{
    card: {
        cardId: string | number;
        stabilityFast: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        reps: number;
        lapses: number;
        scheduledDays: number;
        learningStep: number;
        state: State;
        scheduleStatus: "review" | "new" | "learning";
    };
    revlog: {
        cardId: string | number;
        stabilityFast: number;
        stability: number;
        difficulty: number;
        dueAt: Date;
        lastReviewAt: Date | null;
        scheduledDays: number;
        learningStep: number;
        reviewTime: Date;
        state: State;
        scheduleStatus: "review" | "new" | "learning";
        rating: Grade;
    };
}>
outcomes
=
const scheduler: DefaultScheduler<"FSRS-7">
scheduler
.
preview: (input: {
    readonly card: Readonly<Omit<Readonly<{
        stabilityFast: number;
        stability: number;
        difficulty: number;
    } & {
        dueAt: Date;
        lastReviewAt: Date | null;
    } & {
        readonly cardId: string | number;
        readonly reps: number;
        readonly lapses: number;
        readonly scheduledDays: number;
        readonly learningStep?: number | undefined;
    } & SchedulerCoreFields$1<"review" | "new" | "learning">>, keyof SchedulerCoreFields$1<"review" | "new" | "learning">> & SchedulerCoreFields$1<"review" | "new" | "learning">>;
    readonly now?: Date | undefined;
}) => PreviewResult<...>
preview
({ card, now })
安定度
3.9221
難易度
3.5307
stabilityFast
3.13768

設計から型安全

一つのスキーマが実行時の検証と入力・出力の型推論を同時に担います。

移行なしで組み替えられる

デフォルトのスケジューラーから始め、同じコアの上でモデル・クロノ・ポリシーを差し替えられます。

遅延評価を前提に設計

遅延プレビュー、バージョン単位のコード分割、tree-shaking 可能なサブパスエクスポート。

段階的な API

まずはシンプルに。拡張しても作り直しは不要。

デフォルトの FSRS スケジューラーをそのまま使うことも、独自のスケジューリング方針を組み立てることも、新しいモデルを実装することも、すべて同じコアの上でできます。

01

使う

DefaultScheduler は適切なデフォルト値を備えた FSRS スケジューラーです。FSRS-3 から FSRS-7 までをサポートし、デフォルトでは FSRS-7 を使います。DefaultScheduler

02

カスタマイズ

モデルとクロノを選び、必要なポリシーをミドルウェアとして一つ一つ追加します。defineScheduler.use(middleware)

03

拡張する

組み込みで足りなくなったら、ミドルウェアや時間システム、モデルを自分で書けます。defineMiddlewaredefineChrono

スケジューラーコア

型安全性

一つのスキーマが、すべての型を貫く。

Standard Schema は、設定・カード・復習ログ・記憶状態・時刻値に共通の実行時検証と型契約を提供します。

  • 同じスキーマが実行時の検証と TypeScript 型推論の両方を担うため、両者がずれることはありません。
  • 入力カードは常に readonly で、可変なのはスケジュール結果だけです。
  • ミドルウェアが追加したフィールドやステータスは、推論される型に自動で現れます。
StandardSchemaV1zod
Model
Chrono
Middleware
Readonly<Card>入力
Mutable<Card>スケジュール結果

scheduleStatus: 'new' | 'review' | 'suspended'

組み込み機能

すぐに使えて、必要に応じて組み合わせられる。

Stats

カードに復習回数(reps)と忘却回数(lapses)のカウンターを追加し、維持します。

DesiredRetention

設定された目標保持率を間隔計算に渡します。

CostAdr

記憶状態と復習コストに応じて保持率を調整します。固定の目標保持率ポリシーの代わりに使用します。

Fuzzing

カード ID と復習回数をシードに、間隔へ決定的な揺らぎを加えます。

LearningSteps

学習・再学習ステップを分・時間・日の単位でスケジュールします。

Leech

忘却回数が設定したしきい値の倍数に達するたびに、カードを一時停止します。

MaximumInterval

最終的なスケジュール間隔を設定された上限以内に収めます。

MonotonicInterval

高い評価で短い間隔にならないよう調整します。

ScheduledDays

間隔と復元用の旧値を保存し、小数日が有効な場合は小数の間隔を保持します。

アーキテクチャ

モデル、クロノ、ミドルウェア。最適な組み合わせを選ぶ。

各コンポーネントは互換性があり、自由に組み合わせられます。

モデル

  • FSRS-3
  • FSRS-4
  • FSRS-4.5
  • FSRS-5
  • FSRS-6
  • FSRS-7
  • defineModel

クロノ

  • dateChrono
  • numericChrono
  • temporalInstantChrono
  • defineChrono

ミドルウェア

  • learningSteps
  • desiredRetention
  • costAdr
  • fuzzing
  • leech
  • stats
  • defineMiddleware
Scheduler CorenewCard · preview · review · rollback
Card + Revlog + ScheduleStatus
definition
.use(fuzzing).use(learningSteps)

use() は新しい definition を返します。既存の definition も、そこから作成済みスケジューラーも変更されません。

パフォーマンス

パフォーマンスはアーキテクチャの一部です。

API は、遅延評価、コード分割、不変な結果を前提に設計されています。

バージョン単位のコード分割

DefaultScheduler は指定された FSRS バージョンを必要に応じて読み込み、初回読み込みに不要なモデルコードが含まれるのを抑えるのに役立ちます。

遅延 preview

preview() は実際にイテレートした評価だけを計算します。

スキーマの遅延作成

スケジューラのスキーマは宣言時ではなく、最初にアクセスされたときに作られます。

tree-shaking 可能なエクスポート

sideEffects は false で、モデルとミドルウェアはサブパスで提供されます。

不変な結果

review は新しいカードを返し、入力を一切変更しません。

取り消せる復習

rollback() は revlog から直前のカードを、ミドルウェアのフィールドごと復元します。

コントリビューター

オープンソースとして開発されています。

プロジェクトのモデルやミドルウェアをはじめとするさまざまな改善は、コミュニティからプルリクエストを通じて寄せられる提案や貢献に支えられています。

スポンサー

あたたかいご支援に感謝します。

ひとつひとつのご支援が、ts-fsrs の継続的なメンテナンスと FSRS 研究への追従を支えています。

現在のスポンサー

  • L-M-Sherlock

過去のスポンサー

  • tomerbeil

スポンサーになる

FSRS から始めて、必要に合わせて拡張する。

デフォルトのスケジューラーで一般的な用途をカバーできます。必要に応じて、異なるモデル、時間システム、ミドルウェアで独自のスケジューラーを構成できます。