Word Chums looks like Scrabble until the scores land: a Q is worth 12, a J 11, and an L costs you 3. This free Word Chums Cheat solves your rack with the game’s own tile values, so the word it ranks first is the word that actually scores most in Chums — not in some other game. Add a starts-with, ends-with or contains filter to play off letters already on the board.
How the Word Chums Cheat works
Enter your tiles and the tool checks every word in our 359,039-word list against them: a word qualifies only if your tiles can cover its letters, tile for tile, with ? standing in for a blank. Survivors are scored with the genuine Word Chums values — A1 B5 C4 D3 E1 F5 G3 H4 I1 J11 K6 L3 M4 N2 O1 P4 Q12 R1 S1 T1 U3 V6 W6 X9 Y4 Z11 — where a letter paid for by a blank scores 0, exactly as in the game. Results are grouped by length with the best Chums scores first in each group, because a longer word is usually the better play even before the score is counted. The optional filters then cut the list by shape: starts with, ends with, or contains a letter string.
Why Chums values change the answer
Most word solvers quietly score with Scrabble values, and in Chums that mis-ranks your plays. The differences are not small: Q is 12 here against Scrabble’s 10, J is 11 against 8, Z is 11 against 10, and B, F, K, V and W are all worth more than a Scrabble player expects, while everyday letters like L (3) and M (4) also cost more. A rack solver using the wrong table will bury your best Chums word under plays that only look good in another game. This one uses the Chums table for everything — ranking, grouping and the score printed on every word.
A worked example
Feed the rack listen to the tool and it finds 156 words. The six-letter group is a five-way tie at the top: enlist, inlets, listen, silent and tinsel each score 9 — the same letters that make only 6 points in Scrabble, because Chums prices the L at 3 and the N at 2. Now add the starts-with filter set to s and the list narrows to 36 words headed by silent (9) — exactly the view you want when the board offers you an open S to build on.
Using the filters like a Chums player
The three filters mirror the three ways real plays attach to a board. Starts with is for hooks: a letter or two already sitting at the edge of a gap that your word must grow from. Ends with is for finishing moves — setting up a plural S, or landing a word against a letter that is already played. Contains is for the string you can see mid-board and must build through. Set one filter at a time and watch the top of the longest group; that is where your best legal play nearly always sits.
Limitations worth knowing
Word Chums has its own dictionary, and our list is a broad English list that is wider than any single game’s. Common words are always safe, but an occasional obscure entry here may be rejected by the game — if a word looks too strange to be real, it probably is for Chums purposes. The tool also cannot see your board: the scores are raw tile totals, and the game’s bonus squares and coin mechanics still apply on top. It solves racks of up to 12 tiles, and letters covered by a blank score 0, matching the game.
Word Chums Cheat – frequently asked questions
Is this really scored for Word Chums, not Scrabble?
Yes. The values are the Word Chums table (Q12, J11, Z11, B5, F5, K6, L3, M4, U3, V6, W6, X9). The same rack of listen scores its best word at 9 here, 8 in Words With Friends values and 6 in Scrabble values — the table matters.
How do blank tiles work?
Type ? for a blank. It can become any letter, and a letter it covers scores 0 points, as in the game itself.
Can I play off a letter already on the board?
Yes — that is what the filters are for. Use starts with for the letter your word must begin with, ends with for one it must finish on, and contains for a string it must include.
Is using a cheat tool against the rules?
Word Chums is a casual game and plenty of players treat solvers as a learning aid for spotting words they would never have seen. Whether to use one mid-game is between you and your opponent; used after a game, it is simply the fastest way to find the play you missed.
More word tools and lists
Browse the full collection on our Word Finder & Word Tools hub. You may also like the Word Unscrambler for unscored rack solving, the Word Solver which scores the same rack in Scrabble, Words With Friends and Chums side by side, and the Word Finder for filtered letter searches.
Embed this tool on your website — free
Copy the code below to add this working tool to your own page. A small credit link stays with it — that’s all we ask.
function ilmScoreWord(w, VAL) {
var s = 0;
for (var i = 0; i < w.length; i++) s += VAL[w[i]] || 0;
return s;
}
function ilmRackCounts(rack) {
var counts = {}, wild = 0;
rack = (rack || ”).toLowerCase();
for (var i = 0; i < rack.length; i++) {
var ch = rack[i];
if (ch === ‘?’ || ch === ‘*’) wild++;
else if (ch >= ‘a’ && ch <= ‘z’) counts[ch] = (counts[ch] || 0) + 1;
}
return { counts: counts, wild: wild };
}
// Rack solver: every word buildable from the rack (subset of tiles, ? = blank,
// blank-covered letters score 0), scored with VAL. opts may carry starts,
// ends, contains (lowercase strings) and exactLen (0 = any).
// Returns [{w, s}] sorted length desc, score desc, A-Z.
function ilmRackSolve(rack, words, VAL, opts) {
opts = opts || {};
var rc = ilmRackCounts(rack), counts = rc.counts, wild = rc.wild;
var total = wild;
for (var k0 in counts) total += counts[k0];
var starts = (opts.starts || ”).toLowerCase();
var ends = (opts.ends || ”).toLowerCase();
var contains = (opts.contains || ”).toLowerCase();
var exactLen = opts.exactLen || 0;
var out = [];
for (var j = 0; j < words.length; j++) {
var w = words[j];
if (w.length < 2 || w.length > total) continue;
if (exactLen && w.length !== exactLen) continue;
if (starts && w.indexOf(starts) !== 0) continue;
if (ends && w.slice(w.length – ends.length) !== ends) continue;
if (contains && w.indexOf(contains) === -1) continue;
var need = {};
for (var k = 0; k < w.length; k++) { var c = w[k]; need[c] = (need[c] || 0) + 1; }
var ok = true, deficit = 0, score = 0;
for (var L in need) {
var have = counts[L] || 0;
if (need[L] <= have) score += VAL[L] * need[L];
else {
deficit += need[L] – have;
score += VAL[L] * have;
if (deficit > wild) { ok = false; break; }
}
}
if (ok) out.push({ w: w, s: score });
}
out.sort(function (a, b) {
return b.w.length – a.w.length || b.s – a.s || (a.w < b.w ? -1 : a.w > b.w ? 1 : 0);
});
return out;
}
// Crossword pattern solver: pattern is letters plus ? or . for unknown
// squares. If len is given and longer than the pattern, the pattern is
// padded with ? on the right; if the pattern is longer than len, no match.
// Returns matching words sorted A-Z.
function ilmCrossword(pattern, words, len) {
pattern = (pattern || ”).toLowerCase().replace(/\./g, ‘?’);
var effLen = len || pattern.length;
if (pattern.length > effLen) return [];
var pat = pattern;
while (pat.length < effLen) pat += ‘?’;
var out = [];
for (var j = 0; j < words.length; j++) {
var w = words[j];
if (w.length !== effLen) continue;
var ok = true;
for (var i = 0; i < effLen; i++) {
var p = pat[i];
if (p !== ‘?’ && p !== w[i]) { ok = false; break; }
}
if (ok) out.push(w);
}
out.sort();
return out;
}
// Pattern + rack solver (Word Solver): the word must match the pattern
// positionally; letters on fixed squares are already on the board (free),
// letters on ? squares must come from the rack (? in the rack = blank tile,
// blank-covered letters score 0). Returns [{w, s}] score desc, A-Z.
function ilmPatternRackSolve(rack, pattern, words, VAL) {
pattern = (pattern || ”).toLowerCase().replace(/\./g, ‘?’);
var rc = ilmRackCounts(rack), counts = rc.counts, wild = rc.wild;
var out = [];
for (var j = 0; j < words.length; j++) {
var w = words[j];
if (w.length !== pattern.length) continue;
var ok = true, score = 0;
var needFromRack = {};
for (var i = 0; i < w.length; i++) {
var p = pattern[i];
if (p >= ‘a’ && p <= ‘z’) {
if (p !== w[i]) { ok = false; break; }
score += VAL[w[i]];
} else {
needFromRack[w[i]] = (needFromRack[w[i]] || 0) + 1;
}
}
if (!ok) continue;
var deficit = 0;
for (var L in needFromRack) {
var have = counts[L] || 0;
if (needFromRack[L] <= have) score += VAL[L] * needFromRack[L];
else {
deficit += needFromRack[L] – have;
score += VAL[L] * have;
if (deficit > wild) { ok = false; break; }
}
}
if (ok) out.push({ w: w, s: score });
}
out.sort(function (a, b) {
return b.s – a.s || (a.w < b.w ? -1 : a.w > b.w ? 1 : 0);
});
return out;
}
// Letter filter (Words With Letters): include = letters that must ALL be in
// the word (multiset: "ee" means at least two e’s); exclude = letters that
// must NOT appear. Optional exactLen, starts, ends. Returns words A-Z.
function ilmFilterWords(words, f) {
f = f || {};
var inc = (f.include || ”).toLowerCase();
var exc = (f.exclude || ”).toLowerCase();
var starts = (f.starts || ”).toLowerCase();
var ends = (f.ends || ”).toLowerCase();
var exactLen = f.exactLen || 0;
var incNeed = {};
for (var i = 0; i < inc.length; i++) {
var c0 = inc[i];
if (c0 >= ‘a’ && c0 <= ‘z’) incNeed[c0] = (incNeed[c0] || 0) + 1;
}
var excSet = {};
for (var e = 0; e < exc.length; e++) {
var c1 = exc[e];
if (c1 >= ‘a’ && c1 <= ‘z’) excSet[c1] = true;
}
var out = [];
for (var j = 0; j < words.length; j++) {
var w = words[j];
if (exactLen && w.length !== exactLen) continue;
if (starts && w.indexOf(starts) !== 0) continue;
if (ends && w.slice(w.length – ends.length) !== ends) continue;
var ok = true;
for (var x = 0; x < w.length; x++) if (excSet[w[x]]) { ok = false; break; }
if (!ok) continue;
var wc = {};
for (var y = 0; y < w.length; y++) wc[w[y]] = (wc[w[y]] || 0) + 1;
for (var L in incNeed) if ((wc[L] || 0) < incNeed[L]) { ok = false; break; }
if (ok) out.push(w);
}
out.sort();
return out;
}
// Random picker: opts {count, len (0 = any 2-15), startsWith}. rng() must
// return [0,1). Samples without replacement.
function ilmRandomWords(words, opts, rng) {
opts = opts || {};
var len = opts.len || 0;
var sw = (opts.startsWith || ”).toLowerCase();
var pool = [];
for (var j = 0; j < words.length; j++) {
var w = words[j];
if (len && w.length !== len) continue;
if (sw && w.indexOf(sw) !== 0) continue;
pool.push(w);
}
var count = Math.min(opts.count || 5, pool.length);
var picked = [];
for (var n = 0; n < count; n++) {
var idx = Math.floor(rng() * pool.length);
picked.push(pool[idx]);
pool.splice(idx, 1);
}
return picked;
}
// Scramble: Fisher-Yates shuffle of the word’s letters, retried until the
// result differs from the original (words made of one repeated letter are
// returned unchanged — none are in the game list).
function ilmScrambleWord(word, rng) {
var letters = word.split(”);
var distinct = {};
for (var d = 0; d < letters.length; d++) distinct[letters[d]] = true;
var nDistinct = 0;
for (var k in distinct) nDistinct++;
if (nDistinct < 2) return word;
for (var attempt = 0; attempt < 200; attempt++) {
var a = letters.slice();
for (var i = a.length – 1; i > 0; i–) {
var j = Math.floor(rng() * (i + 1));
var tmp = a[i]; a[i] = a[j]; a[j] = tmp;
}
var s = a.join(”);
if (s !== word) return s;
}
return letters.slice().reverse().join(”);
}
// ~150 common English words for the Word Scramble game (4-8 letters).
var ILM_GAME_WORDS = [‘apple’,’banana’,’orange’,’garden’,’planet’,’silver’,’market’,’window’,’summer’,’winter’,’spring’,’autumn’,’bridge’,’castle’,’dragon’,’friend’,’school’,’pencil’,’paper’,’river’,’ocean’,’forest’,’jungle’,’desert’,’island’,’mountain’,’valley’,’village’,’kitchen’,’bedroom’,’picture’,’camera’,’guitar’,’piano’,’violin’,’trumpet’,’basket’,’bottle’,’candle’,’mirror’,’button’,’pocket’,’ticket’,’travel’,’journey’,’holiday’,’picnic’,’breakfast’,’dinner’,’supper’,’cheese’,’butter’,’coffee’,’sugar’,’pepper’,’lemon’,’melon’,’grape’,’peach’,’mango’,’rabbit’,’turtle’,’monkey’,’tiger’,’zebra’,’panda’,’koala’,’eagle’,’shark’,’whale’,’snake’,’horse’,’sheep’,’chicken’,’spider’,’flower’,’garden’,’hammer’,’ladder’,’rocket’,’planet’,’comet’,’meteor’,’galaxy’,’nebula’,’tunnel’,’harbor’,’anchor’,’sailor’,’pirate’,’treasure’,’diamond’,’golden’,’copper’,’iron’,’steel’,’wooden’,’cotton’,’leather’,’plastic’,’magnet’,’battery’,’engine’,’wheel’,’brake’,’helmet’,’jacket’,’gloves’,’scarf’,’boots’,’socks’,’shirt’,’dress’,’skirt’,’watch’,’clock’,’phone’,’tablet’,’laptop’,’screen’,’keyboard’,’mouse’,’printer’,’speaker’,’dancer’,’singer’,’farmer’,’doctor’,’nurse’,’teacher’,’writer’,’artist’,’baker’,’driver’,’hunter’,’fisher’,’sailor’,’soldier’,’captain’,’general’,’king’,’queen’,’prince’,’knight’,’wizard’,’witch’,’giant’,’fairy’,’elf’,’dwarf’,’goblin’,’troll’,’phoenix’,’unicorn’,’mermaid’,’thunder’,’lightning’,’rainbow’,’snowflake’,’raindrop’,’sunshine’,’moonlight’,’starlight’,’breeze’,’storm’,’cloud’,’fog’,’frost’,’ice’,’snow’,’rain’,’wind’,’wave’,’sand’,’stone’,’rock’,’cliff’,’cave’,’lake’,’pond’,’stream’,’waterfall’,’meadow’,’prairie’,’savanna’,’tundra’,’volcano’,’glacier’,’canyon’,’oasis’,’lagoon’,’coral’,’pearl’,’shell’,’feather’,’wing’,’claw’,’horn’,’tail’,’mane’];
ILM_GAME_WORDS = ILM_GAME_WORDS.filter(function (w, i) { return ILM_GAME_WORDS.indexOf(w) === i; });
if (typeof module !== ‘undefined’) {
module.exports = { ILM_SCRABBLE: ILM_SCRABBLE, ILM_WWF: ILM_WWF, ILM_CHUMS: ILM_CHUMS,
ilmScoreWord: ilmScoreWord, ilmRackSolve: ilmRackSolve, ilmCrossword: ilmCrossword,
ilmPatternRackSolve: ilmPatternRackSolve, ilmFilterWords: ilmFilterWords,
ilmRandomWords: ilmRandomWords, ilmScrambleWord: ilmScrambleWord, ILM_GAME_WORDS: ILM_GAME_WORDS };
}
var WORDLIST_URL = ‘https://ilmhunt.com/wp-content/uploads/2026/10/wordlist.txt’;
var WORDS = null, LOADING = false;
function sendH(){ try { parent.postMessage({wpcId: 5212, wpcH: document.body.scrollHeight + 16}, ‘*’); } catch (e) {} }
window.addEventListener(‘load’, sendH);
function st(msg){ document.getElementById(‘status’).textContent = msg; }
function ensureWords(cb){
if (WORDS) { cb(); return; }
if (LOADING) { return; }
LOADING = true; st(‘Loading the word list (359,039 words)…’);
fetch(WORDLIST_URL).then(function(r){ return r.text(); }).then(function(t){
WORDS = t.split(/\r?\n/).filter(function(x){ return x.length > 0; });
st(‘Word list ready — ‘ + WORDS.length.toLocaleString(‘en-US’) + ‘ words.’);
cb();
}).catch(function(){ LOADING = false; st(‘Could not load the word list. Check your connection and press Find Words again.’); });
}
function render(res){
var box = document.getElementById(‘results’);
if (!res.length) { box.innerHTML = ‘<p class="none">No words match. Loosen a filter or check your letters.</p>’; sendH(); return; }
var cap = 1000, shown = res.slice(0, cap), html = ”, curLen = -1;
shown.forEach(function(x){
if (x.w.length !== curLen) {
if (curLen !== -1) html += ‘</div>’;
curLen = x.w.length;
var n = res.filter(function(y){ return y.w.length === curLen; }).length;
html += ‘<div class="grp"><h3>’ + curLen + ‘ letters — ‘ + n + ‘ word’ + (n === 1 ? ” : ‘s’) + ‘</h3>’;
}
html += ‘<span class="chip">’ + x.w + ‘<sup>’ + x.s + ‘</sup></span>’;
});
html += ‘</div>’;
if (res.length > cap) html += ‘<p class="none">Showing the best ‘ + cap.toLocaleString(‘en-US’) + ‘ — add a starts/ends/contains filter to see more of the rest.</p>’;
box.innerHTML = html;
st(res.length.toLocaleString(‘en-US’) + ‘ words found, scored with Word Chums values.’);
sendH();
}
function clean(id){ return document.getElementById(id).value.replace(/[^a-zA-Z]/g, ”).toLowerCase(); }
function run(){
ensureWords(function(){
var rack = document.getElementById(‘rack’).value.replace(/[^a-zA-Z?*]/g, ”).slice(0, 12);
if (rack.length < 2) { st(‘Enter at least 2 letters.’); return; }
render(ilmRackSolve(rack, WORDS, ILM_CHUMS, { starts: clean(‘starts’), ends: clean(‘ends’), contains: clean(‘contains’) }));
});
}
document.getElementById(‘go’).addEventListener(‘click’, run);
document.getElementById(‘rack’).addEventListener(‘keydown’, function(e){ if (e.key === ‘Enter’) run(); });
</script>
</body>
</html>
" style="width:100%;height:620px;border:0;display:block;overflow:hidden;" scrolling="no"></iframe></div>
<p><a href="https://ilmhunt.com/word-chums-cheat/" target="_blank" rel="noopener">Word Chums Cheat — Find the Best Words from Your Tiles</a> by <a href="https://ilmhunt.com/" target="_blank" rel="noopener">IlmHunt</a> — free online tools</p>
