[Userscript] Level Duration 2.0

:warning: This is a third-party script/app and is not created by the WaniKani team. By using this, you understand that it can stop working at any time or be discontinued indefinitely.

This script replaces the original Level Duration script. Unlike the previous one, this script fetches your level unlock date from the API, so it is much more accurate. To do this it relies on WKOF, so you will need to install that first for this to work.

There are a couple of different display options for this script. If you have been on your current for say 4 days and 2 hours, you can choose from these options:

4 days 2 hours
4.1 days on level
4.1 days
4d 2h
4日2時 (in the FangSong font)


Available at


Let’s see if my browser can handle one more script… :smiling_imp:


I like it, very sleek, thanks a lot :slight_smile:

1 Like

Nice! I think I’ll switch over to this one but probably make a local modification to make it look a bit more like the old one but without the extra spacing which is a good idea.

Was thinking of something like:

.level-duration {
    text-align: center;
    color: #999 !important;
    margin-top: -2px;
    font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
    text-shadow: 0 1px 0 #ffffff;

And damn it, I just went from 18 days to 19.3 days after that switch. Somehow I didn’t want to know that… 57


I like those CSS changes. I should probably have made the text exactly like the other text from the start. I’ll update the script with that CSS incorporated, but I’ll leave the text as “[number] days on level”.


I’m not sure if WKOF supports it (I think it does), but you should look at the level_progressions endpoint for API v2. We’ve been tracking people’s progress on levels for a while, and those records should contain all the goodness. You can compare when they leveled up (unlocked_at) to when they finished their first lesson (started_at) without having to scan all their assignments for the level. :slight_smile:


Oh, that’s neat, thank you. I must have missed this when I scrolled through the documentation. It looks as though you are adding indexed arrays as one levels up; is it correct to fetch unlocked_at for the current level this way? I assume total_count refers to the number of recorded levels.

//array contains the /level_progressions endpoint data
date = array.data[array.total_count - 1].data.unlocked_at

Damn this script made me cry


It’s alright, we’re not all speed demons. I’ll fix it taking up two lines in the next update.


Thank you for this!

I never used the original, but with my reset the stats site isn’t accurate with this yet and I’d actually been planning to start a spreadsheet just to try and keep track myself for a rough idea, and this is a million times better.

1 Like

That’ll work! If you need the whole object, there’s always:

var latest_level_up = array.data.pop();
// then you can do latest_level_up.unlocked_at or latest_level_up.started_at

I’d suggest the started_at attribute for calculating the time on the level, though. That’s populated when someone does their first lesson for that level, so completionists who like finishing all their vocab before moving on won’t get the wrong impression. :wink:


Thanks! I already updated the script and it’s even neater now. Down to 50 lines compared to the old version’s 300 lines. I don’t know about using started_at though. unlocked_at feels more natural to me, as a user. I’ll ask around and see what people prefer, thanks for the suggestion.


1 Like

How would I increase the spacing like the old script? I really liked the formatting.

1 Like

You mean you would like some extra margin below the text?

If yes, you could override the script to change the part that looks like this:

 '    .level-duration {' +
			 '        text-align: center;' +
			 '        color: #999 !important;' +
			 '        font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;' +
			 '        text-shadow: 0 1px 0 #ffffff;' +
			 '        margin-top: -2px;' +
			 '        margin-bottom: 14px;' +
			 '    }' +

The last row with “margin-bottom: 14px” is not in the script at the moment. If you add this, you would have some extra spacing on the bottom. You can play with those -2px and 14px values a bit and adjust it how you think looks best to you.


Thank you! Haven’t used the original but this is great =)

1 Like

Awesome! Thank you!

Thank you, that’s a useful script.

Are you aware that it does not print on the mobile version of the website (Firefox 60/ Android 7)? I suppose that is because the “append” instruction does not find any matching pattern.


Indeed I was not. That’s interesting. It works for me with Firefox 59 and Android 6. Are you using the mobile version of the site? I can’t see the level circle at all with the mobile version.

yes, I use the mobile version of the site, because of its compact design.
Yet, as you mention, it does not seem to have any level circle by default.

If you’d like I could probably add the duration under the reviews circle on mobile

1 Like