# How to Customize FSRS Algorithm Parameters in TypeWords

> Learn how to customize FSRS algorithm parameters in TypeWords. Edit settings via the UI or programmatically for personalized spaced repetition.

- Repository: [Zyronon/TypeWords](https://github.com/zyronon/TypeWords)
- Tags: how-to-guide
- Published: 2026-09-03

---

**TypeWords uses the open-source `ts-fsrs` spaced-repetition engine, with all FSRS algorithm parameters stored in a reactive Pinia store at [`app/core/stores/setting.ts`](https://github.com/zyronon/TypeWords/blob/main/app/core/stores/setting.ts) and editable through a built-in UI or programmatically.**

TypeWords leverages the `ts-fsrs` library to power its adaptive flashcard scheduling. Whether you want to tune retention targets, adjust grade thresholds, or modify the weight vector, every configurable aspect of the algorithm is exposed through a centralized Pinia store. This guide explains where these parameters live, how the UI connects to them, and how to override them in code.

## Where FSRS Parameters Are Stored

All FSRS configuration resides in the **Pinia setting store** ([`app/core/stores/setting.ts`](https://github.com/zyronon/TypeWords/blob/main/app/core/stores/setting.ts)). The store maintains two related structures:

- **`store.fsrsParameters`** — Core algorithm parameters passed directly to the `ts-fsrs` `GeneratorParameters` interface
- **Grade threshold fields** (`fsrsEasyLimit`, `fsrsGoodLimit`, `fsrsHardLimit`) — Map wrong-answer counts to FSRS `Rating` values

### Core FSRS Parameters in `store.fsrsParameters`

| Parameter | Type | Description |
|-----------|------|-------------|
| `request_retention` | `number` | Target retention probability (0–1, default ~0.9) |
| `maximum_interval` | `number` | Hard cap on interval length in days |
| `w` | `number[]` | 17-element weight vector controlling the model |
| `enable_fuzz` | `boolean` | Adds small random noise to intervals |
| `enable_short_term` | `boolean` | Enables short-term scheduling |
| `learning_steps` | `number[]` | Minutes between learning-stage reviews |
| `relearning_steps` | `number[]` | Minutes between relearning-stage reviews |

### Grade Threshold Mapping

The `fsrsEasyLimit`, `fsrsGoodLimit`, and `fsrsHardLimit` values determine how many wrong attempts translate to each FSRS `Rating`:

- **Again**: Wrong times > `fsrsHardLimit`
- **Hard**: `fsrsGoodLimit` < wrong times ≤ `fsrsHardLimit`
- **Good**: `fsrsEasyLimit` < wrong times ≤ `fsrsGoodLimit`
- **Easy**: wrong times ≤ `fsrsEasyLimit`

This conversion happens in [`app/core/hooks/fsrs.ts`](https://github.com/zyronon/TypeWords/blob/main/app/core/hooks/fsrs.ts), where the store values are used to instantiate a fresh `FSRS` object and to compute ratings.

## Method 1: Programmatically Update the Store

For dynamic customization, import `useSettingStore()` and mutate the reactive properties directly. Changes propagate immediately to the FSRS helper.

### Update Core Algorithm Parameters

```typescript
import { useSettingStore } from '@/core/stores/setting.ts'

const setting = useSettingStore()

// Raise retention target to 95%
setting.fsrsParameters.request_retention = 0.95

// Enable fuzz to reduce card clustering
setting.fsrsParameters.enable_fuzz = true

// Modify the weight vector for faster decay
setting.fsrsParameters.w = setting.fsrsParameters.w.map(w => w * 0.8)

```

### Adjust Grade Thresholds

```typescript
import { useSettingStore } from '@/core/stores/setting.ts'

const setting = useSettingStore()

// Stricter grading: Easy only with 0–1 mistakes, Good with 2–3, Hard with 4–6
setting.fsrsEasyLimit = 1
setting.fsrsGoodLimit = 3
setting.fsrsHardLimit = 6

```

Because the store is reactive, the next call to `useNextCard()` or any FSRS operation automatically uses the updated configuration. No manual persistence is required.

## Method 2: Use the Built-in FSRS Settings UI

TypeWords ships with a dedicated settings component at [`app/components/setting/FsrsSetting.vue`](https://github.com/zyronon/TypeWords/blob/main/app/components/setting/FsrsSetting.vue). This component binds form inputs directly to the Pinia store fields, providing:

- Numeric inputs for `request_retention`, `maximum_interval`, and weight vector elements
- Toggles for `enable_fuzz` and `enable_short_term`
- Array editors for `learning_steps` and `relearning_steps`
- Threshold inputs for `fsrsEasyLimit`, `fsrsGoodLimit`, `fsrsHardLimit`

To embed the settings UI elsewhere in your application:

```vue
<template>
  <FsrsSetting />
</template>

<script setup lang="ts">
import FsrsSetting from '@/components/setting/FsrsSetting.vue'
</script>

```

## How the FSRS Hook Consumes Parameters

The [`app/core/hooks/fsrs.ts`](https://github.com/zyronon/TypeWords/blob/main/app/core/hooks/fsrs.ts) file bridges the store to the `ts-fsrs` engine. It:

1. Reads `store.fsrsParameters` to construct a new `FSRS` instance
2. Uses the threshold fields to convert raw wrong-attempt counts into `Rating` values
3. Exposes `useNextCard()` and related composables that automatically pick up store changes

This architecture ensures that **customizing FSRS algorithm parameters in TypeWords** is always consistent—whether through UI interaction or direct store manipulation.

## Summary

- **Primary storage**: [`app/core/stores/setting.ts`](https://github.com/zyronon/TypeWords/blob/main/app/core/stores/setting.ts) holds all FSRS configuration in a reactive Pinia store
- **Two customization paths**: Built-in UI component ([`FsrsSetting.vue`](https://github.com/zyronon/TypeWords/blob/main/FsrsSetting.vue)) or programmatic store access
- **Core parameters**: `request_retention`, `w`, `enable_fuzz`, `maximum_interval`, and step arrays in `store.fsrsParameters`
- **Grade logic**: `fsrsEasyLimit`, `fsrsGoodLimit`, `fsrsHardLimit` control the mapping from wrong attempts to FSRS ratings
- **Integration point**: [`app/core/hooks/fsrs.ts`](https://github.com/zyronon/TypeWords/blob/main/app/core/hooks/fsrs.ts) instantiates `FSRS` with current store values and handles rating conversion

## Frequently Asked Questions

### What is the default `request_retention` value in TypeWords?

The default retention target is approximately 0.9 (90%), but you should verify the exact initialization in [`app/core/stores/setting.ts`](https://github.com/zyronon/TypeWords/blob/main/app/core/stores/setting.ts). This value represents the probability that you will recall a card when it next appears, with higher values producing more frequent reviews.

### Can I modify the 17-element weight vector `w` without breaking the algorithm?

Yes, but cautiously. The weight vector is exposed for advanced tuning, yet arbitrary changes may destabilize scheduling. Start with small perturbations (±10–20%) and monitor retention metrics. For production stability, prefer adjusting `request_retention` or enabling `enable_fuzz` before tampering with `w` directly.

### Why does `useNextCard()` reflect changes immediately without reloading?

The FSRS helper in [`app/core/hooks/fsrs.ts`](https://github.com/zyronon/TypeWords/blob/main/app/core/hooks/fsrs.ts) constructs a fresh `FSRS` instance on each relevant call using the reactive `store.fsrsParameters`. Since Pinia stores are reactive, any mutation triggers dependent consumers to re-evaluate with the latest configuration.

### How do grade thresholds interact with the `ts-fsrs` Ratings?

TypeWords extends raw FSRS by converting typing-performance metrics (wrong attempt counts) into the four standard FSRS `Rating` values. The thresholds in `store.fsrsEasyLimit`, `store.fsrsGoodLimit`, and `store.fsrsHardLimit` define the boundaries for this conversion, effectively customizing how strictly your typing accuracy maps to scheduler difficulty.