Parse URLs with <a> tags in JavaScript

I've needed to use JavaScript to parse URLs while working at Braintree. In Node, this is easy; just use the built-in URL module. Before I started at Braintree, I thought browser-based URL parsing would require pulling in a third-party library or writing some tricky string parser. It turns out that there's an easy way that's built into browsers.

You can use <a> tags to parse out various attributes of a URL. For example, to get the hostname of a URL, you could do something like this:

var a = document.createElement('a')
a.href = ''

a.hostname  // => ''

You can grab things like hostname, protocol, hash, and much more. Take a look:

var a = document.createElement('a')
a.href = ''

a.hash      // => '#hash'      // => ''
a.hostname  // => ''
a.origin    // => ''
a.password  // => 'pass'
a.pathname  // => '/p/a/t/h'
a.port      // => '8080'
a.protocol  // => 'http:'    // => '?query=string'
a.username  // => 'user'

This is really useful as a lightweight way to parse URLs!

How to transfer Android Neko Atsume saves using adb

This post assumes you have adb installed on your computer and can use it to communicate with your Android phone. You should have basic familiarity with a command-line terminal.

I've been playing Neko Atsume for months. It is almost frustrating that someone else discovered such a charming concept that could be so simple.

I recently got a new phone and couldn't find an easy way to back up my in-game spoils, so I did a little searching and found that you can use Android's adb tool to transfer your save between two Android phones by doing a simple backup/restore. And it doesn't require root privileges!

Here's how I did it:

  1. Install adb.
  2. Open up a terminal.
  3. Plug in the phone that you want to take data from.
  4. Make sure USB debugging is enabled on both devices.
  5. Run this command, which creates a backup file in your home folder:

    adb backup -f ~/back.ab -noapk ''
  6. When that's done, unplug the first phone and plug in the next one (the one you want to transfer your save to).

  7. Make sure the game is installed on this phone. Launch it to make sure it runs, then close the app.

  8. Run this command to transfer your backup to the new phone:

    adb restore back.ab

That's it! Your nekos should be safe.

This should, in theory, work on many apps. I only tried it on Neko Atsume but I'm sure it will work with many other apps.

Disable ESLint for a file

I love ESLint but sometimes you want it to completely ignore a whole file. Add this to the top of your file:

/* eslint-disable */

It needs to be in /* this kind */ of comment, not // this kind.

And ESLint won't complain about your file any more!

The CSP module is the largest part of Helmet

This post is aimed at people that have some familiarity with my Helmet Node.js module.

Helmet is a Node.js module that helps you secure your Express applications by setting various HTTP headers. It sets headers like X-Frame-Options to help prevent a kind of attack called "clickjacking" or X-XSS-Filter as a basic protection against cross-site scripting attacks. If you're writing an Express app (or a Connect or Koa app), I hope you'll give it a look!

The bulk of the module is pretty straightforward: just set nine HTTP headers. Some of the headers are set every time no matter what, while others have a small amount of logic associated with them. Eight of them are simple and one of them is a beast: the Content Security Policy (CSP) module. I'll spend this post talking about why that module is so much bigger than the rest.

Expect this to be boring.


I certainly feel like the CSP part of Helmet is the biggest. I spend the most time working on it and it's the hardest to wrap my head around. But how much bigger is it?

cloc is a cool program that counts lines of code. I used it to see which module was the biggest, and made sure to exclude node_modules, package.json, and test files. To see how big each module was, I ran this command in each directory:

cloc --quiet --exclude-dir=node_modules,test --not-match-f='package\.json' --include-lang=Javascript,JSON .

It gave me the following stats:

You can think of it this way:

  • CSP code: 223 lines
  • everything else combined: 226 lines

Why is it so big?

In short, the size of the CSP module comes from browser sniffing.

Every browser supports a slightly different variation of Content Security Policy (or don't support it at all). The simplest example is the name of the header. Newer browsers call the header Content-Security-Policy and older ones choose X-Content-Security-Policy or X-WebKit-CSP. There are loads of other browser differences that are much more difficult to deal with.

The CSP module has to inspect user agents to figure out what headers to set and how to set them. This is a nightmare. Without browser sniffing, this module would probably be about 30 lines; with browser sniffing, it's almost 200!

In my opinion, that's the real differentiator of Helmet. The rest of the library could be rewritten from scratch in a pretty short amount of time, but the amount of code and research that went into CSP-related browser quirks is pretty unique. It's the most frustrating to deal with, but it's the most important!

Vim's :x command

In short: Vim has :x which is basically the same as :wq but slightly less typing.

The first time I opened Vim, it was an accident. In a mad panic, I started smashing keys. What was this wretched program? Soon, Vim presented me with a message telling me to type :quit to exit Vim. This was the first Vim command I ever learned.

After spending more time with Vim, I learned the :q shorthand. This is an example of Vim users' hatred of the extra keystroke. Instead of typing :write and then :quit to save and quit, you can type :wq.

Most Vim users I've met know about :wq, but a big slew of people (including me, until recently) don't know they can trim a keystroke with the (nearly) equivalent :x command. To quote Vim's documentation on the command:

Like :wq, but write only when changes have been made.

I use :x instead of :wq every time and haven't encountered a problem—it's rare that you need to update the modification time of a file with no other changes.

This has saved me thousands of keystrokes throughout my Vim career. I thought it was worth sharing with the world!