For AI agents: the complete documentation index is available at https://open-spaced-repetition.github.io/ts-fsrs/llms.txt, the full documentation bundle is available at https://open-spaced-repetition.github.io/ts-fsrs/llms-full.txt, and this page is available as Markdown at https://open-spaced-repetition.github.io/ts-fsrs/guide/scheduler/index.md.

Scheduler overview

A scheduler is the object your application calls to create cards and schedule reviews. You rarely build one from scratch: defineScheduler({ model, chrono }) creates a reusable definition from the two parts, and DefaultScheduler is a ready-made preset built from the same machinery. See Architecture for how model, chrono, and middleware fit together, or the Model, Chrono, and Middleware guides for each part.

For your Agent
Implement or explain a scheduler

Copy this prompt to keep an AI agent inside the Scheduler contract instead of mixing in model, chrono, or middleware behavior.

Definition and instance

A scheduler exists in two stages:

StageWhat it isHow you get it
DefinitionA schema-only description: a model, a chrono, and optional middleware. It holds no configuration and no card data.defineScheduler({ model, chrono }) and .use(...)
InstanceA working scheduler bound to one validated configuration.definition.create({ config })

defineScheduler keeps the concrete model and chrono types, so schemas and handlers stay type-checked through .use(...). .use(middlewareA, middlewareB) returns a new definition with the middleware added in order; the original definition is unchanged and stays reusable. Calling .create({ config }) validates that configuration against the scheduler schemas and returns an independent scheduler whose state is its own.

Keep the definition, create the instances

Store the definition, including its registered middleware, at the program level. Call .create({ config }) when a user or collection configuration becomes available. Each call validates that configuration and returns a separate instance, so two .create() calls never share scheduling state.

Reuse one definition for many schedulers

Here one definition builds two schedulers whose only difference is the target retention. Because schedulerDesiredRetentionMiddleware contributes desiredRetention to the config schema, .create() accepts and validates it per instance:

import { 
const dateChrono: 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;
            };
        }>;
    };
}>
dateChrono
,
function defineScheduler<const M extends AnyModel, const C extends AnyChrono>(definition: {
    readonly model: M;
    readonly chrono: C;
}): CustomScheduler<SchedulerNameOf<M>, SchedulerEnvFor<M, C, readonly []>, M, C>
defineScheduler
,
type Rating = 0 | 1 | 2 | 3 | 4
const Rating: Readonly<{
    readonly Manual: 0;
    readonly Again: 1;
    readonly Hard: 2;
    readonly Good: 3;
    readonly Easy: 4;
}>
Rating
} from 'ts-fsrs'
import {
const schedulerDesiredRetentionMiddleware: Middleware<symbol, {
    readonly config: SRSSchema<{
        input: {
            readonly desiredRetention: number | Record<Grade, number>;
        };
        output: {
            readonly desiredRetention: Record<Grade, number>;
        };
    }>;
}>
schedulerDesiredRetentionMiddleware
} from 'ts-fsrs/middlewares'
import {
const FSRS6_DEFAULT_WEIGHTS: number[]
FSRS6_DEFAULT_WEIGHTS
,
const FSRS6Model: Model<{
    readonly name: "fsrs-6";
    readonly config: SRSSchema<{
        input: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
        output: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stability: number;
            difficulty: number;
        };
        output: {
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS6Algorithm;
}>
FSRS6Model
} from 'ts-fsrs/models/fsrs-6'
// Create a reusable definition once, at the program level. const
const schedulerDefinition: CustomScheduler<"fsrs-6", ExtendSchedulerEnv<SchedulerEnvFor<Model<{
    readonly name: "fsrs-6";
    readonly config: SRSSchema<{
        input: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
        output: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stability: number;
            difficulty: number;
        };
        output: {
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS6Algorithm;
}>, Chrono<...>, readonly []>, readonly [...]>, Model<...>, Chrono<...>>
schedulerDefinition
=
defineScheduler<Model<{
    readonly name: "fsrs-6";
    readonly config: SRSSchema<{
        input: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
        output: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stability: number;
            difficulty: number;
        };
        output: {
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS6Algorithm;
}>, Chrono<...>>(definition: {
    ...;
}): CustomScheduler<...>
defineScheduler
({
model: Model<{
    readonly name: "fsrs-6";
    readonly config: SRSSchema<{
        input: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
        output: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stability: number;
            difficulty: number;
        };
        output: {
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS6Algorithm;
}>
model
:
const FSRS6Model: Model<{
    readonly name: "fsrs-6";
    readonly config: SRSSchema<{
        input: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
        output: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stability: number;
            difficulty: number;
        };
        output: {
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS6Algorithm;
}>
FSRS6Model
,
chrono: 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;
            };
        }>;
    };
}>
chrono
:
const dateChrono: 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;
            };
        }>;
    };
}>
dateChrono
,
}).
CustomScheduler<"fsrs-6", SchedulerEnvFor<Model<{ readonly name: "fsrs-6"; readonly config: SRSSchema<{ input: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; output: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; }>; readonly memoryState: SRSSchema<{ input: { stability: number; difficulty: number; }; output: { stability: number; difficulty: number; }; }>; readonly algorithm: FSRS6Algorithm; }>, Chrono<...>, readonly []>, Model<...>, Chrono<...>>.use: <readonly [Middleware<symbol, {
    readonly config: SRSSchema<{
        input: {
            readonly desiredRetention: number | Record<Grade, number>;
        };
        output: {
            readonly desiredRetention: Record<Grade, number>;
        };
    }>;
}>]>(middlewares_0: Middleware<symbol, {
    readonly config: SRSSchema<{
        input: {
            readonly desiredRetention: number | Record<Grade, number>;
        };
        output: {
            readonly desiredRetention: Record<Grade, number>;
        };
    }>;
}>) => CustomScheduler<...>

Returns a new scheduler definition extended with the supplied middleware. The current scheduler and any cores created from it remain unchanged.

use
(
const schedulerDesiredRetentionMiddleware: Middleware<symbol, {
    readonly config: SRSSchema<{
        input: {
            readonly desiredRetention: number | Record<Grade, number>;
        };
        output: {
            readonly desiredRetention: Record<Grade, number>;
        };
    }>;
}>
schedulerDesiredRetentionMiddleware
)
const now = new Date('2026-01-01T00:00:00.000Z') // Each .create() validates its own config and returns an independent scheduler. const
const library: SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{
    readonly name: "fsrs-6";
    readonly config: SRSSchema<{
        input: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
        output: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stability: number;
            difficulty: number;
        };
        output: {
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS6Algorithm;
}>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>
library
=
const schedulerDefinition: CustomScheduler<"fsrs-6", ExtendSchedulerEnv<SchedulerEnvFor<Model<{
    readonly name: "fsrs-6";
    readonly config: SRSSchema<{
        input: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
        output: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stability: number;
            difficulty: number;
        };
        output: {
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS6Algorithm;
}>, Chrono<...>, readonly []>, readonly [...]>, Model<...>, Chrono<...>>
schedulerDefinition
.
CustomScheduler<"fsrs-6", ExtendSchedulerEnv<SchedulerEnvFor<Model<{ readonly name: "fsrs-6"; readonly config: SRSSchema<{ input: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; output: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; }>; readonly memoryState: SRSSchema<{ input: { stability: number; difficulty: number; }; output: { stability: number; difficulty: number; }; }>; readonly algorithm: FSRS6Algorithm; }>, Chrono<...>, readonly []>, readonly [...]>, Model<...>, Chrono<...>>.create: (ctx: {
    readonly config: {
        readonly weights: number[];
        readonly enableShortTerm: boolean;
        readonly numRelearningSteps: number;
    } & {
        readonly fractionalDays?: boolean | undefined;
    } & EmptyPart & {
        readonly desiredRetention: number | Record<Grade, number>;
    };
}) => SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{
    readonly name: "fsrs-6";
    readonly config: SRSSchema<{
        input: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
        output: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stability: number;
            difficulty: number;
        };
        output: {
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS6Algorithm;
}>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>
create
({
config: {
    readonly weights: number[];
    readonly enableShortTerm: boolean;
    readonly numRelearningSteps: number;
} & {
    readonly fractionalDays?: boolean | undefined;
} & EmptyPart & {
    readonly desiredRetention: number | Record<Grade, number>;
}
config
: {
weights:
const FSRS6_DEFAULT_WEIGHTS: number[]
FSRS6_DEFAULT_WEIGHTS
,
enableShortTerm: true, numRelearningSteps: 1, desiredRetention: 0.9, }, }) const
const exam: SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{
    readonly name: "fsrs-6";
    readonly config: SRSSchema<{
        input: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
        output: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stability: number;
            difficulty: number;
        };
        output: {
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS6Algorithm;
}>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>
exam
=
const schedulerDefinition: CustomScheduler<"fsrs-6", ExtendSchedulerEnv<SchedulerEnvFor<Model<{
    readonly name: "fsrs-6";
    readonly config: SRSSchema<{
        input: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
        output: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stability: number;
            difficulty: number;
        };
        output: {
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS6Algorithm;
}>, Chrono<...>, readonly []>, readonly [...]>, Model<...>, Chrono<...>>
schedulerDefinition
.
CustomScheduler<"fsrs-6", ExtendSchedulerEnv<SchedulerEnvFor<Model<{ readonly name: "fsrs-6"; readonly config: SRSSchema<{ input: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; output: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; }>; readonly memoryState: SRSSchema<{ input: { stability: number; difficulty: number; }; output: { stability: number; difficulty: number; }; }>; readonly algorithm: FSRS6Algorithm; }>, Chrono<...>, readonly []>, readonly [...]>, Model<...>, Chrono<...>>.create: (ctx: {
    readonly config: {
        readonly weights: number[];
        readonly enableShortTerm: boolean;
        readonly numRelearningSteps: number;
    } & {
        readonly fractionalDays?: boolean | undefined;
    } & EmptyPart & {
        readonly desiredRetention: number | Record<Grade, number>;
    };
}) => SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{
    readonly name: "fsrs-6";
    readonly config: SRSSchema<{
        input: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
        output: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stability: number;
            difficulty: number;
        };
        output: {
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS6Algorithm;
}>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>
create
({
config: {
    readonly weights: number[];
    readonly enableShortTerm: boolean;
    readonly numRelearningSteps: number;
} & {
    readonly fractionalDays?: boolean | undefined;
} & EmptyPart & {
    readonly desiredRetention: number | Record<Grade, number>;
}
config
: {
weights:
const FSRS6_DEFAULT_WEIGHTS: number[]
FSRS6_DEFAULT_WEIGHTS
,
enableShortTerm: true, numRelearningSteps: 1, desiredRetention: 0.8, }, }) function nextGoodDue(
scheduler: SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{
    readonly name: "fsrs-6";
    readonly config: SRSSchema<{
        input: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
        output: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stability: number;
            difficulty: number;
        };
        output: {
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS6Algorithm;
}>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>
scheduler
: typeof
const library: SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{
    readonly name: "fsrs-6";
    readonly config: SRSSchema<{
        input: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
        output: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stability: number;
            difficulty: number;
        };
        output: {
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS6Algorithm;
}>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>
library
) {
const
const card: {
    stability: number;
    difficulty: number;
    dueAt: Date;
    lastReviewAt: Date | null;
    state: State;
    scheduleStatus: "new" | "learning" | "review";
}
card
=
scheduler: SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{
    readonly name: "fsrs-6";
    readonly config: SRSSchema<{
        input: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
        output: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stability: number;
            difficulty: number;
        };
        output: {
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS6Algorithm;
}>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>
scheduler
.
SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{ readonly name: "fsrs-6"; readonly config: SRSSchema<{ input: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; output: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; }>; readonly memoryState: SRSSchema<{ input: { stability: number; difficulty: number; }; output: { stability: number; difficulty: number; }; }>; readonly algorithm: FSRS6Algorithm; }>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>.newCard: (options?: {
    readonly now?: Date | undefined;
} | undefined) => {
    stability: number;
    difficulty: number;
    dueAt: Date;
    lastReviewAt: Date | null;
    state: State;
    scheduleStatus: "new" | "learning" | "review";
}
newCard
({ now })
return
scheduler: SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{
    readonly name: "fsrs-6";
    readonly config: SRSSchema<{
        input: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
        output: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stability: number;
            difficulty: number;
        };
        output: {
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS6Algorithm;
}>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>
scheduler
.
SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{ readonly name: "fsrs-6"; readonly config: SRSSchema<{ input: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; output: { readonly weights: number[]; readonly enableShortTerm: boolean; readonly numRelearningSteps: number; }; }>; readonly memoryState: SRSSchema<{ input: { stability: number; difficulty: number; }; output: { stability: number; difficulty: number; }; }>; readonly algorithm: FSRS6Algorithm; }>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>.review: (input: {
    readonly card: Readonly<Omit<Readonly<Omit<Readonly<{
        stability: number;
        difficulty: number;
    } & {
        dueAt: Date;
        lastReviewAt: Date | null;
    } & SchedulerCoreFields$1<"new" | "learning" | "review">>, keyof SchedulerCoreFields$1<"new" | "learning" | "review">> & SchedulerCoreFields$1<"new" | "learning" | "review">>, keyof SchedulerCoreFields$1<"new" | "learning" | "review">> & SchedulerCoreFields$1<"new" | "learning" | "review">>;
    readonly grade: Grade;
    readonly now?: Date | undefined;
}) => {
    ...;
}
review
({ card, grade:
const Rating: Readonly<{
    readonly Manual: 0;
    readonly Again: 1;
    readonly Hard: 2;
    readonly Good: 3;
    readonly Easy: 4;
}>
Rating
.Good, now })
.
card: {
    stability: number;
    difficulty: number;
    dueAt: Date;
    lastReviewAt: Date | null;
    state: State;
    scheduleStatus: "new" | "learning" | "review";
}
card
.dueAt.toISOString()
} console.log( JSON.stringify( { libraryRetention: 0.9, libraryDue: nextGoodDue(
const library: SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{
    readonly name: "fsrs-6";
    readonly config: SRSSchema<{
        input: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
        output: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stability: number;
            difficulty: number;
        };
        output: {
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS6Algorithm;
}>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>
library
),
examRetention: 0.8, examDue: nextGoodDue(
const exam: SchedulerCore<SchedulerCoreEnv<ExtendSchedulerEnv<SchedulerEnvFor<Model<{
    readonly name: "fsrs-6";
    readonly config: SRSSchema<{
        input: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
        output: {
            readonly weights: number[];
            readonly enableShortTerm: boolean;
            readonly numRelearningSteps: number;
        };
    }>;
    readonly memoryState: SRSSchema<{
        input: {
            stability: number;
            difficulty: number;
        };
        output: {
            stability: number;
            difficulty: number;
        };
    }>;
    readonly algorithm: FSRS6Algorithm;
}>, Chrono<...>, readonly []>, readonly [...]>>, ModelCore<...>, ChronoCore<...>>
exam
),
}, null, 2 ) )

The lower retention target lets the interval grow, so the exam scheduler's first Good review is due on January 9 while the library scheduler's is due on January 3. The definition itself never changes; the two schedulers differ only through their validated configurations.

Ready-made preset

DefaultScheduler is an asynchronous factory that assembles the same definition-and-instance machinery with the FSRS-7 model (by default), dateChrono, and the standard scheduling policies, so you only pass options. See DefaultScheduler for the options and versions, or Quick start to run it first.