header

Universal/Isomorphic React on a Go backend

React’s standard flow is to start with an empty HTML template from the server, and populate the DOM entirely on the client. Letting React pre-render the initial HTML for your app on the server before the client takes over has some advantages, though: it lets slower (mobile) clients load your app much faster, and it’s good for SEO for search engines that don’t support JavaScript. Since you have to run React on the server to do this, you need a JavaScript-able backend, which is why such Universal (a.k.a. Isomorphic) apps are mostly built with Node.js backends. However, you can create universal React apps with other languages too, including Go. In this post, I’ll walk through an example of a universal React app running on a Google App Engine Standard Go backend (which is slightly more constrained than a regular Go server).

Continue reading post

header

Ken Burns Effect Slideshows with FFMPeg

One of the first things that impressed me about Mac OS X when I first saw it was its screensaver. Instead of just showing a simple slideshow of your pictures, it actually used a ‘Ken Burns’ panning and zooming effect with a fancy fading transition to make the otherwise static pictures really come to life. It always sounded like a fun project to create a standalone tool to create slideshow movies that used this effect, with full control over where and how much pictures should be zoomed. It turns out you don’t really need a new tool: you can get the same result using just FFMpeg. In this post, I’ll walk through the steps of creating slideshows using the Ken Burns effect.

Oh, and cats. There will be cats!

Continue reading post

header

Universal/Isomorphic React on a Swift Backend

React’s standard flow is to start with an empty HTML template from the server, and populate the DOM entirely on the client. Letting React pre-render the initial HTML for your app on the server before the client takes over has some advantages, though: it lets slower (mobile) clients load your app much faster, and it’s good for SEO for search engines that don’t support JavaScript. Since you have to run React on the server to do this, you need a JavaScript-able backend, which is why such Universal (a.k.a. Isomorphic) apps are mostly built with Node.js backends. However, you can create universal React apps with other languages too, including Swift. In this post, I’ll walk through an example of a universal React app using Swift’s Vapor web framework.

Continue reading post

header

A Dutch Diceware List

Ever since I read XKCD 936, I’ve been a big fan of the Diceware approach for picking strong passwords, where you randomly pick words from a list to create a memorable passphrase. Sometimes, I need to generate Diceware passwords in Dutch for friends and relatives. Unfortunately, the Dutch word list from the Diceware page contains many uncommon words, non-existent words, duplicate words (yikes!), numbers, and characters (as the example ijler 100 leperd akolei kolkje on that page proves), which diminishes the memorability and usability of the generated passwords. I therefore created my own, improved lists, which you can try out directly from your browser on my password generator. The list consists of the most common Dutch words, and has an added benefit that it only contains words that don’t weaken security when leaving out spaces between words. This post discusses the details how I composed this list. The process and links can be used as a guide to generate Diceware lists for other languages.

Continue reading post

header

HAProxy Alerts with WebHooks

I want to be notified immediately when one of the backend servers behind my HAProxy instance goes down. HAProxy offers alerting functionality, but only via SMTP: when a backend goes down it sends an email to a list of recipients via an SMTP server you provide. Unfortunately, email isn’t an ideal mechanism for real-time notification, and I don’t have an SMTP server accessible from my HAProxy instance. In this post, I’ll show my setup of HAProxy posting its alerts to a Slack channel and the Pushover push notification service, using smtp-http-proxy and AWS Lambda.

Continue reading post

header

Extracting Surround Music Discs

I own a couple of multi-channel Surround Sound music albums on DVD, Blu-Ray, and SACD discs. I wanted to extract them all to a hard drive to avoid the nuisance of putting discs in slow (and often stammering) CD/DVD/Blu-Ray players with unfriendly navigation menus, and wanted to have a backup of the audio in case the discs go bad. Each of the different formats requires different tools to convert them to a playable format, so it took me some time to figure out how to convert each one of them. I wrote up a summary of the tools and processes for future reference.

Continue reading post

Unicode Emoji Combinations

Playing around with emoji over the weekend, I found out that the Unicode consortium did some pretty neat tricks here and there:

  • Country flags are encoded in such a way that adding a new country doesn’t require them to update a standard. They defined 26 Regional Indicator Symbols, one for each letter of the English alphabet. Creating a flag is just a matter of looking up the 2-letter ISO3166 country code (e.g. BE), mapping each letter to the Regional Indicator Symbol (e.g. 🇧,🇪), and concatenating them (e.g. 🇧🇪).
  • Skin tones have recently been added to the standard simply by providing 5 Fitzpatrick Emoji Modifiers (🏻 🏼 🏽 🏾 🏿), corresponding to different categories of the Fitzpatrick Scale. You take an emoji 👩, append a skin tone 🏽, and you get 👩🏽.
  • Combined emoji such as 👪 are actually just combinations of simpler emoji such as 👨👩👦 with zero-width joiner characters between them. A slightly longer one: 👩+❤+💋+👨=👩‍❤️‍💋‍👨

Have a look at this bin to see the emoji combinations live.

header

Optimizing Static Sites

As an excuse to play around with some web stuff, I pretended my website was getting so much traffic it was costing me an arm and leg to host it, and that my users complained it was too slow for them. Because my website is statically generated, optimizing it was pretty low hanging fruit, so I set out to do a few tweaks to optimize it, and wrote them down here for future reference.

Continue reading post