Most computer keyboards feature a small integrated LED light, indicating the current input mode, as controlled with the CAPS LOCK button.

enter image description here

Your task is to blink it:

  • Turn it on;
  • Wait for 0.5 (+/-0.1) seconds;
  • Turn it off again.

Video footage of the LED blinking is highly appreciated !


  • You can blink a different LED (e.g. Scroll Lock, Num Lock, Wi-Fi status etc), if you wish, but it must be physically located on your keyboard;

  • If your language is missing a subsecond sleep command, your program may use a 1 second delay instead, at a penalty of +2 bytes (that's for 0.);

  • Your program must blink at least once, what happens afterward is up to you, i.e. it can continue to blink (in which case you must wait for the same delay, before turning it on again), or halt e.t.c.;

  • If the chosen LED is ON by default, on your system, you can assume that it has been explicitly switched off (e.g. manually), before the program is run;

  • This is , the shortest answer in bytes wins.


var QUESTION_ID=110974,OVERRIDE_USER=61904;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

  • 84
    \$\begingroup\$ Cheating answer that doesn't quite work: on a Linux system, intentionally crash the kernel. Linux's equivalent of a BSOD flashes the Caps Lock light, just in case the crash also took down the video hardware and you can't see the BSOD report onscreen. Unfortunately, as far as I can tell it flashes a little too fast to be an eligible answer. This would lead to a (somewhat malicious) 14-byte solution if it were allowed. \$\endgroup\$ – user62131 Feb 22 '17 at 20:59
  • 57
    \$\begingroup\$ Now blink it in Morse code: "Help, I'm trapped in a keyboard factory!" \$\endgroup\$ – mbomb007 Feb 22 '17 at 22:48
  • 12
    \$\begingroup\$ @ais523 my laptop will do that if I shake it (0 bytes). Too fast tho... \$\endgroup\$ – Tim Feb 22 '17 at 23:35
  • 18
    \$\begingroup\$ The capslock key on a C64 is a mechanical switch. Blinking that might be a bit tricky... \$\endgroup\$ – Mark Feb 23 '17 at 0:56
  • 8
    \$\begingroup\$ Now I'm wondering whether the low-battery LED on my wireless keyboard flashes at the correct rate. If so: zero bytes. \$\endgroup\$ – Roger Lipscombe Feb 23 '17 at 10:24

32 Answers 32


Befunge (BEF32), 390 334 305 bytes

This is really silly, but as long as this site accepts the notion that the interpreter defines the language, I might as well abuse the rule. This code only works in Kevin Vigor's Win32 Befunge-93 Implementation, version 1.01 (I think the only version available). You can download the binary here.

Sleep kernel32.dll keybd_event user32.dll

Now normally you wouldn't expect this sort of challenge to be possible in a Befunge, but BEF32 is a Win32 port of a very old version of the reference implementation, and back then there was no bounds checking on the p (put) command. This effectively allows us to write to any location in memory, which ultimately lets us force the interpreter to execute arbitrary machine code.

Now we can't actually alter any of the existing code, since the .text section of the executable won't have write permissions. However, we can trick the system into executing an address in the .data section, by writing that address into the the runtime library's atexit table (at least I suspect that's what it is). The end result is that our code is automatically executed when the interpreter exits.

This relies on the fact that the executable is loaded at a fixed address, so we know exactly where everything is in memory - it assumedly wouldn't work if you overrode the default ASLR settings. It also relies on the .data section being executable, despite not having the executable attribute set, so again it most likely wouldn't work if you overrode the default DEP settings.

The code itself is essentially a copy of Mego's keybd_event technique translated into machine code:

6823B84000         push "keybd_event"
682FB84000         push "user32.dll"
6810B84000         push "Sleep"
6816B84000         push "kernel32.dll"
BB02000000         mov  ebx,2
89C7               mov  edi,eax
FF1594D14000       call LoadLibraryA
50                 push eax
FF1590D14000       call GetProcAddressA
4B                 dec  ebx
75EE               jnz  initloop
89C6               mov  esi,eax
6A00               push 0
6A01               push 1
6A45               push 69
6A14               push 20
FFD6               call esi
6A00               push 0
6A03               push 3
6A45               push 69
6A14               push 20
FFD6               call esi
68F4010000         push 500
FFD7               call edi
EBE3               jmp  flashloop

This version of the code continues flashing forever (or at least until you kill the process), since that turned out to be easier to golf than a single flash.

And since everyone is posting animations, this is an approximation of what it looks like on my keyboard.

Animation of the capslock light flashing

  • 30
    \$\begingroup\$ People usually abuse rules in order to make life easier for them, but those are not Befunge coders :) \$\endgroup\$ – Aaron Feb 23 '17 at 15:08
  • 21
    \$\begingroup\$ Never expected an esolang answer to this challenge +1 \$\endgroup\$ – zeppelin Feb 23 '17 at 16:58
  • 9
    \$\begingroup\$ This is now my favourite answer on this site \$\endgroup\$ – Cruncher Feb 23 '17 at 17:56
  • 2
    \$\begingroup\$ Excellent implementation! \$\endgroup\$ – Daniel Feb 24 '17 at 15:20
  • 3
    \$\begingroup\$ @JamesHolderness So? This is a great answer, even if it is long. \$\endgroup\$ – NoOneIsHere Jul 1 '17 at 15:34

AutoHotkey, 29 26 bytes

Thanks to @Dane for saving 3 bytes


I originally chose NumLock because it's one character shorter than CapsLock. The GIF below reflects that condition. It's the same effect as the altered code above. I could have gone with VK90 above to make the GIF still be accurate but aligning with the original challenge felt better.


In honor of mbomb007's comment, here's a morse code message in 239 bytes:


Here are the first 30 seconds of that message:


  • 3
    \$\begingroup\$ How about send,{vk14} instead to shave off 3 bytes? Bonus: you'd be blinking the CapsLock. \$\endgroup\$ – Dane Feb 27 '17 at 11:35

GFA-Basic 3.51 (Atari ST),  61 56 43  35 bytes

This code will make the floppy drive LED blink forever at the required rate (PAUSE 25 = pause for 25 / 50 second).

This would probably be shorter in assembly, but I don't have the appropriate tools at my fingertips. This is the size of the GFA-Basic listing once saved in .LST format and manually edited to remove useless whitespace, rename instructions to shorter strings and replace each CR+LF with a simple CR. Note that a final CR is required.

i=i XOR2
SP &HFF8802,i
PA 25

Will automatically expand to:

  i=i XOR 2
  SPOKE &HFF8802,i
  PAUSE 25

SPOKE is a supercharged POKE that first puts the 68000 in supervisor mode, so that it's allowed to access restricted memory areas (here: the register write address of the YM2149 soundchip, which is also responsible for some other I/O).

And yes: the LED is physically located on the keyboard ... I suppose.

ST Floppy LED

I don't have access to a real ST right now, so this is just a mockup.

  • 7
    \$\begingroup\$ Floppy drive! Wow! \$\endgroup\$ – David Conrad Feb 23 '17 at 14:56
  • 12
    \$\begingroup\$ Hand-drawn red circle missing ... \$\endgroup\$ – Hagen von Eitzen Feb 23 '17 at 15:06

fish + ckb, 56 54 bytes

while cd;echo rgb (random)|tee /d*/*/*/c*;sleep .5;end

Blinks my entire keyboard in random colors, though since the number isn't 6 hex digits long it's a bit limited.

And yes, that shell glob is potentially dangerous. Works On My Machine™

Bonus script, 8 months later: This will go through all colors. Not golfed.

while true
        echo rgb (printf '%06x' (random 0 16777215)) | tee /dev/input/ckb*/cmd > /dev/null
        sleep 0.5
  • 13
    \$\begingroup\$ Which keyboard is it? lol \$\endgroup\$ – Mc Kernel Feb 24 '17 at 10:01
  • 1
    \$\begingroup\$ @McKernel bump curious as to what keyboard that is as well \$\endgroup\$ – CraigR8806 Feb 24 '17 at 12:24
  • 3
    \$\begingroup\$ K70 RGB with custom keycaps - unascribed.com/f/67209fe8_keyboard_design.svg \$\endgroup\$ – Una Feb 24 '17 at 22:06
  • 6
    \$\begingroup\$ Bonus points for going above and beyond by making the entire keyboard blink. \$\endgroup\$ – Mast Feb 26 '17 at 20:07
  • \$\begingroup\$ tee /d*/*/*/c*? Bonus points for being liable to brick some poor sod's computer in the future when this inevitably expands to something important. (EFI variables anyone? Maybe there'll be something like /dev/efi/vars/cpu_type) \$\endgroup\$ – user253751 Mar 17 '18 at 7:13

Bash + amixer, 45 Bytes

a() { amixer set Master toggle
a;sleep .5;a

Blinks the mute light on my keyboard.

  • 17
    \$\begingroup\$ a()(amixer set Master toggle;sleep .5;a) or amixer set Master toggle;sleep .5;$0 as a full program are a bit shorter. \$\endgroup\$ – Dennis Feb 23 '17 at 1:14

C (Windows), 79 bytes



keybd_event is a (deprecated) Windows API function to send a keyboard event (keyup or keydown). 20 is the code for the Caps Lock key, 69 is the hardware scan code (I have no idea what that means), and 1 means keydown and 3 means keyup. A keypress is simulated by sending a keydown event immediately followed by a keyup event. One keypress is sent to turn on Caps Lock, then the program sleeps for 500 milliseconds, and then another keypress is sent to turn Caps Lock back off.

Thanks to Steadybox for a bunch of bytes saved

  • 1
    \$\begingroup\$ Given this is C, can you not declare int keybd_event();? \$\endgroup\$ – Neil Feb 22 '17 at 21:54
  • \$\begingroup\$ @Neil It would be void keybd_event();, and I also need void Sleep(); from windows.h. Those two declarations together are longer than the include. \$\endgroup\$ – Mego Feb 22 '17 at 21:57
  • 1
    \$\begingroup\$ 79 bytes: #include<windows.h> k(n){keybd_event(20,69,n,0);}f(){k(1);k(3);Sleep(500);f();} \$\endgroup\$ – Steadybox Feb 22 '17 at 22:02
  • 2
    \$\begingroup\$ Sure, but for primitive types, C doesn't care about the mismatch if you never use the result. \$\endgroup\$ – Neil Feb 22 '17 at 23:37
  • 6
    \$\begingroup\$ Scan codes are what your keyboard sends over the wire at the lowest level. Their values are based on positions in a standard layout because doing that let them make the keyboard as dumb as possible and without having to wire each key up (limitations of this design are part of why cheaper keyboards can only return a few simultaneous keystrokes - the baseline USB keyboard interface then baked the limitation into the vast majority of keyboards about 20 years ago by designing to the min std) at the cost of offloading a translation step onto the host computer. en.wikipedia.org/wiki/Scancode \$\endgroup\$ – Dan is Fiddling by Firelight Feb 23 '17 at 1:15

MATLAB, 146 136 70

Thanks to @Poke for removing 66 bytes!

r=java.awt.Robot;while 1

This uses Matlab's ability to call Java classes. The Num Lock light is blinked in a loop by programmatically pressing and releasing Num Lock.

Video or it didn't happen.

  • 9
    \$\begingroup\$ Can you use 144 instead of java.awt.event.KeyEvent.VK_NUM_LOCK? CAPS_LOCK would be 20 \$\endgroup\$ – Poke Feb 22 '17 at 21:30
  • 2
    \$\begingroup\$ @Poke Yes! There go 66 bytes!! \$\endgroup\$ – Luis Mendo Feb 22 '17 at 21:36
  • 7
    \$\begingroup\$ Funny that it's shorter than the java answer \$\endgroup\$ – Matsemann Feb 23 '17 at 20:19

x86 machine code for PC (e.g. MS-DOS COM file), 27 bytes

This machine code (displayed here with a Unicode rendering of the usual CP437 of PC BIOS) will blink the CAPS LOCK indicator forever on a PC:


The code has been made so it contains no NULL bytes, and can thus be typed with the keyboard (using the Alt+XXX trick for extended characters) to create a COM file (e.g., using the COPY CON blink.com command under MS-DOS, in which case the output file will have to contain a spurious 28th byte, the ^Z (EOF) character required to stop the copy operation).

The effect is achieved by directly sending commands to the keyboard controller of the PC (port 60h) to set the LED state (as a side-effect, it might set Num Lock and Scroll Lock LEDs to a random non-blinking state). The timing, to minimize the number of instructions, is achieved by using the countdown timer maintained by the BIOS at address 0040:0040 (it decrements every 54.925 ms, with 9 cycles the blinking cycle is 494.3 ms, which is within the allowed margin) — this counter is normally used by the BIOS to stop the floppy disk motor; as the floppy drive is not used by the program and the code is assumed to run in a single-task environment (e.g. DOS), playing with the floppy motor timer is not an issue.

The code runs fine under MS-DOS (tried with VirtualBox, it should also run fine on real hardware, although I didn't have the time yet to make a bootable MS-DOS USB stick to test). As it doesn't rely on any OS functions, it can even run without the operating system (e.g., by placing it in the boot sector of a disk). It requires at least a 80186 processor to run, because of the "immediate push" instructions used to shorten the code of some bytes.

Assembly source code:

  PUSH 0x40               ; pushes 0x0040 (BIOS data segment) on the stack
  POP DS                  ; pops it into DS segment selector
  MOV SI, DS              ; copies DS to SI (timer counter is nicely placed at 40:40)
  PUSH 0x60               ; pushes 0x0060 (kbd controller port) on the stack
  POP DX                  ; pops it to DX
  MOV AL, 0xED            ; 8042 keyboard controller 'set mode indicators' command
  OUT DX, AL              ; outputs the command to the keyboard contr oller
  MOV AL, BL              ; copy BL register to AL
  OUT DX, AL              ; outputs LED state to keyboard controller
  XOR BL, 4               ; toggles bit 2 (CAPS LOCK) for next iteration
  MOV BYTE PTR[SI], 0x0A  ; sets floppy motor countdown timer to 10
  CMP BYTE PTR[SI], 0x01  ; checks if timer reached 1
  JE loop                 ; if yes, time for next iteration
  JMP wait                ; if not, checks again

Hexadecimal dump of the assembled code:

6A 40 1F 8C DE 6A 60 5A B0 ED EE 88 D8 EE 80 F3 04 C6 04 0A 80 3C 01 74 EF EB F9

Here is the result running under MS-DOS in VirtualBox (doesn't work with DosBox, presumably because the keyboard controller is not completely emulated):

Blinking CAPS LOCK

(sorry for the shaky video).


SmileBASIC, 36 23 bytes


Blinks the microphone status light. (video coming soon)


Python2 - 108 bytes

Does the capslock key. Interestingly, this actually turns on just the LED itself without affecting the keyboard or pressing the key. You can change the 4 at the end to 2 to do numlock. 6 does both.

import fcntl,os,time;exec"fcntl.ioctl(os.open('/dev/console',os.O_NOCTTY),19250,%d);time.sleep(.5);"*2%(4,0)
  • \$\begingroup\$ Looks like I got an error: Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<string>", line 1, in <module> IOError: [Errno 25] Inappropriate ioctl for device \$\endgroup\$ – haykam Feb 26 '17 at 17:12
  • \$\begingroup\$ @haykam are you on Windows? \$\endgroup\$ – Maltysen Feb 26 '17 at 18:44
  • 1
    \$\begingroup\$ No, I'm on macOS Sierra Version 10.12.1 (16B2555). \$\endgroup\$ – haykam Feb 26 '17 at 19:33

shell+numlockx, 40 35 bytes

[Saved 5 bytes thanks to Ryan.]

Continually blinks the NumLock light on unixish systems.

numlockx toggle;sleep .5;exec sh $0

Single blink, 33 bytes

numlockx on;sleep .5;numlockx off
  • 1
    \$\begingroup\$ You can use exec sh $0 instead of while to save 5 bytes, or sh $0 if creating processes forever is considered okay. \$\endgroup\$ – Ry- Feb 22 '17 at 22:38
  • 2
    \$\begingroup\$ watch -n0.5 numlockx toggle for 27 bytes. \$\endgroup\$ – Tejas Kale Feb 25 '17 at 18:11
  • \$\begingroup\$ For a different flavour of the above, on interactive shells, you could type in: numlockx toggle;sleep .5;!# (27 bytes) for a single blink . !# is the history expansion event replaced by everything typed so far in the command line. \$\endgroup\$ – init_js Mar 17 '18 at 13:08
  • \$\begingroup\$ in the single blink command, the on can be omitted. it's the default. \$\endgroup\$ – init_js Mar 17 '18 at 13:20
  • \$\begingroup\$ With assignments, no tricks: f=numlockx;$f;sleep .5;$f off (29). And (an inferior) looping version using recursion: g(){ f=numlockx;$f toggle;sleep .5;g;};g (40). \$\endgroup\$ – init_js Mar 17 '18 at 13:55

PowerShell, 71 bytes

for(){(New-Object -c WScript.Shell).SendKeys('{NUMLOCK}');sleep -m 500}


  • Blinks forever
  • Uses NUM LOCK to save a byte.
  • \$\begingroup\$ "If your language is missing a subsecond sleep command..." - doesn't sound like it's missing from PowerShell. \$\endgroup\$ – Dane Feb 27 '17 at 3:37
  • \$\begingroup\$ @Dane I've asked the poster for clarification. If electing to accept the penalty is not allowed I will revert it. \$\endgroup\$ – briantist Feb 27 '17 at 4:32
  • \$\begingroup\$ @Dane rolled back. \$\endgroup\$ – briantist Feb 27 '17 at 14:57
  • \$\begingroup\$ How come sleep .5 doesn't work here? I tried it and it seems to go at like 5ms but I thought by default it's (-s) so it would be 0.5 s? \$\endgroup\$ – Jake Harry Feb 28 '17 at 3:11
  • 1
    \$\begingroup\$ @JakeHarry: The -Seconds parameter is an int, so 0.5 will be converted to int, which results in 0 (round to even is the default rounding mode). So you're not sleeping at all (results in a delay of about 1000 ticks here, so 10 µs). Fairly basic conversion and parameter binding rules in PowerShell. \$\endgroup\$ – Joey Feb 28 '17 at 7:13

VBS, 75 bytes

wscript.sleep 500

Repeatedly blinks Num Lock key, as numlock is 1 byte shorter than capslock.


C#, 215 202 198 195 185 bytes

Without realising I have done the "same" code as this answer by @Mego, go check it out!.

[System.Runtime.InteropServices.DllImport("user32")]static extern void keybd_event(int v,int s,int f,int e);n=>{for(n=0;;System.Threading.Thread.Sleep(125))keybd_event(20,69,n++&2,0);};

Saved 13 bytes thanks to @Metoniem
Saved 10 bytes thanks to @VisualMelon

Here's a full formatted version showing it working:

class P
    static extern void keybd_event(int v, int s, int f, int e);

    static void Main()
        System.Action<int> a = n =>
            for (n = 0; ; System.Threading.Thread.Sleep(125))
                keybd_event(20, 69, n++ & 2, 0);


For bonus fun change n++ & 2 to n+=2 & 2 and watch the num lock and caps lock keys alternate in flashing on and off. I have no idea why that happens because it shouldn't but it looks "cool".

  • \$\begingroup\$ Wait, you're using System; but as far as I can tell you're not actually using anything directly from the System namespace? I think you can remove that. \$\endgroup\$ – Metoniem Feb 23 '17 at 10:50
  • \$\begingroup\$ @Metoniem Good spot the signature for the keybd_event method is actually void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);. I releasise I could remove the UIntPtr's after posting and have them as int's and just forgot to remove the using. \$\endgroup\$ – TheLethalCoder Feb 23 '17 at 10:52
  • 1
    \$\begingroup\$ Ahh, I see haha, stuff like that happens! Nice answer man :) \$\endgroup\$ – Metoniem Feb 23 '17 at 10:53
  • \$\begingroup\$ I think you really should name and type the two 'functions': you refer to k in one, but it is clearly undefined. Not checked, but I think you'd be better off having one call to keybd_event in an unbraced for loop, I should think: for(int i=0;;...Sleep(250))keybd_event(i++&2) or something. \$\endgroup\$ – VisualMelon Feb 23 '17 at 11:38
  • \$\begingroup\$ @VisualMelon Thanks, I have updated the code, had to alter the sleep to get the timing right though :) \$\endgroup\$ – TheLethalCoder Feb 23 '17 at 11:56

Java 7, 121 118 113 bytes

void a()throws Exception{java.awt.Robot r=new java.awt.Robot();r.keyPress(20);r.delay(500);r.keyRelease(20);a();}

A single press and release just triggers the state; it doesn't blink it. Thus we may as well loop it and it looks like recursion is the cheapest manner of doing that.

  • 1
    \$\begingroup\$ What a pity I don't have a QBasic interpreter here! Because it is done using a Poke instruction! \$\endgroup\$ – sergiol Feb 23 '17 at 1:40
  • \$\begingroup\$ Does this get tail-call optimized or will this eventually exceed the call stack limit? \$\endgroup\$ – Cyoce Feb 24 '17 at 1:09
  • \$\begingroup\$ @Cyoce I don't think Java has tail call optimization until Java 9 so this eventually hits the recursion depth limit but that's ok because I only needed to blink the light once :] \$\endgroup\$ – Poke Feb 24 '17 at 2:09
  • 1
    \$\begingroup\$ I mean that you can put the entire code into a lambda, which loses the function declaration overhead. Kind of like: ()->for(;;){java.awt.Robot r=new java.awt.Robot();r.keyPress(20);r.delay(500);r.keyRelease(20);}, which is a saving of 18 bytes due to the 4-character lambda declaration overhead. \$\endgroup\$ – Tamoghna Chowdhury Feb 24 '17 at 14:44
  • 1
    \$\begingroup\$ One more reason I'm not going back! ;) In all seriousness, just change the answer to Java 8 and go into double-digit scores. Install it if you don't have it already for testing. \$\endgroup\$ – Tamoghna Chowdhury Feb 24 '17 at 17:03

JavaScript, 82 bytes

Credit goes to @FinW actually, I just changed old function to new ES6 arrow function in order to save some bytes. And becuase I don't have enough points to comment I wrote a new reply.

Edit - deleted brackets to save another 2 bytes.

o=new ActiveXObject("WScript.Shell");setInterval(()=>o.SendKeys("{NUMLOCK}"),500);

His code looked like this

o=new ActiveXObject("WScript.Shell");setInterval(function(){o.SendKeys("{NUMLOCK}")},500);
  • 1
    \$\begingroup\$ For arrow function you don't need the parentheses in front of it. \$\endgroup\$ – fəˈnɛtɪk Feb 27 '17 at 20:07
  • \$\begingroup\$ Totally forgot about this, thanks. \$\endgroup\$ – ruler23 Feb 27 '17 at 20:20
  • \$\begingroup\$ I had meant the parentheses which were left over from when you removed function() \$\endgroup\$ – fəˈnɛtɪk Feb 27 '17 at 20:21
  • \$\begingroup\$ Oh, but you can't do that, it won't work. But you can remove the brackets as they are not needed in one-line statements (for some reason your comment reminded me of them even though you meant something different) \$\endgroup\$ – ruler23 Feb 27 '17 at 20:30
  • \$\begingroup\$ Save a byte by either replacing the () with another, single character, such as _ or by making o a parameter with a default, like so: (o=new ActiveXObject("WScript.Shell"))=>. \$\endgroup\$ – Shaggy May 3 '17 at 10:21

Scala, 84 83 78 bytes

Edit: Saved 1 byte thanks to @TheLethalCoder,

He suggested using 1>0 in place of true.

Edit 2: Saved 5 bytes thanks to @Corvus_192,

He suggested using infix notation and dropping the parentheses after the constructor

while(1>0){val r=new java.awt.Robot;r keyPress 20;r keyRelease 20;r delay 500}


while(1>0) {
    val r=new java.awt.Robot()

Standard Scala port of @Poke's Java answer. Type it directly into the Scala interpreter prompt.

A video of it blinking both my Caps Lock LED and my OSD to boot!

Blinking Caps Lock LED and OSD

  • \$\begingroup\$ Can you do for(;;) or while(1>0) or while(1) in Scala? \$\endgroup\$ – TheLethalCoder Feb 24 '17 at 16:07
  • \$\begingroup\$ The second is possible. A 1-byte saving which hadn't occurred to me before. Thanks! \$\endgroup\$ – Tamoghna Chowdhury Feb 24 '17 at 16:57
  • \$\begingroup\$ You can use infix notation: r keyPress 20 is a byte shorter than r.keyPress(20). The same applies to the other method calls, saving 3 bytes in total. \$\endgroup\$ – corvus_192 Feb 26 '17 at 19:22
  • \$\begingroup\$ Also, drop the parenthesis from the constructor call to save another 2 bytes. \$\endgroup\$ – corvus_192 Feb 26 '17 at 19:27

Linux terminal, 8+11 = 19 bytes


File f = 1B 5B 33 71 1B 5B 30 71

native@shell:~$ pv f -q -L8


According to ECMA-48, 1B starts terminal control escape sequence.

Caps on =1B 5B 33 71, then off = 1B 5B 30 71

pv progress view

f file

-q quiet

-L8 8 bytes/s = 0.5 sec delay



#Create file
echo "1B 5B 33 71 1B 5B 30 71"|xxd -r -p > f 

#Install progress view utility
sudo apt install pv

Ctrl+Alt+F6 switch to native console

run pv f -q -L8

Ctrl+Alt+F7 switch back


Bash + Xdotool, 36 bytes

for((;;)){ xdotool key 66;sleep .5;}

Just execute it in a bash shell. It needs to be in a graphical environment. Infinite loop from here. Changed Num_Lock to 66 to save 6 bytes, and thanks to @Michael Kjörling for 2 bytes.

  • \$\begingroup\$ You can save at least two bytes by removing unnecessary whitespace. You don't need the whitespace before the closing curly bracket, and you don't need whitespace surrounding the semicolons separating the commands. You do need the whitespace after the opening curly bracket, though. \$\endgroup\$ – a CVn Feb 23 '17 at 21:14
  • \$\begingroup\$ Also, regarding your initial revision: Keep in mind that you can use : as an alias for true on most systems. while :;do sth;done does the same thing as while true;do sth;done but is three bytes shorter. for((;;)){ sth;} is still shorter, though. \$\endgroup\$ – a CVn Feb 23 '17 at 21:15
  • \$\begingroup\$ @Cyoce Where? It didn't work for me. \$\endgroup\$ – Feldspar15523 Feb 24 '17 at 21:41
  • \$\begingroup\$ @Cyoce I think that only works for declaring functions. \$\endgroup\$ – Feldspar15523 Feb 25 '17 at 4:05
  • \$\begingroup\$ @Feldspar15523 oops nevermind then \$\endgroup\$ – Cyoce Feb 25 '17 at 6:34

xdotool, 20 bytes

key -delay=500 66 66

Presses the key 66 aka Caps Lock twice, with a delay of 500 ms between key presses.

Note that xdotool is a scripting language; it can be run from a file and it even supports shebangs. Since its exec command allow running external programs, it is capable of addition and primality testing, so it satisfies our definition of programming language.

Test run

$ cat blink.xdo; echo
key -delay=500 66 66
$ xdotool blink.xdo

enter image description here


Python using pyautogui: 126 143 115 103 bytes

Thanks to @nedla2004 for saving 12 bytes

from pyautogui import*
import time
while 1:keyDown('capslock');time.sleep(.5);keyUp('capslock')pslock')
  • 1
    \$\begingroup\$ You could change the while loop to while 1:keyDown('capslock');time.sleep(.5);keyUp('capslock'), and you can change the first line to from pyautogui import*, and the second to import time. \$\endgroup\$ – nedla2004 Feb 26 '17 at 18:17
  • \$\begingroup\$ you can remove the duplicate 'capslock'. import time;c='capslock' ... \$\endgroup\$ – init_js Mar 17 '18 at 12:25
  • \$\begingroup\$ you could also remove time altogether. from pyautogui import*; while 1:press('capslock',1,.5). ymmv. on my environment pyautogui does affect the case I type, but the light doesn't blink. \$\endgroup\$ – init_js Mar 17 '18 at 12:27

Bash, 31 bytes

xset led 1;sleep .5;xset -led 1

Works in X, without root access ! (If it does not work for you, see the init function of the code below to make sure xkbcomp is configured correctly)

And a bonus script to send any morse code through caps lock (not golfed) :

function init {
        xkbcomp $DISPLAY $file
        sed -i 's/!allowExplicit/allowExplicit/' $file
        xkbcomp $file $DISPLAY &>/dev/null
        rm $file
if [[ -z $1 ]]; then
        echo "Usage : blink [message]"
        exit 1
function finish {

function on {
#su -c 'setleds -L +caps < /dev/console'
xset led $id
function off {
#su -c 'setleds -L -caps < /dev/console'
xset -led $id
function slp {
        sleep $(echo "$unit*$1" | bc)
function dot {
slp 1
slp 1
function dash {
slp 3
slp 1
function gap {
        slp 3
function morse {
        for (( i=0; i<${#msg}; i++ )); do
                if [[ $char == "-" ]]; then
                elif [[ $char == "." ]]; then
                elif [[ $char == "/" ]]; then
while true; do
        morse $1

Exemple : blink "...././.-../.-../---//.--/---/.-./.-../-..///"


Bash + setleds, 43 bytes

setleds -D +caps;sleep 0.5;setleds -D -caps

Pretty simple. Uses setleds to toggle the light.


Bash, 103 bytes

cd /sys/class/leds/asus\:\:kbd_backlight;while true;do echo 3;sleep .5;echo 0;sleep .5;done>brightness

Must be run as root.

Does flashing the entire keyboard backlight work? (video to come when I get home)

  • 1
    \$\begingroup\$ Does flashing the entire keyboard backlight work? Well, if you think of it, the keyboard highlight is an indicator of the keyboard highlight being on or off, and it is definitely "physically located on the keyboard", so, yes, I think it counts. \$\endgroup\$ – zeppelin Feb 24 '17 at 10:42

JavaScript, 90 bytes

o=new ActiveXObject("WScript.Shell");setInterval(function(){o.SendKeys("{NUMLOCK}")},500);

It requires ActiveX meaning it will only run on IE (Edge doesn't support it, though). It flashes the NUMLOCK key because, as with other answers, it is shorter than CAPSLOCK or SCROLLLOCK.


shell = new ActiveXObject("WScript.Shell");

Bash, 33 Bytes

This assumes Num-Lock to be on before it is run. Switch off and on otherwise. Requires the numlockx package obviously ;)

numlockx off;sleep .5;numlockx on


Saw Alex Howansky has already posted this solution, yet not marked it with Bash and I just searched the site for "Bash".

  • \$\begingroup\$ +1, you don't have to repeatedly blink it (I think). \$\endgroup\$ – NoOneIsHere Feb 28 '17 at 8:39
  • \$\begingroup\$ If you're in an interactive shell, you can type at the command line: numlockx toggle;sleep .5;!# (27 bytes) . !# is the event that expands to everything in the command line that has been typed so far. \$\endgroup\$ – init_js Mar 17 '18 at 12:57

Batch File (With help of vbs), 74+2=76 bytes

echo Createobject("wscript.shell").sendkeys"{numlock}">z.vbs&z&timeout 1&z

Partially based on Trelzevir's answer.

.vbs is automatically included in PATHEXT.


Kotlin Script, 72 bytes

While not smallest one, still it's pretty good. I'm loving kotlin's run for some things, and this is one of them ( smaller than val r = java.awt.Robot() because we don't need both r. and val r =. Still, it's longer than MathLab )



java.awt.Robot().run {
    while(1>0) {

Python3 , 55 49 bytes

Thank you @NoOneIsHere for -4 bytes!

This includes packages: pyautogui and time modules


Thank you @NoOneIsHere for -4 bytes!
The key in action:
Caps Lock

  • 3
    \$\begingroup\$ Welcome to the site! :) \$\endgroup\$ – James Jul 1 '17 at 8:34
  • \$\begingroup\$ You can save quite a few bytes by using while 1, and making it a one-liner with a semicolon. (while 1:pyautogui.press("capslock");time.sleep(.5)) \$\endgroup\$ – NoOneIsHere Jul 1 '17 at 15:33
  • 1
    \$\begingroup\$ Unfortunately, this is also a snippet but by adding import pyautogui to the start of the program and changing the rest to while 1:pyautogui.press("capslock");time.sleep(.5) you can make this a valid answer. \$\endgroup\$ – caird coinheringaahing Jul 4 '17 at 6:54
  • \$\begingroup\$ @cairdcoinheringaahing There's also need to be an import time there. \$\endgroup\$ – FlipTack Nov 26 '17 at 20:08
  • \$\begingroup\$ @cairdcoinheringaahing Exactly, which is why you need an import time... \$\endgroup\$ – FlipTack Nov 26 '17 at 20:10

VBA, 82 Bytes

Anonymous VBE Immediate window function that takes no input and annoys the user indefinitely. Depedant upon the windows kernel32 function sleep that is declared below.

Sleep Declaration (Win-32)

Declare Sub Sleep Lib "kernel32" (ByVal M&)

Sleep Declaration (Win-64, + 8 Bytes)

Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal M&)

Anonymous VBE immediate window function

Do:SendKeys"{CAPSLOCK}":Sleep 500:DoEvents:Loop

Slightly more fun version, 97 Bytes

A set of mutually recursive subroutines that indefinitely annoys the user

Sub A
Application.OnTime Now+5.8E-6,"B"
End Sub

Sub B
End Sub

Questionable version, 66 + 2 Bytes

I'm not sure if having to declare a function from a dll counts as having an inbuilt function so, in the case that it does not, then here is a 66+2 byte version that waits 1 second

Do:DoEvents:Application.Wait Now+#0:0:1#:SendKeys"{CAPSLOCK}":Loop

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.