The wtfjs handbook is one markdown file, its npm package stopped at 1.22.8 in 2022, and npm test is prettier
🤪 A list of funny and tricky JavaScript examples
At a glance
- What is it?
- wtfjs is a collected list of surprising JavaScript behaviours, credited to a 2012 conference talk and maintained as a set of markdown READMEs with a terminal pager on top. What a reader should know is that the newest published version is from 2022, that npm test runs a formatter rather than a test suite, and that the translations are explicitly allowed to be incomplete and out of date.
- Who is it for?
- Read wtfjs from the repository rather than from the installed CLI if you care whether an example is current, since the published package is the 2022 text and the default branch has moved since. Do not treat the translations as an equivalent source, because the project states they may omit examples and may be outdated, and do not assume the project verifies its own examples, since its test script is a formatting check.
- Can I use it commercially?
- Yes. WTFPL is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 90 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
npm test is prettier --check, because there is nothing to test
The scripts in package.json explain the shape of the project better than any description does. The test script is prettier --check ., the format script is prettier --write ., the toc script is npx doctoc with a title of '# Table of Contents' and a maxlevel of 2 across README*.md, the release script is npx semantic-release, and prepare runs husky install. There is no test file in the repository and no test directory.
That is correct for what this is. The product is a document, and a document has two things worth automating: that it is formatted consistently, and that its table of contents matches its headings. Both are scripts, and both run before a commit through lint-staged, which for README*.md runs npm run toc and then prettier --write --ignore-unknown, and for every other file runs prettier on its own.
The consequence is a specific gap. Nothing in the pipeline checks that a JavaScript example in the README still produces the output written beside it. A change to the language, or to a runtime, can make an entry wrong and every check will pass, because the checks are about the file's shape rather than its claims. When you cite an example from this list, run it before you repeat it.
The published package is the 2022 text and the branch is from 2026
The version in package.json is 1.22.8, and the release record shows v1.22.8 on 2022-09-30, v1.22.7 and v1.22.6 both on 2022-04-26, ninety minutes apart. The repository's last push was on 2026-07-03. So the newest thing npm will give you is about four years older than the newest thing in the tree, and nothing in the rendered output tells you which text you are looking at.
Install it and you get a pager, not a live document. The bin entry maps wtfjs to wtfjs.js, and running wtfjs opens the manual in your selected $PAGER. The content it prints comes from the installed package, so it is the 1.22.8 text, and there is no version banner in that output to warn you.
Versions are derived from commits rather than typed by hand, since the release script runs semantic-release with the commit analyzer, a notes generator, the npm and GitHub plugins and a git plugin. That is a clean setup, and it also means the gap between a release and the branch is a maintainer decision rather than a forgotten version bump. The practical rule: read the repository when you want to know what the project currently says, and treat the CLI as a convenient copy of the 2022 edition.
Eight README files in the tree, seven named in the translation list
The top-level entries hold README.md plus seven files the README itself names: README-zh-cn.md, README-hi.md, README-fr-fr.md, README-pt-br.md, README-pl-pl.md, README-it-it.md and README-kr.md, covering Chinese, Hindi, French, Brazilian Portuguese, Polish, Italian and Korean. There is an eighth in the tree, README-si.md, which the translation list does not mention.
The project states the terms of the translations plainly, and they are worth reading before you point a colleague at one: translations are maintained by their translators, they may not contain every example, and existing examples may be outdated. That is an explicit warning that a translation is a snapshot taken at somebody else's commit, and it is the reason the English file is the only one you can treat as current.
There is a coordination wrinkle too, because npm run toc runs doctoc across README*.md rather than README.md alone. Regenerating the table of contents rewrites a section in every translation, including files maintained by people who are not you. The lint-staged configuration does the same on commit. Translation work in this repository is therefore shared-file work, not independent work, and the file that exists without being listed is a small example of how a translation can arrive without its bookkeeping.
The table of contents is generated and says not to edit it
The README carries two HTML comments around the contents list. One says the section is doctoc generated and to keep the comment there to allow auto update. The other says do not edit this section, instead re-run doctoc to update. The generated list runs from Motivation through Notation, Examples, Other resources, Supporting and License, and the Examples entry expands into the individual entries, from [] is equal ![] through to the non-strict comparison of a number to true.
The maxlevel of 2 in the doctoc script is why the list has the shape it has. Headings up to level two are collected, so the fifty-odd examples appear as a flat list under Examples rather than as a nested tree, which is the right choice for a document meant to be skimmed and also the reason an example's own subsections never show up in the contents.
For a contributor this is a small discipline with a real payoff. You add an entry, you add a heading, and the script regenerates the index, the pre-commit hook runs it for you, and the formatting hook then normalises what doctoc wrote. The cost is that any change to the contents list by hand is a merge conflict waiting to happen, and the count of entries you see in a translation is a snapshot of when that translation was last regenerated.
The CLI is a markdown pager with an update notifier attached
The whole install is one command, and the README gives it as a shell transcript rather than a package name to look up:
$ npm install -g wtfjsThat puts a wtfjs executable on your path. Run wtfjs and it opens the manual in your selected $PAGER, and the README notes that otherwise you can go on reading the source at the repository.
The runtime dependencies describe the tool exactly: meow for argument parsing, msee for rendering markdown in a terminal, default-pager for the $PAGER behaviour, chalk for colour, boxen for the frame, through2 for streaming, and update-notifier. The result is a single file, wtfjs.js, that prints a document and hands it to your pager.
The dependency worth noticing is update-notifier. A tool whose entire job is showing you a document still checks npm for a newer version of itself, which means running wtfjs makes a network request it does not need for the text. On a locked-down machine that request either fails quietly or holds the pager open, and neither failure looks like a problem with the content.
The second consequence is the one from the release dates. The document you read is the packaged one, so a reader who installed the package a while ago and a reader who cloned the repository today are reading different manuscripts, and nothing in the output distinguishes them. If you are checking whether an entry still holds, use the repository and a runtime you control.
The list mixes 2012-era coercion with entries that will age faster
The stated goal is to collect crazy examples and explain how they work, if possible. That qualifier is the honest part. The collection runs to fifty-odd entries covering coercion, numbers, regular expressions, strings and objects, functions and arrow functions, generators and classes, timers and promises, and syntax oddities such as HTML comments being valid JavaScript and double dots. Entries like Adding arrays, Adding RegExps, Why you should use semicolons and Split a string by a space are about the language's oldest decisions, and they are not going to change.
Others are tied to a runtime. document.all is described as an object that is undefined, Object.is() and === has its own entry for the cases where they disagree, and there are separate entries for arrow functions, for a generator which yields itself, for a setTimeout object and for resolve() not returning a Promise instance. Those depend on engines and on the standard, so they are the entries most likely to need revisiting, and the README does not carry dates per entry to tell you which have been.
The origin is stated as well: the idea belongs to Brian Leroux, from his talk at dotJS 2012. That date explains the shape of the collection, which is strongest on the parts of JavaScript that were settled before 2012 and thinner on the ones that were not. A professional developer will get the most from it as a reference for the coercion and equality rules, which is what the README suggests it is for.
WTFPL 2.0, one markdown file, and no build step at all
The licence is WTFPL 2.0, stated in package.json and carried on a matching badge, with a LICENSE file in the repository root and a License section at the end of the README. For a handbook of examples this is a reasonable choice. For an organisation with a licence allowlist it is a question to answer before you paste the text into an internal document, because WTFPL is a do-what-you-want licence rather than one of the standard permissive licences most policies are written around.
There is no build. The product is markdown, the bin is a single JavaScript file, and the package's homepage field points at the README in the repository rather than at a site. The only generated artefact in the tree is the table of contents, and the only automation is formatting. That means forking it is a text edit, and the cost of keeping your fork current is re-running doctoc and prettier rather than resolving anything.
The maintenance picture matches that. The repository is not archived and its last push was on 2026-07-03, well after the 2022 releases, so the file is still being touched while the published package is not. Two support links are on the README, Patreon and Buy Me A Coffee, and the contribution guidance points at CONTRIBUTING.md for translations as well as code.
Editorial conclusion
Read wtfjs from the repository rather than from the installed CLI if you care whether an example is current, since the published package is the 2022 text and the default branch has moved since. Do not treat the translations as an equivalent source, because the project states they may omit examples and may be outdated, and do not assume the project verifies its own examples, since its test script is a formatting check. Verify first by reading the entry in README.md and running the snippet in a current runtime yourself, then by checking whether WTFPL 2.0 is on your organisation's licence allowlist before copying text into internal documentation.
Frequently asked questions
How do I install wtfjs?
Run npm install -g wtfjs, then run wtfjs at the command line, which opens the manual in your selected $PAGER. The source is at https://github.com/denysdovhan/wtfjs, and the README notes you can keep reading there instead.
What licence is wtfjs released under?
WTFPL 2.0. package.json declares the license field as WTFPL 2.0, the README carries a matching badge, and a LICENSE file sits in the repository root alongside a License section at the end of the document.
Is the wtfjs npm package up to date with the repository?
Not necessarily. The newest release is v1.22.8 from 2022-09-30, after v1.22.7 and v1.22.6 on 2022-04-26, while the repository's last push was on 2026-07-03. Running wtfjs prints the packaged text, so check README.md in the repository for the current version of an entry.
What does npm test run in the wtfjs project?
The test script is prettier --check ., a formatting check rather than a test suite, and there is no test file in the repository. The other scripts are toc for regenerating the table of contents with doctoc, format for prettier --write ., and release for semantic-release.
Are the wtfjs translations complete and current?
The README states that translations are maintained by their translators, that they may not contain every example, and that existing examples may be outdated. Seven are named in the list, and the repository tree also contains a README-si.md that the list does not mention.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/denysdovhan-wtfjs)