Work in progress — content and features are actively being added.

The Derivation Idea

Most Old English verb forms are not memorized individually — they are derived from a small number of inputs using a fixed sequence of rules. For strong verbs, those inputs are the four principal parts: the infinitive, the past singular, the past plural, and the past participle. Every other form can be produced mechanically from these four, given the right rules for endings, i-mutation, and consonant collision.

This page documents those rules explicitly, so they can serve both as a learning aid and as the specification for the paradigm generator used to produce the conjugation tables in the verb reference.

Principal Parts and Stems

A strong verb is specified by four principal parts. We use the infinitive as the first part rather than the 3rd person singular present — this is because the 3rd person singular present forms (which involve i-mutation and consonant collision) are themselves derived by the rules. Supplying the infinitive is therefore sufficient; the 3rd singular is a computed output, not an input.

The four principal parts are: infinitive, past singular, past plural, past participle. Each yields one stem by stripping its characteristic ending:

beran   present stem:  ber-
bær     past sg stem:  bær-
bǣron   past pl stem:  bǣr-
boren    past part stem: bor-
import re

def extract_stems(principal_parts):
    inf, past_sg, past_pl, past_part = principal_parts
    present_stem   = re.sub(r'an$', '', inf)
    past_sg_stem   = past_sg
    past_pl_stem   = re.sub(r'on$', '', past_pl)
    past_part_stem = re.sub(r'en$', '', re.sub(r'^ġe', '', past_part))
    return {
        'present_stem':   present_stem,
        'past_sg_stem':   past_sg_stem,
        'past_pl_stem':   past_pl_stem,
        'past_part_stem': past_part_stem,
    }

The Ending Table

Once the four stems are known, each inflected form is built by concatenating the appropriate stem with its ending. The present sg2 and sg3 use the i-mutated stem (with collision rules applied); all other present forms use the plain present stem.

Endings for strong verbs
Form Stem Ending
Pres. ind. sg1 present + e
Pres. ind. sg2 mutated + st (apply collision rules)
Pres. ind. sg3 mutated + þ (apply collision rules)
Pres. ind. pl present + aþ
Past ind. sg1 past sg (bare stem)
Past ind. sg2 past pl + e
Past ind. sg3 past sg (bare stem)
Past ind. pl past pl + on
Pres. subj. sg present + e
Pres. subj. pl present + en
Past subj. sg past pl + e
Past subj. pl past pl + en
Inflected inf. present tō + … + enne
Pres. participle present + ende
Past participle past part ġe + … + en
Imperative sg present (bare stem)
Imperative pl present + aþ
def build_forms(stems, mutated_stem):
    ps  = stems['present_stem']
    sg  = stems['past_sg_stem']
    pl  = stems['past_pl_stem']
    pp  = stems['past_part_stem']
    ms  = mutated_stem
    return {
        'pres_ind':  {'sg1': ps+'e', 'sg2': apply_collision(ms,'st'),
                      'sg3': apply_collision(ms,'þ'),  'pl': ps+'aþ'},
        'past_ind':  {'sg1': sg, 'sg2': pl+'e', 'sg3': sg, 'pl': pl+'on'},
        'pres_subj': {'sg': ps+'e', 'pl': ps+'en'},
        'past_subj': {'sg': pl+'e', 'pl': pl+'en'},
        'infinitive': ps+'an',
        'inflected_infinitive': 'tō '+ps+'enne',
        'pres_participle': ps+'ende',
        'past_participle': 'ġe'+pp+'en',
        'imperative_sg': ps,
        'imperative_pl': ps+'aþ',
    }

I-Mutation

I-mutation (also called i-umlaut) is a historical sound change in which a back or low vowel was fronted and raised when a high front vowel /i/ or /j/ followed in the next syllable. That triggering vowel was later lost, leaving the mutated stem vowel as the only trace. In the Old English present tense, i-mutation applies to the 2nd and 3rd person singular, which historically took a suffix beginning with i. The long vowel ē is already a front vowel and does not mutate.

I-mutation vowel correspondences
Base vowel Mutated
a æ
ā ǣ
e i
o e
ō ē
u y
ū ȳ
ea ie
ēa īe
eo ie
ēo īe
an en
am em
I_MUTATION = {
    'a': 'æ',   'ā': 'ǣ',  'e': 'i',   'o': 'e',
    'ō': 'ē',   'u': 'y',  'ū': 'ȳ',   'ea': 'ie',
    'ēa': 'īe', 'eo': 'ie','ēo': 'īe', 'an': 'en',
    'am': 'em',
}

# Match longest vowel sequence first to avoid 'e' matching inside 'eo'
VOWELS_LONGEST_FIRST = sorted(I_MUTATION, key=len, reverse=True)

def apply_i_mutation(stem):
    for v in VOWELS_LONGEST_FIRST:
        idx = stem.find(v)
        if idx != -1:
            return stem[:idx] + I_MUTATION[v] + stem[idx+len(v):]
    return stem  # no vowel found — return unchanged

Consonant Collision

When the stem ends in certain consonants and the ending begins with another consonant (-st for 2nd sg, for 3rd sg), the two consonants collide and must be resolved. The collision produces a single merged spelling rather than an impossible cluster. Additionally, a doubled consonant (nn, mm, ll, pp) is simplified to a single consonant before another consonant.

Collision outcomes
Context Result
d + þ (3rd sg) tt
t + þ (3rd sg) tt
s + þ (3rd sg) st
d + st (2nd sg) tst
þ + st (2nd sg) st
nn/mm/ll/pp + C n/m/l/p + C

The live engine handles additional consonant clusters and special cases beyond those shown here — including dotted-letter changes (ċ → c, ċġ → ġ), nasal-cluster simplification (e.g. findan → fint), and weak verb past-tense formation. If interested, feel free to explore the guts of the engine in the linked GitHub repo: paradigm.js

THIRD_SG_COLLISION  = {'d+þ': 'tt', 't+þ': 'tt', 's+þ': 'st'}
SECOND_SG_COLLISION = {'d+st': 'tst', 'þ+st': 'st'}
# Doubled consonants drop one before another consonant

def apply_collision(stem, ending):
    # Simplify doubled final consonant before a consonant ending
    if len(stem) >= 2 and stem[-1] == stem[-2] and ending[0] not in 'aeiouāǣēīōūȳ':
        stem = stem[:-1]
    key = stem[-1] + '+' + ending
    if ending == 'þ' and key in THIRD_SG_COLLISION:
        return stem[:-1] + THIRD_SG_COLLISION[key]
    if ending == 'st' and key in SECOND_SG_COLLISION:
        return stem[:-1] + SECOND_SG_COLLISION[key]
    return stem + ending

Worked Example — beran

Input: beran — principal parts ['beran', 'bær', 'bǣron', 'boren']

1 Extract stems. Strip endings from each principal part:
beran-an presentStem = ber
bær (bare stem) pastSgStem = bær
bǣron-on pastPlStem = bǣr
borenġe- (none) − -en pastPartStem = bor
2 Apply i-mutation to ber. Scan longest-first: vowel e found at index 1 mutated to i mutatedStem = bir
3 Check collision for sg2 (bir + st). Final consonant r: no collision rule applies, no doubled consonant birst (epenthetic e optional: bir(e)st)
4 Check collision for sg3 (bir + þ). Final consonant r: no collision rule applies birþ (epenthetic e optional: bir(e)þ)
5 Build present indicative from presentStem ber and mutatedStem bir:
sg1 = ber + e = bere  ·  sg2 = bir(e)st  ·  sg3 = bir(e)þ  ·  pl = ber + = beraþ
6 Build past indicative from pastSgStem bær and pastPlStem bǣr:
sg1 = bær (bare)  ·  sg2 = bǣr + e = bǣre  ·  sg3 = bær (bare)  ·  pl = bǣr + on = bǣron
7 Build non-finite forms from presentStem ber and pastPartStem bor:
inflected infinitive = tō + ber + enne = tō berenne
present participle = ber + ende = berende
past participle = ġe + bor + en = ġeboren
8 Build imperative from presentStem ber:
sg = ber (bare)  ·  pl = ber + = beraþ
beran — to carry, bear — Strong IV — derived output
Present Indicative
1st sg. bere
2nd sg. bir(e)st
3rd sg. bir(e)þ
plural beraþ
Past Indicative
1st sg. bær
2nd sg. bǣre
3rd sg. bær
plural bǣron
Present Subjunctive
singular bere
plural beren
Past Subjunctive
singular bǣre
plural bǣren
Non-finite & Imperative
Infinitive
beran
Inflected Inf.
tō berenne
Pres. Participle
berende
Past Participle
ġeboren
Imperative Sg.
ber
Imperative Pl.
beraþ