[Userscript] Keisei 形声 Semantic-Phonetic Composition

Is anyone aware of a good source where I could read up on this aspect of Kanji? I see there are database sources in the OP but I’m looking more for books, published studies, etc.
I loved this script when I was going through WaniKani, and have recently become extremely interested in exploring the concept in more depth.


There’s a little more information on the source for a lot of this in the original phonetic-semantic composition script thread, though the link to the thesis appears to be broken, so you might have to look elsewhere for it if you want to read it. There is also a book called The Kanji Code that is based on the original thesis, which I have not yet read myself, but it might be worth checking out!


I actually just ordered the book last week (it hasn’t been delivered just yet), but the broken link from the other thread is actually what led me to try asking here :sweat_smile: Even tried looking searching around on google for Hiroko Townsend to try and find the thesis somewhere else, but haven’t had any luck yet.

1 Like

I found a couple links that might be useful! Here’s one, and here’s another. I think the first is the paper originally cited in the first version of this script, and the second link seems to be an article that was published in a journal a couple years later.

Something that’s kind of funny to me is that it seems like this WK script has actually driven a lot of people toward studying this topic in earnest. Multiple reviews for The Kanji Code on Amazon mention WK, haha!


Just saw this! You’re a saint and a scholar, thank you! :smile:


@Sinyaven Is there a way to use this without compatibility mode? Another script I use requires it off.

Are you using version 1.8.15? It should currently also work with compatibility mode disabled. What doesn’t work for you? Reviews? Lessons?

I investigated a bit more and it looks like it was a configuration error on my end rather than a compatibility mode issue. Sorry for the confusion.


I’m a little bit lost with the topic i have the script but i don’t really understand how the phonetic composition works. Can someone share a link or something where i can more about the topic? Thanks :slight_smile:

1 Like

I’m not sure what the best resource for explaining the subject is (I have several books on it, but those are going to be on the advanced side), but the general idea is that many kanji (something like 80% of the ones most people know) are composed of an element that indicates the broad meaning category the kanji belongs to, and one element that represents the sound that the kanji has.

This is often quite straightforward. The radical 氵 indicates something is related to water, and 羊 sounds like よう, so 洋 is a new character that is related to water (it means ocean, and later, by extension, other countries across the ocean) and sounds like よう.

Other times, the relationship is obscured by history. Kanji shapes change, meanings change, pronunciations change, and things that originally made sense in ancient Chinese can appear completely unrelated in modern Japanese. So that might make you scratch your head when looking at some of the listed items.

If you have more questions, I can try to answer them.


Is it possible to make it searchable for Kanji outside WaniKani, like Joyo, Jinmeiyo, Japanese social media?

It seems that non-WK kanji are also in the database, so this should be possible. The script author is not maintaining this script anymore, but they are still accepting pull requests (at least for fixes – I don’t know if they would be willing to accept new features). If you want, you could try adding this feature yourself and maybe open a pull request.

As a starting point: in wk_keisei.main.js, the line 61 is


If you change this to

this.populateKeiseiSection({kan: "嫉", phon: this.kdb.getKPhonetic("嫉")});

the Keisei section dispays info about the kanji 嫉.


I put this at the end of the UserScript. Works well for Kanji info pages.

(function () {
  'use strict';

  function keisei(k) {
    document.getElementById('keisei_explanation').textContent = '';
    document.getElementById('keisei_main_phonetic_grid').textContent = '';
      kan: k,
      phon: wk_keisei.kdb.getKPhonetic(k),

  new MutationObserver((muts) => {
    for (const mut of muts) {
      for (const n of mut.addedNodes) {
        if (n instanceof HTMLFormElement) {

    const elFormContainer = document.querySelector('#keisei_section h3');
    if (elFormContainer && !elFormContainer.querySelector('form')) {
      const elForm = document.createElement('form');
      elForm.style.display = 'inline-block';
      elForm.innerHTML = `<input type="text" lang="ja" value="${
        wk_keisei.currentSubject.kan || ''
      }" style="all:unset; margin-left:0.1em; cursor:pointer">`;
      elForm.onsubmit = (ev) => {
        const [elInput] = elForm.elements;
        const [v] = elInput.value
          .replace(/[\p{scx=Hiragana}\p{scx=Katakana}\w\s]/gu, '')
        if (v) {
      elFormContainer.append(' of ', elForm);
  }).observe(document.body, {
    childList: true,
    subtree: true,

  Object.assign(typeof unsafeWindow === 'undefined' ? window : unsafeWindow, {

Well, there aren’t contents for many Kanji, such as 繋 in 繋がり. Perhaps Kanji Outlier’s Dictionary / app is a better idea?

About the looks (Click and edit. That is a inconspicuous text input.):

I wonder why 亲 doesn’t list 新, but only shows 親。

Unfortunately, the Semantic-Phonetic Composition script has mostly stopped working for me all of a sudden; I noticed this yesterday.

I can confirm that is has been working for weeks and at least until last Tuesday but I don’t know when the problems started as I haven’t updated my main browser for Wanikani (Safari) or anything.

The good news is that is somehow still works during reviews and lessons. The bad news is that it doesn’t work on the radical and kanji overview pages anymore.

I’ve looked at this thread and other threads and tried some suggested things such as…

  • disabling all my other scripts and enabling them one by one to see if there is an issue between Keisei and another script – didn’t find anything unusual, the other scripts all work fine, only Keisei doesn’t work.

  • turning tapermonkey on and off on my browser (Safari) in the settings page – script didn’t work.
    → Weirdly enough, it also doesn’t work on Firefox (also have tapermonkey and some scripts installed there) either anymore .

  • enabling and disabling tapermonkey in my browser page – Keisei-script still didn’t work.

  • deleting and re-installing the script (latest version 1.8.16) – Keisei-script still didn’t work.

Lastly, I only activated the Keisei-script on an overview page and opened debug-mode during this. This is what was shown:

However, I’m not very tech-savvy and I don’t know how to code, so I don’t understand these reports. Could anyone explain – in a simplified way if possible – what may be preventing the script from working and if there would be a way to fix anything based on the reports?

I can also try giving more information if needed but cannot guarantee I’ll understand where to look for first…


WaniKani is currently transitioning the webpage to the React framework. Last week, they changed the Radical item pages, and it seems that today they have changed the Kanji pages. I am currently maintaining Keisei and Niai and will try to make them compatible to the new item pages as soon as possible.

EDIT: I have created a pull request with the fixes. It might take a few days until the pull request gets accepted. Afterwards, your script manager should update the script automatically.


I didn’t know about the changes that are taking place within the framework of the webpage, so it is safe to assume that this is why the script was not working the last few days. Thank you for telling me.

On that note I also want to say a big thank you for maintaining both the Keisei and the Niai script – both of which are great scripts which I’ve found very helpful and informative on my WK journey thus far. The same goes for the creator, of course, though they are not active on the forums anymore from what I’ve seen.


Version 1.8.17 of Keisei with the fixes for the new kanji item page should be available now. It uses Open Framework to include jQuery, so you need to have Open Framework installed for it to work. If there are still problems, let me know.


I just looked at the overview pages and can confirm that it’s working again. Thank you so much for the updates! :slightly_smiling_face:


I am not sure how Keisei normalize Radical images, but it seems to already work for some images.

I updated External Definition script lately to support image radicals, so I found out how much Keisei already supported some Radical images. My lookup maps are the following, and so I updated in A List of WaniKani’s Radical Names vs More Common Radical Names - #2 by Belthazar

  const radicalMap = {
    Gun: ['𠂉'],
    Leaf: ['丆'],
    Beggar: ['丂'],
    Spikes: ['业'],
    Kick: ['𧘇'],
    Viking: ['𤇾', '𦥯'],
    Cape: ['𠃌'],
    Hills: [],
    Gladiator: ['龹'],
    Pope: [],
    Spring: ['𡗗'],
    Squid: ['㑒', '僉'],
    Yurt: [],
    Chinese: ['𦰩', '堇'],
    Bear: ['㠯'],
    Blackjack: ['	龷'],
    Trash: ['𠫓'],
    Tofu: [],
    Creeper: [],
    Bar: ['㦮', '戔'],
    Saw: ['巩'],
    Zombie: ['袁'],
    Explosion: [],
    Morning: ['𠦝', '龺'],
    'Death Star': ['俞'],
    Comb: [],
    Elf: [],
    Coral: ['丞'],
    Cactus: [],
    Satellite: ['䍃'],
    // Except this one; but it's a smaller radical not elsewhere described.
    Psychopath: ['鬯'],