language learner

Dutch, Korean and English from the very first word to advanced. Structured lessons from A1 to C1, spaced repetition, and endless daily challenges to grind.

{#if progress.loaded}

streak

today

{progress.todayXp()} / {progress.settings.goal} XP

total

{Object.values(progress.data.langs).reduce((n, p) => n + (p?.xp ?? 0), 0)} XP

{/if}
{#each COURSES as c (c.code)} {@const count = data.counts[c.code]}
{c.code.toUpperCase()} {#if progress.loaded && progress.streak(c.code)} {/if}

{c.name}

{c.nativeName}

{c.tagline}

{count.lessons} lessons · {count.words} words · {count.levels[0]}–{count.levels.at(-1)}

{#if progress.loaded}
{completed(c.code)} / {count.lessons} lessons {#if progress.due(c.code).length} {progress.due(c.code).length} to review {/if}
{/if} {completed(c.code) ? 'Continue' : 'Start'}
{/each}

how it works

settings

{#if progress.loaded}
{#each COURSES as c (c.code)} {/each}
Daily goal
{#each goals as goal (goal)} {/each}

Progress is saved in this browser. Export it to move it to another device.

{#each COURSES as c (c.code)} {#if progress.data.langs[c.code]} {/if} {/each}
{#if importError}

{importError}

{/if}
{/if}
{ if (!open) resetTarget = null; }} > Reset {resetTarget?.name}?This deletes all progress for this language and cannot be undone.Cancel { if (resetTarget) progress.reset(resetTarget.code); resetTarget = null; }}>Reset progress