Home Blog Index
Joseph Petitti —

Quines in JavaScript

Because programmers have nothing better to do with their free time, they often amuse themselves by finding clever solutions to difficult logic problems. One such problem is called a "quine," and it goes something like this: write the shortest possible program the prints its own source code.

It would be trivial to just read the file that the program is saved as and output that, but most programmers would consider this to be cheating. With this restriction in place creating quines becomes an interesting challenge that is more complicated than it initially appears.

If you've never tried to create a quine in your favorite programming language, I highly recommend you try it before reading further. There's something magical about figuring out how to do it for the first time. Spend some time tinkering until you solve it, then come back here.

Don't look below this turtle burger if you don't want me to spoil your discovery by telling you how to make a quine.

A rare but delicious turtle burger
This image hides the rest of the article so you don't get spoilered if you haven't created your own quine yet

Here's the first quine I made today, in JavaScript:

s=console.log;r=x=>x.replace(/\\/g,"\\\\").replace(/"/g,"\\\"");u="s(\"s=console.log;r=\"+r+\";u=\\\"\"+r(u)+\"\\\";\"+u);";s("s=console.log;r="+r+";u=\""+r(u)+"\";"+u);

The actual program doesn't have any newlines, but here it is broken up into separate statements with some syntax highlighting to make it easier to read:

s=console.log; r=x=>x.replace(/\\/g,"\\\\").replace(/"/g,"\\\""); u="s(\"s=console.log;r=\"+r+\";u=\\\"\"+r(u)+\"\\\";\"+u);"; s("s=console.log;r="+r+";u=\""+r(u)+"\";"+u);

At 170 characters in length this is definitely not the shortest possible, but I think it's not bad for a first attempt. Let's walk through how it works.

The first statement just sets a one letter variable to equal the function console.log, so that I don't have to retype it later. Normally in JavaScript you declare variables with let or const, but you don't actually need to. It will still run just fine as long as you're not in strict mode.

Line 2 declares an arrow function that takes an argument, x, and performs two regular expression find and replace operations on it. It replaces a single backslash with two backslashes, and a quotation mark with \". This essentially "unescapes" a string, and will be useful later.

The third line is a complex and ugly string containing a bunch of escaped quotation marks and backslashes. This is the contents of the final console.log as a JavaScript string.

The final line actually calls console.log, printing the source code. When the function r is concatenated onto a string literal, JavaScript calls the Function.toString() method on it to coerce it into being a string. This inserts the source code of r into the string that is printed. Finally, r(u) unescapes the string u so it is printed with backslashes exactly as it appears in the source code.

This quine works, but it's still a little long. With a bit more time I managed to shorten it to 130 characters:

r=x=>x.replace(/(["\\])/g,"\\$1");u="console.log(\"r=\"+r+\";u=\\\"\"+r(u)+\"\\\";\"+u)";console.log("r="+r+";u=\""+r(u)+"\";"+u)

Once again, here's a version with newlines and syntax highlighting so it's easier to read:

r=x=>x.replace(/(["\\])/g,"\\$1"); u="console.log(\"r=\"+r+\";u=\\\"\"+r(u)+\"\\\";\"+u)"; console.log("r="+r+";u=\""+r(u)+"\";"+u)

The first line is completely removed from this version, because I realized it's shorter to just type out console.log twice. The function r is shortened by combining the two replace() calls into one, using a more complicated regular expression that does the same thing as the two previous ones.

Because of these changes u is shorter, and I removed the final semicolon from the end because it isn't strictly required.

I thought this was the shortest I could get this quine to be, but after another couple hours of playing with it I was able to cut it all the way down to just 35 characters. Behold the shortest JavaScript quine I could come up with:

r=x=>console.log(`r=${r};r()`);r()

I had a hunch the power of Function.toString() could be abused to create a very short quine, and it turned out to be right.

First, r is declared as an arrow function. Note that it takes one argument, even though this argument is never used. This is because r=x=>... is one character shorter than r=()=>... and still just as valid. Because all function parameters are optional in non-strict JavaScript we don't even need to pass anything to r when we call it later.

If an arrow function is only one statement you can omit the curly braces around the body, so the body of this function is just the console.log call. Once again r is converted into a string through type coercion, this time by inserting it into a template literal. At the end of the line r() is actually called, causing our output to be printed.

This is the shortest JavaScript quine I could think of. A quick search revealed that some very clever people have come up with even shorter ones, but I think 35 characters is still a pretty good score.

Bonus content: other cool quines

You can make quines in almost any programming language, and even some things that aren't really programming languages.

For example, it's possible to make a quine out of a Lempel-Ziv compressed data stream, the format used to define zip files. This means you can create a zip file that recursively contains an infinite number of copies of itself.

Here's a neat shell script quine:

#!/bin/cat

If you make this script executable and run it, the shebang indicates that the program it should be run with is cat. This obviously just prints the file to the stdout, technically making it a correct quine.

Finally, here's a quine I wrote in Haskell. It's not very good, but it does work:

module Main where main = do putStr (s ++ (show s) ++ "\n") where s = "module Main where\n\nmain = do putStr (s ++ (show s) ++ \"\\n\")\n where s = "