A self hoster’s guide to port forwarding and SSH tunnels

Self hosting with NAT and port forwarding and dynamic DNS is kinda fragile. I’ve been using a very cheap cloud-hosted nginx VPS to forward traffic to my self-hosted servers and it works nicely.

But tonight I set up a ssh tunnel that punches out from my server skipping the NAT, forwarding, and DNS stuff entirely. It’ll dial home from anywhere there’s network so I could even take my server to the park and it should work over 5g.

I just think that’s neat.

I’ve tried to explain a bit of my thinking, and a loose guide for how to set this up yourself. These instructions are for someone who’s vaguely familiar with nginx and ssh.

  1. How it usually works
  2. A more resilient port forwarding over ssh
  3. How to set up an nginx proxy to forward to your self hosted server
  4. How to forward ports to your self-hosted server over SSH
  5. How to set up a persistent SSH tunnel/port forward with systemd
  6. My observations using SSH tunneling

How it usually works

A typical port forwarding scenario opens ports on each device. When all the right ports are open, traffic flows all the way through from the internet to my self hosted server.

A traditional port forwarding scenario requires dyndns to upate the dynamic IP, as well as forwarding of ports through each device until it reaches the self-hosted server.

In my example, I have a nginx server on a cheap VPS in the cloud that handles forwarding. That VPS looks up my home IP address using a dynamic DNS service, then forwards traffic on port 80 to that IP. In turn my router is configured to forward traffic from port 80 on to the self hosted server on my network.

It works well, but that’s a lot of configuration:

  1. Firstly I need direct access to the ‘net from my ISP, whereas today most ISPs put you behind a carrier grade NAT by default.
  2. If my IP changes, there’s an outage while we wait for the DNS to update.
  3. If my router gets factory reset or replaced with a new one, I need to configure port forwarding again.
  4. Similarly, the router is in charge of assigning IPs on my LAN, so I need to ensure my self hosted server has a static IP.

A more resilient port forwarding over SSH

We can cut out all the router and dynamic DNS config by reversing the flow of traffic. Instead of opening ports to allow traffic into my network, I can configure my self-hosted server to connect out to the nginx server and open a port over SSH

You could also use a VPN, but I chose SSH because it works with zero config.

A self-hosted server creates a ssh tunnel to the remote server and routes traffic that way, without DynDNS or router configuration.

In this diagram, the self-hosted server makes a connection to the nginx server in the cloud via SSH. That ssh connection creates a tunnel that opens port 8080 on the nginx server, which forwards traffic to port 80 on the self hosted server. Nginx is then configured to forward traffic to http://localhost:8080, rather than port 80 on my router.

So the router doesn’t require any configuration, the cloud-hosted VPS server only needs to be configured once, and the dynamic dns server isn’t needed because the self-hosted server can create a direct tunnel to itself from wherever it is.

The huge benefit of this zero-config approach is I can move my self-hosted server to another network entirely and it will dial back into the nginx server and continue to work as normal.

How to set up a nginx server to forward to a self-hosted server

Putting an nginx server in front of your self-hosted stuff is a good idea because it reduces your exposure to scary internet risks slightly, and can also be used as a caching layer to cut down on bandwidth use.

In these examples, I’m forwarding traffic to localhost:8080 and 443 and will set up a SSH tunnel to forward that traffic later.

There are two ways to set up forwarding:

As a regular nginx caching proxy:

This is a good option when you want to utilise caching. However you’ll need to set up your letsencrypt certificates on the server.

server {
  server_name myserver.au
  location / {
    proxy_pass http://localhost:8080/;
    proxy_buffering off;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Port $server_port;

As a socket forwarding proxy

This option doesn’t proxy http traffic, it just forwards packets directly.

stream {
                proxy_pass localhost:8080;

        server {
                proxy_pass localhost:8443;

This method is easier for something like Coolify that deals with virtualhosts and ssl for you, but the downside is that there’s no caching, we can’t add an x-forwarded-for header, and it eats up an entire IP address. You can’t mix a socket forward with a regular proxy-pass.

How to forward ports to your self hosted server

First, generate SSH keys on your self-hosted server, and allow logins from your self hosted server to your nginx server. DigitalOcean has a guide to setting up ssh keys.

You can verify this is working by running ssh root@myNginxServer.au on your self hosted server and seeing it log in automatically without a password.

Then test your port forwarding with the following command:

ssh root@myNginxServer.au -R 8080: -R 8443:

The -R argument opens port 8080 on the remote server, and forwards all traffic to port 80 on the local server. I’ve included two forwards in this command, for both http and https. The address binds traffic to localhost, so only the local machine can forward traffic on these ports, but you could open it to the whole world with

How to set up a persistent SSH tunnel/port forward with systemd

Then, create a systemd service to maintain the tunnel.

I borrowed these instructions from Jay Ta’ala’s notes and customised them to suit:

sudo vim /etc/systemd/system/ssh-tunnel-persistent.service

And paste:

Description=Expose local ports 80/443 on remote port 8080/8443
ExecStart=/usr/bin/ssh -NTC -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -R 8080: -R 8443: root@myNginxServer.au

You can then start the systemd service/ssh tunnel with:

# reload changes from disk after you edited them
sudo systemctl daemon-reload

# enable the service on system boot
sudo systemctl enable ssh-tunnel-persistent.service 

# start the tunnel
sudo systemctl start ssh-tunnel-persistent.service

My observations using SSH tunneling

If all is working, those steps should now be forwarding traffic to your self hosted server.

Initially this was difficult to set up because the vagueness of the docs for whether to use -L or -R, but once it was running it seems fine.

The systemd service works well for maintaining the connection and restarting it when it drops. I can reboot my nginx proxy and see the tunnel reestablish shortly afterward. My high level understanding is that when the tunnel breaks after ServerAliveInterval=60 seconds, the ssh command will realise the connection has dropped and terminate, then systemd restarts the service ad infinitum.

You can adjust the ssh command to suit. There’s probably not much point enabling compression because the traffic is likely to already be compressed. But you could tweak the timeouts to your preference.

Panasonic SA-DP1 Review – hifi from the early 2000s

A Panasonic hifi and speaker sit on a cabinet with fancy lighting

Over Christmas while we were packing stuff up to move it around, my mum confided that she doesn’t use the hifi system in her office. It doesn’t get any radio signal and she doesn’t have any CDs to play in it any more, so it just sits there doing nothing.

Since my living room only has the tiny Google Home speaker, I offered to take it off her hands to hook up as an aux device to my living room TV to improve the sound. And it’s delightful.

I love a bit of a retro nostalgia trip, this website is proof enough of that, and this hifi system is really doing it for me. It harks back to a time when things were simple enough to plug together and screw around with. A good time for a kid like me.

This thing is a little beast. It’s an AM/FM CD/DVD player from back when these sorts of things were common. The year 2003 to be exact, just a year before HDMI was first released in consumer gear, so it’s the absolute peak of analog tech before digital signals fully took over.

Hooking up to my TV was a simple affair, I grabbed a 3.5mm audio to RCA cable to connect the TV straight to the hifi system. I could have bought an optical DAC (digital audio converter) for better quality, or even a HDMI audio splitter so I can play audio without the TV on, but this was the most straightforward solution and it sounds flawless.

It also happens that my TV is a hand-me-down old enough to support composite video directly (thanks Ben!) so I hooked it up in reverse to (theoretically) play DVDs. Why? Cos why the heck not.

The early and kinda disappointing days of digital video

A USB CD drive with a bright orange Verbatim CD-RW sticking out and some jewel cases in the background

Around the time this thing was made I was browsing an electronics store in Singapore and stumbled upon a VCD of the 2002 film Resident Evil with a gorgeous holographic cover (Video CD being the precursor to DVD icymi).

I needed to have it! In part because it the cover was cool, but also because I didn’t have a DVD player at home so I’d be able to watch this with the CD drive on my computer.

It was a pretty bad, but fascinating technical choice. Turns out VCDs have exactly half the resolution of VHS tape, and only fit about 80 minutes of MPEG-1 video per disc, so the movie was terrible quality and chopped in half to fit over two discs. Not only that, but the censors also cut out a bunch of good bits.

Still, I loved that film and I’ve been trying to burn a VCD with some old vlogs just for a nostalgia trip.

(Side note: Super VCD used MPEG-2 and had a higher resolution, so they’re almost passable quality-wise. But they’re still limited to 4:3 for that old school cool)

A Devede window reads 'Burning image to CD. Writing track 3. 154 MiB of 650 MiB. Estimated drive speed 723 Kib/s (4.2x)'

I didn’t have much luck creating a VCD in in the year 2020 because it’s all pretty outdated, but I found an all-in-one burner alled Devede which actually managed to take my rips from youtube, crop and convert em, then burn onto an SVCD disc.

Unfortunately the unit didn’t seem to be able to play them. I’ve got a couple of rewritable DVDs coming in the new year so maybe there it will have more luck with those.

Day to day Panasonic SA-DP1

Cool old tech aside, I’m mostly likely to use this as an aux system for the TV with the Chromecast as a source, because any other configurations are really too outdated to want to use on a day to day basis. And for that it’s fantastic.

Amazon is filled with reviews from people who loved this thing fifteen years ago. It wasn’t super expensive, it’s a solid piece of kit, and it sounds great too.

Overall, I give the Panasonic SA-DP1 five stars.

MSI Optix 31.5in Monitor (MAG321CURV) review

Text reads "this display is crap, regret buying it" with an overly large pixel pitch

Ew. I can not stand this monitor.

The USBC display doesn't work with my Macbook Pro. The monitor won't turn on, and the laptop uses more charge than it can draw from the cable.

Reflections from even the slightest light source in the room deliver a different image to each eye, leaving me struggling to focus and causing eyestrain. Further, there's enough space between pixels you can drive a truck through.

After about 10 minutes using this thing I was feeling nauseous. I turned it off, put it back in the box and submitted a return order. This display should be avoided unless you're very confident none of these issues will bother you.


Heading back to Australia in times of Coronavirus

It has been SO hard being in Amsterdam away from my partner, friends, family and all the people I love during the pandemic and I need to fix that. So in some very bittersweet news I am returning to Australia.

As far as I know the only flights to Australia are repatriation flights from Hong Kong, Los Angeles, and London via Qantas. I missed the first round of flights, but another 6 opened up from London and after speaking to work I decided I wanted to be on one.


  1. 14 day quarantine on arrival into Australia
  2. Organised on a state by state basis, and rules constantly in flux
  3. Up to 2 "care packages" can be picked up from within the city by staff. Not all items are allowed.
  4. Non-perishable grocery deliveries allowed from Woolworths
  5. Laundry quota twice a week
  6. Once a week supervised outside exercise allowed
  7. Free internet access 🎉 as well as movies

I've scanned the documents outlining Victoria's quarantine procedures as of May 23 into a Google Docs folder.

Getting to London

Getting to London was not difficult from Amsterdam because The Netherlands doesn't have any measures preventing travel.

The UK seems to be accepting folks with the same visa restrictions as before, providing they have a valid onward journey. I couldn't find this information anywhere online and only found out when I was unable to check-in online.

At the KLM check-in desk I was able to check-in by showing the details for my Australia flight, even though it was on a different day. Others were not so lucky. One man in the queue was advised to "book a train or a bus ticket" before he was allowed to check into the London flight.

On the London side I passed through the automated security check with no hassles at all, and didn't speak to another human.

Uber in London doesn't seem to have any real preventative measures in place, but the taxis in the cab rank had sealed partitions between the driver & passenger which made it an easy choice.

Checking into the repatriation flight

Before check-in, Qantas sent a COVID-19 health screen form which could be filled out online at the check-in desk.

In addition to the obvious "do you have COVID-19" question, they also asked:

  1. Are you diagnosed or suspected to have pneumonia or COVID-19 infection?
  2. Have you been in contact with someone that is a suspected (being tested) or confirmed a COVID-19 case in the last 14 days?
  3. Have you been on a cruise ship or in a shared accommodation setting such as a hostel in the last 14 days?
  4. Do you currently or have you recently felt unwell with any of the following symptoms:
  • Feverish, fatigued or aching
  • Cold or flu like symptoms such as runny nose, cough or sore throat
  • Shortness of breath

I'm not sure what answering yes to any of these would mean because again I couldn't find info about it online.

A card reads: COVID-19 Health Screen Approved

Heathrow was a total clusterfuck. Security took about 30 minutes and it wasn't possible to social distance because of the layout of the queues winding tightly back on each other. This didn't stop them from putting up signs advising you to do so, and thankfully almost everyone was wearing masks.

Once cleared, there was a final health check to measure temperature, etc before we were given a little green pass and allowed to board.

Flying to Australia

A yellow bag with a biohazard label

Upon boarding the flight we were handed a yellow biohazard bag containing spare face masks, hand sanitizer, a pen, an immigration card & several spare bio bags.

Contact was kept to a minimum, and after meals any remaining garbage was only collected in the bio bags.

The flight was a Boeing 787-9 Dreamliner, which had three groups of three seats per row in economy. People were distanced at one person per three seats, and spaced so that nobody was sitting directly in front or behind anyone in the next row.

We were all required to wear masks, and they say the HEPA filters take out the majority of nasties so it's about as safe as you can get locked up in an airplane for 22 hours. But of course, nothing's a given.

I remember being relieved they did anything at all. There was no info on the Qantas website about it so I was preparing for the worst, but it was well implemented. I felt a lot more relaxed on the plane (aside from the woman sitting near me who kept taking her mask off and wearing it on her chin. Some people!)

I got to see both a sunset and a sunrise. Watching the sun come up through the tinted Dreamliner windows was beautiful: a giant purple-red orb rising through the clouds, looking like a fiery gas giant in alien solar system.

Sunset from a plane window

Melbourne via Perth

Since the flight to Australia is too long for conventional aircraft, there's usually a stop-over somewhere in Asia or the Middle East. None of the countries that I know of are allowing transit at the moment. Instead the flight ran directly to Perth to refuel before continuing to Melbourne.

The stop in Perth was brief. We didn't leave our seats, we just sat waiting for the crew to change over and the refuel to finish. I lost track of the time because I was sleepy, but Flightradar24 says it took about an hour and a half.

The final leg of the trip to Melbourne was fairly uneventful.

The Crown. Or in Spanish, La Corona

What happens when you land in Australia?

The very first thing is another temperature check & health screen. This wasn't the quickest procedure, so we queued in the aerobridge while this was taking place.

Once cleared we were given a detention notice from the Victorian government, letting us know that we would be quarantined for 14 days which we were required to sign.

A state of emergency exists in Victoria under section 198 of the Public Health and Wellbeing Act 2008 (Vic), because of the serious risk to public health posed by COVID-19.

You must proceed immediately to the vehicle that has been provided to take you to the hotel. Once you arrive at the hotel you must proceed immediately to the room you have been allocated. You must not leave the room in any circumstances

Finally, we were given the information about the hotel we would be staying in. In my case, the Crown Metropol in the center of Melbourne which was cordoned off especially for this.

After that we were herded onto the tarmac and boarded buses directly to our hotel. There was no social distancing on the bus, but we were required to wear our masks through the whole process.

The quarantine

The hotel is a quarantine zone so nobody other than staff and occupants are allowed in.

When the bus arrived we were shepherded off one at a time and given our room number, a care package of various snacks, toiletries & necessities, and many pages of documentation about how things work.

This was the first time I learned anything solid about ANYTHING to do with the quarantine. Before now I'd only heard rumours.

As I understand it's a rapidly evolving situation, and it's managed on a state-by-state basis which is possibly why the Federal government has no information for travellers.

I've scanned the documents outlining Victoria's quarantine procedures as of May 23 into a Google Docs folder, which has a lot more info on how everything works.

My experience

Through this time I've been an anxious mess but now that I'm in the hotel I'm finally starting to relax.

The hotel room is bigger than my apartment in Amsterdam by a large margin so even though I'm locked in I'm feeling much less cooped up.

The meals so far have been pretty good, all things considered. There's far too much food provided at any given mealtime, but that leaves plenty of other items for snacks in between.

The hotel, security, and health staff have been absolutely amazing and I'm so grateful to be able to come home. The amount of love and support and human connection I've had from everyone while in isolation this past week is truly overwhelming, and I'm beginning to feel that just maybe things are going to be okay <3

Retro nostalgia & why my new website looks like Window 9x

For a while I’ve been wanting to update my website, but I’m really not a designer and I knew any attempts to improve on what I already had would be a haphazard mess.

I was looking for a new job as a React developer and really wanted to hone my skills, so I thought what better way than to build a new site in React?

As for design… why not pay homage to one of the most influential operating systems of my youth: Windows 9x. And for fun, why not make it all fit on a floppy disk.

The rise of retro nostalgia

Windows 9x is the loose name for the operating systems from Windows 95 through ME. They were pretty shoddily built on top of MS-DOS and kinda sucked. But they were revolutionary at the time, and we didn’t know better.

The design aesthetic, particularly in the Windows 98 era was something to behold.

In present day, retro tech is really making a comeback. One of my favourite examples of this is Paul Verbeek-Mast’s horrible excellent website which was kind of an inspiration for me through my design process.

But there are plenty of other amazing examples of retro nostalgia including the gorgeous poolside.fm streaming radio, and this fun game concept:

I spoke about this stuff at the October QueerJS meetup in Amsterdam.

It’s running on a floppy disk you guyz

Ultimately the entire site is designed to fit on a 3.5″ floppy disk, attached to a Raspberry Pi running nginx, sitting on the shelf under my TV.

That means the entire site is 1.44 mb (or less) at any given time, and served to you straight from the ’90s.

The site is using Hexo to render out the static content, which includes a bunch of custom theming to make the data hook together nicely.

It’s also using Netlify for builds and Cloudflare as a CDN, so chances are you’ll never actually have to wait for the magnetic drive to spin up. But you never know! I get a little thrill out of that.

Update: this is back on Netlify while I’m at Fronteers Conference since I don’t have time to put the pi back together.

React & open source

This site was largely built with Preact (A fast 3kB alternative to React with the same modern API). The content is built with Hexo then progressively enhanced, so you can disable javascript (with the skip link for accessibility, or in the Start menu just for kicks) and the site still mostly works.

The interface is inspired by the more nostalgic bits of Windows 98 and ME, which were my operating system of choice in my more formative years.

If I’m honest, this was a terrible choice because the (p)react lifting state/render model is not great for large applications like this, and I led myself into an architecture that’s super inefficient and hard to maintain. But at this point I dont care, it’s working pretty well.

The UI components and some of the apps have been released on Github as a library called ui95. It’s a bit rough but you can use the library to create your own sites, apps, or just as a learning tool. Interestingly Artur Bień has been working on a parallel component library of Windows 95 styled components as well, so that’s probably worth a check-out too.

Some apps were built by third parties, including Paint and originally I was planning on including Webamp but it was too big to fit in my size budget. You can check each app for license information.

Where to from here?

Not sure. I’d like to post more on my blog and maybe find a local computer group.

But in seriousness, this was a fun project and I learned a lot putting it together. I hope you get some inspiration out of it and bring back a little of the whimsy in the retro web.

The reason I cancelled my love affair with Google Home

In 2018 I wanted to buy a Google Home because I was working at ABC News on chatbots and figured immersing myself in the voice assistant hype would give me a better perspective on how to create for them.

A Google Home sits on a table in a home

Maybe I could write an app! Or at least understand better how they could fit into people's lives. I was never especially convinced of the broader applications, but it was cheap enough so I figured it couldn't hurt.

After buying a second for the bedroom and using it for a year and a half, I finally tipped over the edge and given up on the platform for good.

What's so good about Google Home?

Ultimately voice assistants have different use cases for everyone.

One of my friends uses an Alexa for music and managing the contents of their fridge. Another uses it to control home automation (and terrorize the cat).

Personally my main uses were checking the (variable Dutch) weather and asking about the time. The latter actually surprised me, it's super useful when you're in the shower or in the dead of night and don't want to open your eyes to look at a clock.

The problem was that aside from turning on and off my lights, it really wasn't doing much for me. I'm not interested in radio, could never get podcasts working, and the news is easier to read online. On top of that, finding apps on Google Home is downright impossible.

I'd say outside of Google's main offering there were no killer apps. It's not a great ecosystem.

Then the bugs

From the get-go I couldn't use the full set of functionality because I have a Google Apps account rather than a plain old Google account.

For a while I could create calendar events, but that feature disappeared unceremoniously one day. I couldn't send messages, dictate emails, or receive notifications and there was no real integration with any major Google features. I'm not sure how much of this was due to my Apps account, and how much was just missing features in general.

But the thing that frustrated me the most was the reliability of the system. In the past few months it seems to have completely tanked.

At various points I've had the assistant light up and start listening for no reason at all, switch to another gender and accent, and more recently it stopped recognizing devices on my network like my TV and smart lights.

As an isolated event this was frustrating, but the frequency it was happening killed my faith in the system.

Web & App Activity

One of the biggest sticking points for me was that for Google Assistant to work, you needed to enable Web & App Activity on your Google account.

Google app activity

This is an all-encompassing feature that logs all your interactions with Google, including searches. It's not just for your voice assistant.

I was initially hesitant to turn this on because it's super creepy having your Google searches stored in perpetuity, especially when dealing with sensitive or embarrassing topics. But I did it because I wanted the hardware assistant to, you know, actually work.

While you can delete Web & App Activity from the My Activity site, it was still kinda chilling and I started using a lot more tools like Duck Duck Go, more private windows, and Firefox Focus (a private browser for mobile which I highly recommend).

But last month after a period of Google Assistant constantly misunderstanding, getting things wrong, and at one point playing loud rock music instead of white noise in the middle of the night, I decided to turn off Web & App Activity and see what happened.

Using Google Assistant without Web & App Activity enabled

Spoiler: not much changed when I turned off Web & App Activty, which surprised me a little.

When I first started using the device this was a mandatory feature, and it wouldn't work without it. But it seems they've some done work on making the hardware devices work without logging enabled.

That said, it wasn't perfect. I lost access to my third party integrations such as LIFX lights and Chromecast controls so it wasn't a complete solution and made the devices pretty useless beyond just the time and weather.

Quitting Assistant

After a few weeks of this, I decided Google Assistant was not worth the hassle and unplugged all my devices.

The news that Google, Microsoft, Apple and Amazon all have fairly lax privacy mechanisms in place around recordings certainly helped.

So my two Google Home Minis have been sitting on my bedside table for the past week and I'm not sure what to do now.

I like the idea of voice assistants and would consider getting another in the future, but right now the Google Assistant isn't very useful. I'm not a big fan of Amazon, and I hear Siri is pretty useless too so I don't hold out hope on things changing any time soon.

From my brief question on Twitter, it doesn't seem like many others are using them for much more than basic tasks. While race to the bottom in terms of price and smartphone ubiquity has contributed to these things being in everyone's homes, I genuinely wonder where the voice assistant revolution is heading from here.

Why are React PropTypes inconsistently named?

I'm reasonably new to PropTypes in my React code and I'm always messing up the naming.

Sure "number" and "string" are easy enough, but why are "function" and "boolean" in a different format to all the others?

PropTypes cheat sheet

According to the Typechecking with PropTypes article the following types are available:

array primitive type
bool primitive type
func primitive type
number primitive type
object primitive type
string primitive type
symbol primitive type
node Anything that can be rendered: numbers, strings, elements, etc.
element An instance of a React component
elementType An element constructor (I think)
instanceOf(x) An instance of class _x_
One of the given values
One of the given types
An array of the given types
An object with certain property types
  a: PropTypes.string
An object of a given shape
  a: PropTypes.string
An object that exact matches the given shape

Why "func" and "bool", not "function" and "boolean"?

I'm always tripped up on the spelling of "func" and "bool". Mainly because the rest of the PropTypes use full names whereas these two don't.

After asking on Twitter, a few folks suggested it might be to avoid Javascript symbol names

But that still didn't answer the question because while "function" is a reserved token in Javsascript, "boolean" definitely isn't.

Eg. assigning to function throws:

> const function = 'error';
const function = 'error';

SyntaxError: Unexpected token function

But assigning to Boolean is totally fine:

> const boolean = 'truly an allowed keyword';
> boolean
'truly an allowed keyword'
> Boolean(boolean)

Further, these tokens are both allowed in an object definition:

> const ParpToots = { function: 1, boolean: 2 }
> ParpToots.function

The plot thickens

I wasn't really happy with the answers I was getting, so I did some Googling.

The search came up empty until I stumbled on this question on the PropTypes Github issue tracker from 2017:

Hi, I've searched a bit in the Readme and in the issues here, I did not find why we do not use Proptypes.function and Proptypes.boolean like we do for object (vs. obj), etc.

Why the shortnames? Are they reserved words? If not, it would be nice to create aliases maybe for these two ones no?

Which was followed up a few hours later with the answer:

Yes, you can't do const { function, bool } = PropTypes in JS because they're reserved words.

Which… is a little more satisfying.

Except we've already shown boolean isn't a reserved word. So what's going on? 🤔

boolean: a reserved word in ES3

Having found the reason why PropTypes doesn't use boolean, I needed to connect the dots. Why is it considered a reserved word?

I eventually landed on the MDN Docs on Javascript lexical grammar which lists the full set of reserved words for Javascript, as well as some previously reserved words from older specs.

And wouldn't you know; there's boolean sitting in a list of "future reserved words" from the ECMAScript Language Specification edition 3, direct from the year 2000.

7.5.3 Future Reserved Words

The following words are used as keywords in proposed extensions and are therefore reserved to allow for the possibility of future adoption of those extensions.

abstract enum       int       short
boolean  export     interface static
byte     extends    long      super
char     final      native    synchronized
class    float      package   throws
const    goto       private   transient
debugger implements protected volatile
double   import     public

The bingo card of Javascript features

Looking at the list there's a good mix of keywords that eventually made it into the spec. const, class, import, all big ticket items.

"boolean", however, was eventually removed from the list and is no longer reserved.

I'm not sure what it would have been for, but alongside "int" and "short" you could wager it was intended to be part of a fully typed Javascript spec.

In fact, peering through history I found a bunch of resources around typed Javascript as early as 2000 (Microsoft had an optionally typed implementation of JScript for .NET 🤯), and there's some fascinating papers from around 2005 that talk about what sounds a lot like modern day Typescript.

Whatever alternate history we avoided, "boolean" is no longer a reserved word. Regardless, it left its legacy on the PropTypes package and many a Failed prop type: prop type is invalid error in our consoles.

Vue & React lifecycle method comparison

🤔 This is a slightly older post. It deals with Vue 2 and React class components. This is probably not what you need if you’re building a new app today.

React and Vue both have fairly well defined lifecycle events which we can use to successfully navigate the mysteries of the virtual DOM.

So without further ado, let’s get down to the React vs Vue lifecycle events smackdown!

Vue and React fighting in an animated fashion. A caption reads "Bam!"

Vue lifecycle events visualised

The following demo logs out the Vue lifecycle events when a component mounts and updates.

It’s actually a fairly nice API in that everything is consistently named, even if not all of the events are strictly useful.

Vue lifecycle events on codepen

React lifecycle events visualised

React is actually the more esoteric of the two in terms of naming, but actually offers more powerful functionality (such as my particular favourite, shouldComponentUpdate).

Vue lifecycle events on codepen

Component mount compared

The basic workflow for a component is pre-mount → render → mount.

Vue has more events, whereas React is more Javascripty with an actual ES constructor.

constructorbeforeCreateRoughly synonymous with each other. The constructor sets up the React class, whereas Vue handles the class creation for you.
dataSet data. Vue recursively converts these properties into getter/setters to make them “reactive”.
createdData observation, computed properties, methods, watch/event callbacks have been set up.
beforeMountRight before the mounting begins: the render function is about to be called for the first time.
getDerivedStateFromPropsInvoked right before calling the render method. It should return an object to update the state, or null to update nothing.
renderrenderThe virtual DOM is rendered and inserted into the actual DOM.
componentDidMountmountedThe component is now mounted. We can make any direct DOM manipulations at this point.

We can see from our lifecycle that the perfect time to hook into the process is once the component has been mounted (in React’s componentDidMount or Vue’s mounted event).

Component update compared

Component update generally follows a pre-update → render → updated workflow. Easy!

getDerivedStateFromPropsSame as when mounting.
shouldComponentUpdateLet React know if a component’s output is not affected by the current change in state or props. We can use this to prevent React blowing away our changes.
beforeUpdateCalled when data changes, before the DOM is patched.
renderrenderThe virtual DOM is rendered and patched into the actual DOM.
getSnapshotBeforeUpdateRight before the most recently rendered output is committed to the DOM. Lets you save the previous state of the DOM for use after the component has updated.
componentDidUpdateupdatedAfter the DOM has been updated

Component unmount compared

When your component is removed from the page, sometimes you need to remove event handlers or clean up after any manual DOM manipulation.

deactivatedWhen using Vue keep-alive, the component is removed from the page but not destroyed so that we can load it again later without the overhead of component mount.
activatedThe previously deactivated component is reactivated.
componentWillUnmountbeforeDestroyWhen a component is being removed from the DOM
destroyedThe component is completely gone.

Handling errors

This is something I’ve not looked too much into, but it’s possible to catch errors from child components and change the render accordingly.

This would be most useful for a top-level component (above the routes, maybe) to show an “Aw Snap” error message into your app and stop the error bubbling up.

errorCapturedAn error occurred in a child component.


Each has their own benefits, neither is objectively better or worse. Personally I prefer the Vue naming, but prefer the power of the React API.

After pulling this info together I’m really interested to try out Vue’s keep-alive for render-intensive jobs. It’s a cool feature I didn’t know existed.

I’m also excited to play with component-level error handling, especially for larger apps. It makes a lot of sense to catch errors in the framework rather than waiting for them to bubble up to the global error handler 😅

Anyway, hope this was helpful. I learned something.

Is this thing on?

I'll be honest, I'm just trying to see if I can post posts from Netlify CMS. Nothing much to add right now, so here's some fun tweets I like.

Hey, I moved to Europe

It happened almost by accident that I moved overseas.

I've always had it in the back of my head that I'd like to work internationally at some point in my life. Just a year ago I was honoured to be invited to speak at a conference in Amsterdam, and It was my first time leaving the Asia/Pacific region. It was a total blast and was really nice to make new friends around the world, but it kinda set a few ideas going in my head.

So when I saw an off-hand remark from a school friend about an opportunity to work in the Netherlands, I followed it up nonchalantly. This started a chain reaction that ended with me selling all my stuff, renting out my apartment, and moving to another country with little more than a general sense of confidence things would work out.

So here I am. I'm in bed at my temporary hotel, having just got home from a night of drinking with my surprisingly international (and incredibly boozy) coworkers, after my third week at the company. Things have generally been pretty good.

I'm still working my way through a bunch of issues (currently trying to get Suncorp Bank to let me make a damn bank transfer), but after three weeks things are generally looking good. I am especially excited to move into my new apartment at the start of next month, so it will be nice to have a place to call home again.

There's no set plan for what I'm doing, but from here I am looking forward to making new friends, getting to know the city, and going even further in my free time to explore the rest of Europe.

To make things a little more fun I've been trying to keep a video blog. You can keep updated by subscribing on youtube if you're interested in that sort of thing.