Skip to main content
KWordle is designed to run on Kindle e-readers, which have unique technical requirements. This page covers the key technical implementation details.

ES5 JavaScript Compatibility

KWordle uses ES5 JavaScript for maximum compatibility with older Kindle models running WebKit-based browsers from 2011-2015.

Why ES5?

Older Kindle models (5.6.1.1 and earlier) run WebKit browsers that don’t support:
  • Arrow functions (() => {})
  • let and const declarations
  • Template literals
  • Destructuring
  • Classes
  • Promises and async/await

ES5 Patterns Used

Variable declarations use var instead of let/const:
var gameState = {
  targetWord: "",
  currentAttempt: 0,
  // ...
};
Object constants instead of enums:
const states = {
  empty: 0,
  filled: 1,
  correct: 2,
  present: 3,
  absent: 4,
  unused: 5
};
Traditional function syntax:
function initGame() {
  log("Initializing KWordle game...");
  // ...
}
Traditional for loops instead of array methods:
for (var i = 0; i < gameState.maxAttempts; i++) {
  var row = [];
  for (var j = 0; j < gameState.wordLength; j++) {
    row.push({
      letter: "",
      state: states.empty
    });
  }
  gameState.letterGrid.push(row);
}

Polyfills

The application includes js/polyfill.min.js to provide modern JavaScript features:
<script src="js/polyfill.min.js"></script>
This polyfill adds support for:
  • Array.prototype.indexOf
  • Array.prototype.forEach
  • String.prototype.trim
  • Object.keys
  • JSON.parse and JSON.stringify

E-ink Display Optimizations

Kindle’s e-ink displays are black and white with limited refresh rates. KWordle is optimized for this:

Grayscale Color Scheme

.grid-cell.correct {
  border: 2px solid #888;
  background-color: #777777; /* Dark gray for correct */
}

.grid-cell.present {
  border: 2px solid #888;
  background-color: #dddddd; /* Light gray for present */
}

.grid-cell.absent {
  border: 2px solid #888;
  background-color: #ffffff; /* White for absent */
}

Visual Indicators

Symbols provide additional clarity beyond color:
if (cell.state === states.correct) {
  // Right place - filled square
  cellDiv.innerHTML = cell.letter + "<span class='indicator correct-indicator'>■</span>";
} else if (cell.state === states.present) {
  // Wrong place - empty square
  cellDiv.innerHTML = cell.letter + "<span class='indicator present-indicator'>□</span>";
}
The indicator key is always visible:
keyDiv.innerHTML = '<span>■ = Correct spot</span> <span>□ = Wrong spot</span> <span>× = Not in word</span>';

Contrast and Readability

body {
  background-color: #f5f5f5;
  -webkit-user-select: none; /* Prevent text selection */
  user-select: none;
  max-width: 700px;
}

.grid-cell {
  font-size: 24px;
  font-weight: bold;
  border: 2px solid #d3d6da; /* High contrast borders */
}

Minimal Animations

No animations or transitions are used to avoid e-ink ghosting and slow refresh artifacts.

localStorage Usage

KWordle uses localStorage to persist game statistics across sessions.

Storage Structure

{
  "kwordle-stats": {
    "gamesPlayed": 0,
    "gamesWon": 0,
    "currentStreak": 0,
    "maxStreak": 0,
    "guessDistribution": [0, 0, 0, 0, 0, 0]
  }
}

Storage Quota

The app requests 25MB of localStorage in config.xml:73:
<kindle:asset key="LocalStorageQuota" value="26214400" />

Reading and Writing Statistics

function loadStatistics() {
  var stats = localStorage.getItem("kwordle-stats");
  if (stats) {
    return JSON.parse(stats);
  } else {
    return {
      gamesPlayed: 0,
      gamesWon: 0,
      currentStreak: 0,
      maxStreak: 0,
      guessDistribution: [0, 0, 0, 0, 0, 0]
    };
  }
}

function saveStatistics(stats) {
  localStorage.setItem("kwordle-stats", JSON.stringify(stats));
}

Statistics Update Logic

function updateStatistics(won) {
  var stats = loadStatistics();
  stats.gamesPlayed++;
  
  if (won) {
    stats.gamesWon++;
    stats.currentStreak++;
    stats.guessDistribution[gameState.currentAttempt - 1]++;
    
    if (stats.currentStreak > stats.maxStreak) {
      stats.maxStreak = stats.currentStreak;
    }
  } else {
    stats.currentStreak = 0;
  }
  
  saveStatistics(stats);
}

Chromebar Integration

KWordle integrates with Kindle’s Chromebar UI system to provide native navigation.

Configuration

The Chromebar is configured in index.html:14-52:
var chromebar = {
  "appId": "xyz.kurizu.kwordle",
  "topNavBar": {
    "template": "title",
    "title": "KWordle",
    "buttons": [
      {
        "id": "KPP_MORE",
        "state": "enabled",
        "handling": "system"
      },
      {
        "id": "KPP_CLOSE",
        "state": "enabled",
        "handling": "system"
      }
    ],
  },
  "systemMenu": {
    "clientParams": {
      "profile": {
        "name": "default",
        "items": [
          {
            "id": "KWORDLE_RELOAD",
            "state": "enabled",
            "handling": "notifyApp",
            "label": "Reload",
            "position": 0
          }
        ],
        "selectionMode": "none",
        "closeOnUse": true
      }
    }
  }
};
window.kindle.messaging.sendMessage("com.lab126.chromebar", "configureChrome", chromebar);
window.kindle.appmgr.ongo = function (ctx) {
  update();
  window.kindle.messaging.receiveMessage("systemMenuItemSelected", function (type, id) {
    switch (id) {
      case "KWORDLE_RELOAD":
        window.location.reload();
    };
  });
};
This adds a “Reload” option to the system menu that refreshes the app.

Kindle Widget Configuration

The config.xml file defines the app as a Kindle widget:

App Identity

<widget id="xyz.kurizu.kwordle" version="1.0" viewmodes="application" 
  xmlns="http://www.w3.org/ns/widgets"
  xmlns:kindle="http://kindle.amazon.com/ns/widget-extensions">
  <name xml:lang="en">KWordle</name>
  <description xml:lang="en">KWordle</description>
  <content src="index.html" />
</widget>

Permissions

<kindle:permissions>
  <kindle:permission name="local-port-access" />
</kindle:permissions>

Gesture Support

<kindle:gestures>
  <kindle:param name="tap" value="yes" properties="fire_on_tap:1 max_updown_delta:0" />
  <kindle:param name="swipe" value="yes" />
</kindle:gestures>

Messaging Integration

<kindle:messaging>
  <kindle:app name="com.lab126.pillow" value="yes" />
  <kindle:app name="com.lab126.chromebar" value="yes" />
  <kindle:app name="com.lab126.readnow" value="yes" />
</kindle:messaging>
This allows the app to communicate with Kindle’s system components.

Browser Compatibility

KWordle targets:
  • Kindle firmware 5.6.1.1 and older (legacy builds)
  • Kindle firmware 5.7.0 and newer (modern builds)
  • WebKit-based browsers from 2011-2024
The app is tested on:
  • Kindle Paperwhite (all generations)
  • Kindle Basic
  • Kindle Oasis
  • Desktop browsers (for development)