The English OpenList: a word list that keeps itself up to date

345,162 English words, lowercase a to z, checked against dictionaries every night

The English OpenList (EOL) is a free list of 345,162 English words, lowercase a to z and nothing else. It’s published on Hugging Face under the MIT license and maintained by a GitHub Actions run that checks new candidates against dictionaries every night.

The EOL is made for word games and apps, research, and teaching. But it’s not just another big text file:

  • Every word has a record: how it got on the list (from a source, through a check that used a language model, or generated by rule), so you can leave out whatever you don’t trust.
  • It updates itself: Every night at midnight UTC, a run looks for new words and checks about 1,000 candidates against a dictionary API. Every run gets its own page in the daily log.
  • Corrections in the open: A word moves by hand only through a ledger row that names the word, the action, the reason, the method, the source, and the date.
  • No arbitrary length limit: Words run from 1 letter to 47, and there’s a ready-made “Lengths 2 to 45” file if you want the shape of a tournament list.
  • A site to search it: The whole list loads into the page, so you can search by prefix, suffix, pattern, or regular expression, and open any word for its record.
The English OpenList’s site: search the whole list in your browser, open a word’s panel, filter by what decided each word, open a night’s run on the daily log, and read the charts. Recorded October 30, 2026.

Why I built it

I’ve always been a word nerd. Growing up, solving the Cincinnati Enquirer’s daily Jumble (anagram puzzle) was one of my favorite little hobbies. For some reason (maybe I’m a bit dyslexic), I am naturally gifted at letter rearrangement and can usually recognize the solution hidden in a jumbled word in under a second. I don’t know how I do it, but I do it. It’s such a trivial talent, like a party trick, and I never thought it would be useful for anything important.

As an adult, I still play word games and enjoy anagram puzzles from time to time. In 2025, I wanted to make my own free, upgraded version of Wordle (and, eventually, I did: Amordle) and to explore some similar letter-rearrangement projects (e.g., Ars Magna, Anagram Tiles).

So I began at a natural starting point: finding a suitable English word list.

But not just any ordinary list of English words would do: I wanted the longest, most current set of “valid” words that could be compatible with games like Scrabble and Wordle. After searching far and wide on the web, I realized that this list just didn’t exist.

The closest ones to it all had serious problems, typically some combination of three things:

  1. Completeness: Some were incomplete or seriously outdated (e.g., MIT 10,000, Google 10,000). These could be merged, but only a handful appear to be from credible sources, and none is maintained or updated frequently.
  2. Cleanliness: Some were dirty, containing OCR errors and other incompatible non-word strings (e.g., Google Books Ngrams). These text datasets would need to be cleaned/processed to remove the unwanted entries before putting them in an app or a game.
  3. Cost: Some, especially the best ones, were paywalled (e.g., COCA) or protected by a restrictive license (e.g., NASPA). These couldn’t be used without forking over money to their creators, and their rules put hard limits on what you can do with them publicly even if you do purchase access to them.

I planned to just combine what I could, clean a dirty dataset if necessary, and call it a day.

But that third problem didn’t sit well with me, and I couldn’t stop thinking about it.

The English language is a public good, and English words themselves should never be locked behind a paywall.

Sure, particular definitions or content using the words could be proprietary, I suppose, but the mere words should be totally free. You shouldn’t have to pay someone to learn which words are considered valid English.

Rather than simply accepting this situation, I decided to fix it by making my own list, named the English OpenList (EOL), which attempted to solve every major problem with the English word lists that came before it.

To do this systematically, I chose to define English strings as structurally valid if their characters met the official Scrabble game rules (with one exception): only 1-grams (no spaces), only letters a to z (no special symbols, numbers, or other non-letter characters), and nothing shorter than two letters or longer than 15 letters. The exception: a maximum of 15 letters is extremely restrictive, so I loosened that rule to permit no more than 45 characters in the string.

And after exploring a number of word validation strategies, I eventually decided, somewhat arbitrarily, to define my words as semantically valid if they could be found in Merriam-Webster’s Collegiate or Medical Dictionaries or on Wordnik, and if they met the remaining higher-level Scrabble requirements:

  • No exclusively proper terms or names, such as “ryan” (whose only standard usage is as a proper noun/name) but not “robin” (which is both a name and a type of bird).
  • No exclusive acronyms or initialisms like “USA” (for “United States of America”), since “usa” is not a recognized word in lowercase, but not “US,” as “us” is a valid word in lowercase.
  • And no exclusive abbreviations, e.g., “prev” for “previous” but not “info” for “information,” or slang.

In January of 2026, I built the EOL through a long, meticulous process. First, I obtained a giant list of as many unique, structurally valid “candidate” words as I could find, using data mining, cleaning, and scraping, text extraction via OCR on real document scans, and structural string generation (some from rules, some with NLP). Then, I tried several approaches to validating these candidates:

  • From a source (176,222): It came from a word list, a dictionary, or a glossary of a field such as medicine. No language model or generator decided it.
  • Checked with a model (131,226): It passed a check of several steps, and a language model was one of the steps.
  • A model’s call alone (6,471): A language model judged it a word, and no other check backs that.
  • Generated by rule (31,243): The synthetic engine made it by rule, for example by adding a prefix or a suffix to a word already on the list.

Importantly, I also saved and documented the words that failed to be validated, not just the ones that succeeded.

Later in 2026, I revisited the core choices behind the EOL and made two changes:

  1. Expanding compatibility beyond Scrabble. Scrabble tournament lists understandably exclude one-letter words, like a and i, as well as strings beyond 15 characters, for reasons of fairness and practicality. But there are valid English words outside of that approved range, and outside of the 2–45 range that I had adopted, and some games with Scrabble-like rules (e.g., Wordle) might support them. So, the EOL was extended, and the Scrabble-compatible list (lengths 2 to 45) can be obtained by simply filtering out the shortest and longest entries, of which there are very few. I also noticed that some entries in the EOL had been duplicated or added by mistake, and I corrected the dataset accordingly.
  2. Creating a version without my (arbitrary) definition of validity. What makes Merriam-Webster and Wordnik so special and credible? How many dictionaries, and which ones, should a word have to appear on to be considered “valid”? Should strings with spaces, hyphens, or other keyboard characters in them be considered valid English? What is the best algorithm for classifying an English candidate word as “valid”? Answers to questions like these are not simple, and there’s no fundamental, universal law about the English language, a human invention, that you can derive to help you. But if someone does invent an English word validation method, then it might help to have a big dataset of word candidate strings, and to know which ones exist on which sources at a given time. As with the EOL, that dataset didn’t freely exist when I looked for it, either. So, I took the EOL’s valid and invalid lists and carefully loosened as many structural rules as I could, before combining them into a single list (called the “universe”) of over 10 million candidate (possibly valid) words. Then, I checked which mainstream lexical sources each entry appeared on, and used the data to construct what I call the Common English OpenList (CEOL) Universe.

The rule

The rule is short: an entry is lowercase a to z and nothing else, the pattern ^[a-z]+$, with no length bound. No capitals, spaces, hyphens, apostrophes, digits, or accents.

That makes the list deliberately not a tournament word list. It holds the 1-letter words a and i, and words longer than 45 letters, both of which tournament lists leave out. If you want their shape, the “Lengths 2 to 45” download has it.

This demo needs JavaScript. The rule is on the English OpenList’s rule page.

How a word gets on, and off

Each night, the run draws about 1,000 candidates (possibly valid words) from a pool of over 9 million strings and checks whether they exist in the Free Dictionary API. A word recognized by a dictionary is promoted to the list. A word whose lookup is refused or rate-limited simply waits for another night, and nothing records it as rejected.

The only other way a word moves is by hand, through a correction ledger. That’s how the list made its biggest correction: in August 2026, 33,594 forms its synthetic engine had made algorithmically (comparatives and superlatives, gerund plurals, verb forms, and agent plurals) were moved off the list, decided by the inflections a dictionary records for their stems.

Every one of them is queued to be checked again, because no word is ever off the list for good. A string absent from a dictionary today might be added to it tomorrow. But once a word enters the EOL, it never leaves, unless it was originally included by mistake.

What decided each word

Not every word entered the EOL the same way. Each word’s record says how it got on, sorted into the four values above.

If you’d rather not ship words a model vouched for, or words a program made, leave them out. That’s the point of keeping the record.

This chart needs JavaScript. The English OpenList’s charts show the same counts.

Night by night

The nightly run adds a few words a night, not thousands. It’s there to keep up with English, not to pad the count. The 100+ runs in the daily log, from May 14 to the present, each have a page with the words they added and where they came from.

This chart needs JavaScript. The English OpenList’s charts show the same series.

How it compares

Here’s the English OpenList next to the free lists you’re most likely to find, by what each one says about itself:

ListEntriesLicenseWhat it records per entry
English OpenList345,162MIT, for its own contributionthe word, how it got on, and usually when; updated nightly
ENABLE (2000)173,528public domainthe word
YAWL264,097public domainthe word
Moby Words II (2002)354,984 single wordspublic domainthe word
dwyl/english-wordsover 466,000the Unlicense, with the copyright left to the original publisherthe word
The official tournament lists–proprietarythe word, under license

Bigger isn’t the point. Some of those counts include entries with spaces, capitals, or hyphens, and none of them can tell you how a given word got in. If you want every candidate English string with the evidence for each, that’s a different project: the CEOL Universe, below.

The catch

A list like this is only useful if you know where it falls short, so here it is up front.

  • Lowercase a to z, nothing else. No hyphenated compounds, accented loanwords, contractions, or multiword terms. That’s by design; the CEOL Universe, below, has them.
  • Not a tournament list. It holds words that tournament lists leave out, so it won’t settle a game of Scrabble.
  • Some words rest on a model, and some were made by rule. 137,697 words were decided with a language model, 6,471 of them by the model’s call alone, and 31,243 came from the synthetic engine. Every one is marked, so you can leave them out.
  • It changes every night. If you need a list that holds still, pin a revision of the dataset.
  • No definitions. A word’s record says how it got on, not what it means. Its panel on the site links to dictionaries that do.

Use it

The list is plain text, 1 word a line, sorted. Grab it with a shell:

curl -sL -o merged_valid_words.txt \
  https://huggingface.co/datasets/ryanjosephkamp/english-openlist/resolve/main/data/merged_valid_words.txt

Or, in Python:

from huggingface_hub import hf_hub_download

path = hf_hub_download(
    "ryanjosephkamp/english-openlist",
    "data/merged_valid_words.txt",
    repo_type="dataset",
)
words = open(path, encoding="utf-8").read().split()
print(len(words))  # 345,162, as of this post

The dataset also holds every word’s record (data/merged_valid_dict.json), the candidates not on the list (data/merged_invalid_words.txt), and word-game files by length (latest/brrrdle/). The list changes whenever the nightly run publishes, so if you need it to hold still, put a revision of the dataset in place of main.

On the site, you can search the list, open any word’s record, read the daily log (with an RSS feed), and download 2 ready-made subsets: the list without the synthetic engine (313,919 words) and lengths 2 to 45 (345,157 words).

This search needs JavaScript. You can search the list on the English OpenList’s site.

Under the hood

The English OpenList is 3 things: a Python program that runs every night, a set of plain files on Hugging Face, and a static site that loads the whole list into your browser.

The nightly run: Python on GitHub Actions

  • Python 3.12, on a schedule: The run is a GitHub Actions workflow that starts at midnight UTC. GitHub runs it for free on a public repository, so the list keeps up with no server of my own.
  • Small, plain dependencies: httpx calls the dictionary APIs, tenacity retries a request politely, feedparser reads the words-of-the-day feeds, orjson handles the 280 MB record file, and huggingface_hub publishes. The lock file pins every package by its hash.
  • It fails loudly: A step that fails stops the run, and a refused or rate-limited lookup is never recorded as a rejection. A dry-run switch runs everything except the publish.
  • Corrections as CSV files: Every change made by hand is a row in a ledger in the repository, so it’s reviewed in a pull request like code, and its history is the repository’s.

The data: plain text, versioned

The list is a sorted text file, 1 word a line, because every language can read that in 1 line of code. Hugging Face hosts it for free and keeps a revision for every publish, so you can pin one; each word’s record sits beside the list as JSON.

The site: the whole list in your browser

  • Astro 7 and React 19, in TypeScript: The pages are static HTML. The search and the charts are React components that load only where they’re used.
  • A compact binary list: The list ships front-coded: since it’s sorted, each word stores only how much it shares with the word before it, plus the rest. That makes it about 8 times smaller over the wire than the text file, and it decodes in a single pass in milliseconds.
  • Search off the main thread: A Web Worker holds the decoded list as 1 flat table rather than hundreds of thousands of separate strings, so prefix, suffix, pattern, and regular-expression searches run without freezing the page.
  • Built from the dataset: A Node tool streams the dataset’s files, the 280 MB record included, into the site’s data and the daily log at build time. A deploy workflow publishes the result to Cloudflare Pages after every nightly run.

Every pull request runs the Python tests and the site’s tests and type checks on GitHub Actions.

And the CEOL Universe

The English OpenList is one answer to “which words count?” Its sibling, the CEOL Universe, keeps about 10 million candidates (everything the English OpenList took in, and more) with the evidence for each, so you can cut a list under a definition of your own. I wrote about it in its own post.