Phaser AE

English word lists

Free packv3.0.0-0WordNew

The words a word game needs, and the questions it asks of them. Check a guess, pick tonight's answer, find every word seven letters can make or suggest the word a player meant, from 69,223 common English words that come with the pack.

This is a Free pack. Every phaser.io account can use it in their games.

Released October 21, 2026

English word lists: a screenshot of its demo
A note about these graphics

Expansion packs don't come with graphics. This screenshot is one way of drawing what the pack does, made for its demo: none of the sprites, tiles or backgrounds in it are in the pack.

That's by design. A pack is a game's logic, mechanics and effects, and it works with whatever art you give it. Some packs draw effects, backdrops or 3D scenes of their own, but none carries a game's sprites.

So the look is yours. Make the art on phaser.io, bring your own, or let your agent draw it in code: the same pack can look like anything.

The pack

englishWords

function englishWords(options: EnglishWordsOptions = {}): Pack<{ words: WordsApi }>

The english-words pack: game.words, the Common English Lexicon (69,223 words) and lists of your own, with exact, pattern, prefix, anagram and fuzzy search. Headless; needs no world or renderer.

Helpers

ALPHABET

const ALPHABET: "abcdefghijklmnopqrstuvwxyz"

The 26 letters every word is made of, in order.

CEL_COMMIT

const CEL_COMMIT: "5836e959e56bac99547345837aacbde8f2a623b8"

The CEL commit these words come from.

CEL_COUNTS

const CEL_COUNTS: Readonly<Record<number, number>>

How many words of each length, 69223 in all.

createWordList

function createWordList(source: Iterable<string> | string, options: WordListOptions = {}): WordList

A list of your own words: an array, or text as parseWords reads it. Each entry is normalised as normaliseWord does (so "Tyrannosaurus Rex" becomes tyrannosaurusrex) and duplicates are kept once. Throws a RangeError for an entry that is not a word, unless options.invalid is 'skip'.

editDistance

function editDistance(a: string, b: string): number

The fewest single-letter edits that turn a into b: an insertion, a deletion, a change, or two neighbouring letters swapped (hte → the is 1). Case and the characters normaliseWord drops are ignored. This is the distance the fuzzy search ranks by.

englishLexicon

function englishLexicon(options: EnglishOptions = {}): WordList

The Common English Lexicon: 69,223 English words of 2 to 45 letters, chosen as common for word games, by Eric Smith and Kenji Matsumoto (MIT licence). By default the 86 rated offensive (slurs, strong swearing, explicit terms) are left out; rating: 'family' leaves out 147 milder ones too, and 'unfiltered' keeps all. Shared and decoded a length at a time, the first time a length is asked for. With options, a list narrowed to min..max letters with include added and exclude taken out.

normaliseWord

function normaliseWord(text: string): string | null

A word's letters as they are stored: lower case, a-z only. Spaces, hyphens, apostrophes and full stops are dropped and accents taken off ("T. Rex" → trex, "café" → cafe). Null when anything else is left or nothing is.

parseWords

function parseWords(text: string): string[]

The words in text: one entry per line, or separated by commas or semicolons. Blank entries and lines starting with # are skipped. Entries are not normalised; createWordList does that.

word

function word(text: string): Word

A word from text: word('Crane').at(2) → 'a'. Throws a RangeError for anything but letters. Not checked against any list.

Functions

wordRating

function wordRating(word: string): WordRating | null

A lexicon word's rating: 'offensive' (slurs, strong swearing, explicit terms), 'mature' (milder swearing, sex, the body, crime), or null for every other word. Rated for the words of the Common English Lexicon; any other text is null. Case does not matter.

Classes

Word

class Word

One word, with questions about its letters: what is at a position, how often a letter appears, whether a partly traced word is on its way to this one, and whether its letters can make another word. Make one with word(text) or take one from a list (pick, sample, list.word). Immutable.

  • readonly text: string — The word in lower case, a-z only.
  • constructor(text: string) — Normalises text as normaliseWord does. Throws a RangeError when it holds anything but letters.
  • get length(): number — How many letters.
  • get first(): string — The first letter.
  • get last(): string — The last letter.
  • get upper(): string — The word in capitals, as most word games show it.
  • get letters(): ReadonlyArray<string> — The letters in order, one string each.
  • get sorted(): string — The letters in alphabetical order, as one string: two words are anagrams when these are equal.
  • at(index: number): string — The letter at index, counting from 0; a negative index counts back from the end (-1 is the last letter). Throws a RangeError outside the word.
  • is(index: number, letter: string): boolean — Is letter at index (from 0; negative from the end)? False outside the word. Case does not matter.
  • has(letter: string): boolean — Does the word contain letter?
  • count(letter: string): number — How many times letter appears. Throws a RangeError for anything but one letter.
  • positions(letter: string): number[] — Every position of letter, from 0, in order.
  • startsWith(part: string): boolean — Does the word start with part? A traced or typed word that is still on its way to this one does.
  • endsWith(part: string): boolean — Does the word end with part?
  • includes(part: string): boolean — Does part appear anywhere in the word?
  • next(part: string): string | null — The letter that comes after part when part is the start of this word, else null (also when part is the whole word). What a hint shows a player halfway through tracing it.
  • matches(pattern: string): boolean — Does the word fit pattern? ?, . or _ is any letter, [abc] any of those, [^abc] any but those.
  • canMake(other: string | Word): boolean — Can other be spelt with this word's letters, each used no more often than it appears here? listen can make silent, tin and lest, not tilt. What a letter-wheel puzzle asks of its base word.
  • isAnagramOf(other: string | Word): boolean — Is other the same letters in another order? A word is not an anagram of itself.
  • equals(other: string | Word): boolean — The same word, ignoring case and the characters normaliseWord drops?
  • toString(): string — The word, lower case.
  • toJSON(): string — The word, lower case, so a Word goes into a save as a plain string.

WordList

class WordList

A list of words, any size, from the English lexicon (englishLexicon) or your own (createWordList). Every word is lower case, a-z only; every lookup ignores case. Immutable: filter, with and without return new lists.

  • readonly name: string — A name for messages and for telling lists apart.
  • readonly size: number — How many words.
  • readonly lengths: ReadonlyArray<number> — The lengths that have words, shortest first.
  • constructor(name: string, counts: ReadonlyMap<number, number>, private readonly group: (length: number) => ReadonlyArray<string>) — Use createWordList or englishLexicon rather than this. counts gives each length's word count and group(length) that length's words, sorted, when first asked for.
  • ofLength(length: number): ReadonlyArray<string> — Every word of length letters, in alphabetical order. Empty for a length the list has none of.
  • words(): string[] — Every word, shortest first, alphabetical within a length.
  • has(text: string): boolean — Is text in the list? Case and the characters normaliseWord drops do not matter.
  • word(text: string): Word | null — text as a Word when it is in the list, else null.
  • find(query: WordQuery = {}, limit = Infinity): string[] — Every word that matches, shortest first and alphabetical within a length, at most limit of them.
  • count(query: WordQuery = {}): number — How many words match.
  • first(query: WordQuery = {}): Word | null — The first word that matches, in find's order, as a Word, or null.
  • isPrefix(prefix: string): boolean — Does any word start with prefix (or equal it)? What a grid solver asks before it goes a letter deeper, and what a game asks of a word the player is still tracing.
  • completions(prefix: string, limit = Infinity): string[] — Words that start with prefix, in alphabetical order (not by length), at most limit.
  • anagrams(letters: string): string[] — Words made of exactly letters, rearranged (anagrams('least') → slate, stale, steal, tales…); letters itself is left out.
  • near(text: string, distance = 1, limit = Infinity): string[] — The words within distance edits of text (an insertion, deletion, change or swap of two neighbours each), nearest first, then shortest, then alphabetical; text itself first when it is a word. What a "did you mean" needs. Default distance 1.
  • closest(text: string, distance = 2): string | null — The nearest word to text within distance edits (default 2), or null. text itself when it is a word.
  • pick(rng: Rng, query: WordQuery = {}): Word — One matching word, chosen by rng. Throws a RangeError when nothing matches, naming the list and the query.
  • sample(rng: Rng, count: number, query: WordQuery = {}): Word[] — Up to count different matching words, chosen by rng, in the order drawn. Fewer only when fewer match.
  • filter(query: WordQuery, name = \${this.name} (filtered)`): WordList` — A new list of the words that match.
  • with(words: Iterable<string>, name = this.name): WordList — A new list with words added, normalised as normaliseWord does. Throws a RangeError for an entry that is not a word.
  • without(words: Iterable<string>, name = this.name): WordList — A new list without words (any case).
  • letterFrequency(): Readonly<Record<string, number>> — How often each letter appears across the list, a to z, as fractions that add up to 1. A letter grid that wants playable letters draws by these. Worked out once, the first time it is asked for.

Types

EnglishOptions

interface EnglishOptions

What englishLexicon and the pack's options take.

  • min?: number — Shortest word, in letters. Default 2, the shortest in the lexicon.
  • max?: number — Longest word, in letters. Default 45, the longest in the lexicon.
  • include?: ReadonlyArray<string> — Words to add (a game's own slang, names it allows). Normalised as normaliseWord does.
  • exclude?: ReadonlyArray<string> — Words to leave out (any case).
  • rating?: RatingFilter — Which rated words to keep (see wordRating): 'standard' (the default) leaves out slurs, strong swearing and explicit terms; 'family' leaves out milder swearing and words about sex, the body and crime as well; 'unfiltered' keeps every word of the lexicon.

EnglishWordsOptions

type EnglishWordsOptions = EnglishOptions

Manifest options: the game's own word list, game.words.lexicon, is the lexicon narrowed by these.

RatingFilter

type RatingFilter = 'standard' | 'family' | 'unfiltered'

Which words a list keeps: standard drops the offensive, family the mature too, unfiltered none.

WordListOptions

interface WordListOptions

How createWordList reads its words.

  • name?: string — A name for messages and for telling lists apart. Default 'custom'.
  • invalid?: 'throw' | 'skip' — What to do with an entry that is not a word of the letters a-z once normalised: 'throw' (the default) or 'skip'.
  • rating?: RatingFilter — Leave out rated words (see wordRating): 'standard', 'family', or 'unfiltered' (the default: your list as given).

WordQuery

interface WordQuery

What to find in a list. Every field narrows it; leave a field out to ignore it. Letters may be given in either case. Results come in length order, then alphabetical.

  • length?: number — Exactly this many letters.
  • min?: number — At least this many letters.
  • max?: number — At most this many letters.
  • startsWith?: string — Starts with these letters.
  • endsWith?: string — Ends with these letters.
  • contains?: string — Has these letters together somewhere.
  • pattern?: string — Fits this pattern, which also fixes the length: ?, . or _ is any letter, [abc] any of those, [^abc] any but those (c?a[^s]e).
  • from?: string — Can be spelt from these letters, each used no more often than it appears here: a letter rack or wheel (from: 'listen').
  • only?: string — Uses no letters but these, as often as it likes (only: 'abcde').
  • uses?: string — Contains every one of these letters at least once.
  • without?: string — Contains none of these letters.
  • exclude?: Iterable<string> — Leave these words out (any case).
  • where?: (word: string) => boolean — Any other test, given the lower-case word.

WordRating

type WordRating = 'offensive' | 'mature'

How suitable a word is for a game's audience.

WordsApi

interface WordsApi

game.words: the game's word list, lists of your own, and seeded picks from the game's random source.

  • readonly lexicon: WordList — The game's word list: the English lexicon within the manifest's min..max letters, include added, exclude taken out.
  • english(options?: EnglishOptions): WordList — The English lexicon narrowed differently from lexicon (english({ min: 3, max: 8 })). The full lexicon with no options.
  • list(source: Iterable<string> | string, options?: WordListOptions): WordList — A list of your own, from an array or from text (one word a line, or separated by commas). See createWordList.
  • loaded(key: string, options?: WordListOptions): WordList — A list from a file the loader fetched under key: a text item read as list reads text, or a json item holding an array of strings. Headless, where the loader fetches nothing, the list is empty. Throws for an unknown key or a JSON value that is not an array of strings.
  • has(text: string): boolean — Is text in lexicon? Case does not matter.
  • word(text: string): Word — text as a Word, whether or not any list holds it. Throws a RangeError for anything but letters.
  • find(query?: WordQuery, list?: WordList): string[] — Every word in list (default lexicon) that matches, shortest first, alphabetical within a length.
  • pick(query?: WordQuery, list?: WordList): Word — One matching word from list (default lexicon), chosen by the game's random source. Throws a RangeError when nothing matches.
  • sample(count: number, query?: WordQuery, list?: WordList): Word[] — Up to count different matching words from list (default lexicon), chosen by the game's random source.
  • distance(a: string, b: string): number — The fewest single-letter edits between two words; see editDistance.
  • readonly rng: Rng — The random source pick and sample draw from: the game's, forked as 'words'.