Coding with Jesse

Trying to decide what to do next? Follow the light.

January 1st, 2023
A tree growing towards the light

Happy New Year! I've been trying to come up with a New Year's resolution, and it got me thinking about setting goals, finding and following your purpose, and how this ties into some books I read this year.

TL;DR: If you're trying to decide what to do next in your life, in which direction you should expand and grow, maybe it helps to think like a tree and go where the sunshine is.

The purpose of life

The most interesting book I read in 2022 was The Romance of Reality, where Bobby Azarian does an amazing job applying Darwinism to the universe.

He says that the universe itself is a self-organizing system, with a bias towards increasing order, complexity and awareness. The idea is that the process of evolution was around before life emerged. Life formed at the bottom of the ocean at thermal vents, where tremendous amounts of extreme heat energy met extreme coldness. Eventually, the first forms of life emerged here to capture that wasted energy and put it to use.

Fast forward to the present, and now we have complex life everywhere we look, actively consuming any and all food and energy available and using it to maintain the structures of our bodies, our systems and our species.

As lifeforms, humans are sentient agents of the universe whose purpose is to use our awareness and intelligence in order to optimise the conversion of available energy into complexity and order.

It's not hard to see how true this is. So much of what we do boils down to consuming energy (food, fuel, heat) so that we can create more order (clean homes, growing families, bigger cities, information, content creation). Pretty much every job is related either directly or tangentially to this process, or optimizing the process.

We've even dug towards the centre of the earth and the centre of the atom in order to unlock and consume more and more available energy and use it to create increasingly complex systems and structures.

So how do you fit into all this? And how can you use this perspective and knowledge to live a good life?

Following your dreams

I just finished reading The Alchemist by Paulo Coelho. It's a story about following your dreams. It's about a shepherd boy in Spain who dreams about finding treasure at the pyramids in Egypt. Following the guidance of those he meets along the way, he goes on a quest to literally follow his dream and see where it leads.

I've always liked stories about following your dreams. I've always tried to follow my own dreams. Once upon a time, I was stuck in the proverbial office job, and dreamed of the day I could be working from home, setting my own hours, choosing work I found interesting. I dreamed about buying a house, getting married and having children.

I followed those dreams, and soon started freelancing. Several years later, I bought a house, got married, and now have the family and life I'd always dreamed about.

So now I'm looking to the future, wondering where to go from here. There are so many possibilities that it's hard to focus and hard to decide.

Thinking like a tree

We're all in search of our potential. It's not just about finding happiness, but also finding activities that won't burn us out, that are sustainable in every sense of the word.

A tree will put more energy into the branches that get more sunshine, because opportunity creates a void that must be filled. Nature abhors a vacuum.

Thinking about our careers, interests and opportunities, it's as if we are trees with branches growing out in many directions, and we are trying to decide whether we should grow in this direction or that.

Like a tree, we can feel the energy coming from each branch to decide whether it's getting more sunshine or less. Sometimes this process is described as market research, trying to establish whether there is demand for a particular enterprise. Is it time to hire an employee? Or write a book? Or start a non-profit? Or teach? Or make a video game? Or take time off and travel? Or just hunker down and work harder doing the same things as ever?

Energy can take the form of light, or heat, or money, but also inspiration, joy, excitement and motivation. Which activities will give you a turbo boost and allow you to grow and expand further? Which are a dead end? You can also see which of your branches are already giving you more energy back. And you can expand carefully, incrementally, to get more feedback, to see if these directions are the right directions for you.

They need not expand forever in any given direction. Maybe there's a ton of energy available to move in the direction of, for example, publishing one small video game. But maybe that's also where it stops, and going all-in on video game development would be a terrible mistake. Or, maybe it opens up a new opportunity, one nobody could see or feel from here?

Follow the light

Follow your passions? What does that even mean? Instead, follow the light.

What is shining brightest to you right now? Where are your branches expanding to, and which of those branches are shouting "Go this way!!" Optimize for excitement. Learn how to convert some of that sunshine into food, by bringing joy to others (aka "providing value") such that others will be happy to give you sunshine tokens (aka "money") for the joy you bring.

If something excites you, it'll likely excite others. Because you do not live alone in a desert. If you can capture a bit of that sunshine out of the air, you can make it available to the whole world. And when you do, more energy will flow back from the world to you, as if to say "Yes, keep going!"

Follow the light. Capture excitement out of the air and share it with the world.

Add Mastodon replies to your blog

December 27th, 2022

You can now comment on blog posts on Coding with Jesse! I turned off comments years ago, because I was getting tons of spam. But recently, with my return to social media, I decided to integrate Mastodon to give people a way to comment on and interact with my articles.

Initially, I wasn't sure how I would accomplish this. Mastodon has a ton of servers, and Mastodon search can only search for hashtags, so how would I know whether someone commented on my article? And how would I integrate it into my website?

I looked around at how some other blogs were handling this, and came across Webmentions, and particularly, It's a web standard for communicating interactions across web servers! Perfect!

I naively assumed that Mastodon would automatically hit my server with notifications any time someone favourited, boosted or replied to a post that contained a link to my site. But alas, Mastodon doesn't do that for privacy reasons (understandably).

Fortunately, I'm not the first one to run into this problem, and so there's a free service available that solves this problem. If you sign up for, you can link your social media accounts, including Mastodon, and will automatically send webmentions to your site whenever one of your posts contains a link to your site, and people reply to, boost or favourite your post. Essentially, your Mastodon posts become an anchor for all the interactions on your blog posts.

With these two services in hand, here's how you can integrate Mastodon into your website the way I did:

1. Sign in to

You need to sign in with your website URL, and your GitHub account. Also, your blog needs to link to that GitHub profile with either <a href="" rel="me"> or <link href="" rel="me">, to prove that you own the site.

2. Add webmention tags to your blog

When you sign in, go to Under Setup, you'll see these two link tags:

<link rel="webmention" href="" />
<link rel="pingback" href="" />

Copy these and paste them into the <head> on your blog. These will tell other services (like where they need to send webmentions for your posts.

Go to and, if you're like me, you'll want to click on "Cross-post to a Mastodon account", so that it'll integrate with your existing Mastodon account.

4. Post a link to a blog post on Mastodon

Try linking to your most recent blog post on Mastodon. If you already did this some time ago, will scan your posts looking for links. You can also feed it a URL to a specific Mastodon post so that it will discover it. will periodically poll your account looking for new interactions on these posts, and will send any new favourites, boosts or replies to

Note that your post doesn't count as a webmention - only the interactions on that post do. But you can reply to your own post as a way to trigger a webmention.

When I was setting this up, I was logged into both and, clicking the "Poll now" button on and eagerly looking for interactions to show up. You have to have some patience here as well, as both services have a bit of a delay.

Once you see some mentions show up on, you're ready to render them onto your blog.

5. Add the webmentions onto your website

Here's the trickier part. You'll need to hit the API and fetch the mentions for your blog post. You can do this server-side, if you want. My blog is static, so I needed to do this client side.

Since the results are paginated, you can only get back 100 at a time. I wrote this function to help me retrieve all the pages at once, and sort the results into chronological order:

async function getMentions(url) {
    let mentions = [];
    let page = 0;
    let perPage = 100;

    while (true) {
        const results = await fetch(
        ).then((r) => r.json());

        mentions = mentions.concat(results.children);

        if (results.children.length < perPage) {


    return mentions.sort((a, b) => ((a.published || a['wm-received']) < (b.published || b['wm-received']) ? -1 : 1));

Then, I used the results of this to pull out four things: the favourites, boosts, replies, and also a link to the original post where I can send other visitors to my blog if they want to "Discuss this article on Mastodon". Here's how that looks:

let link;
let favourites;
let boosts;
let replies;

const mentions = await getMentions(url);

if (mentions.length) {
    link = mentions
        // find mentions that contain my Mastodon URL
        .filter((m) => m.url.startsWith(''))
        // take the part before the hash
        .map(({ url }) => url.split('#')[0])
        // take the first one

    // use the wm-property to make lists of favourites, boosts & replies
    favourites = mentions.filter((m) => m['wm-property'] === 'like-of');
    boosts = mentions.filter((m) => m['wm-property'] === 'repost-of');
    replies = mentions.filter((m) => m['wm-property'] === 'in-reply-to');

Of course, you should replace the link to my profile with the link to your own. I'm taking the first mention (after sorting chronologically) that is interacting with one of my posts, and linking to that post URL.

With those in hand, you'll have everything you need to render the replies, boosts and favourites to your blog. My approach was to render just the avatars of everyone who boosted or favourited my post, and all the replies.

One thing to watch out for is that the content of each reply is HTML. To be safe (paranoid), I'm running the HTML through sanitize-html to make sure nobody can inject sketchy HTML into my site.

6. Allow people to share posts without mentions

For any posts that don't have any mentions, I added a different button, "Share this on Mastodon". When you click it, it runs this code, which prompts you for your Mastodon server (inspired by Advent of Code's share functionality):

const server = prompt('Mastodon Instance / Server Name?');

if (server) {
    // test if server looks like a domain
    if (!server.match(/^[^\s]+\.[^\s]+$/)) {
        alert('Invalid server name');

    const text = `"${post.title}" by @[email protected]\n\n${url}`;`https://${server}/share?text=${encodeURIComponent(text)}`);

Yay for Mastodon comments!

I'm really happy with how this turned out. To add some placeholders on my old blog posts, I posted some links to some of the more recent posts, so they interactions would have a place to live. For the older posts, I'm just relying on the share functionality.

I'm considering implementing some server-side functionality to replace either or in the future, so that the mentions live in my database instead of relying on a third-party service that may disappear one day. I think I could also skip the webmentions process by associating a Mastodon post URL with each blog post, and then using the Mastodon API of my server to periodically check for interactions and replies. Or maybe it could log in to my server and listen for notifications. But for now, this works really well.

So from now on, whenever I write a new blog post, like this one, I'm sure to share in on Mastodon and give a place for readers to ask questions or discuss the article. Check the end of this blog post to see how it all looks, and be sure to favourite, boost or reply to my Mastodon post so that you show up on the page as well!

Advent of Code 2022

December 4th, 2022

I've been really enjoying working on this year's Advent of Code. If you haven't heard of it, it's a series of coding puzzles, two a day for 25 days, from December 1st to December 25th every year. It only started a few days ago, so it's not too late to catch up. Or, if you're reading this later, you can always go back and try it out at your leisure. But, it is a lot of fun to wait until midnight each day to see what the next puzzle is.

What's cool about it, is that you can use any programming language you want. You just need to take an input file, run a calculation based on the puzzle instructions, and come up with an "answer", which is usually a number of some kind.

You can use your favourite language to try to come up with an answer as fast as possible, or you can use it as an opportunity to strengthen your skills in another language, even a language you've never used before and want to try out!

You need to log in with GitHub, Google, Reddit or Twitter, and then you can download an input file for each day. You'll need to read the input file in to your language of choice, and parse and process each line of the file.

If you're really fast, you can even get on the leaderboard. But doing that requires completing the puzzles in just a few minutes at midnight EST so that you're one of the first 100 people to do so. I'm definitely not fast enough to even bother trying!

So far, I've been using JavaScript with Node.js this year. My approach is to pipe in the input into my puzzle solution like this:

node solution.js < input.txt

To do this, I'm using an npm library called split that simply splits a stream into lines, to make it easier to work with. Here's a simple example that just counts the number of lines in a stream:

import split from 'split';

// keep some variables in the module scope to keep track of things
let count = 0;

// read the input file as a stream from stdin (Standard Input)

    // pipe it to the split library, to split it into lines

    // receive a callback for each line in the stream
    .on('data', (line) => {
        // do something with each line, in this case just counting

    // receive a single callback when the file is done
    .on('end', () => {
        // do something at the end, eg. console.log the output

If you're interested, there is an online community on Reddit where you can share your solution and join in the discussion to see what others have done each day.

I'll be sharing my progress on Mastodon at @[email protected], so you can follow me on there for updates and commentary.

I've also been pushing my solutions to Advent of Code up to GitHub, so feel free to see how I've approached it, if you're interested. But no cheating! 😉

Why I love Mastodon

November 27th, 2022

I quit Twitter at the end of 2020, and haven't really used social media at all since then. So when I heard in the news that others were ditching Twitter for Mastodon, I got really excited!

I signed up for Mastodon back in May 2019 and, at the time, I wrote on there: "I just heard about Mastodon a few days ago. I keep spelling it Mastadon. It's a really cool platform and architecture, and I would love to see it completely replace Twitter one day. Do you think it could?"

It seems like that time has come. Not everybody has moved from Twitter to Mastodon, but a large number of developers have, and that's what matters most to me.

A wild month

In 14 years of using Twitter, I never went viral. The closest I came was when I published my blog post Svelte is the most beautiful web framework I've ever seen. The tweet linking to that post received 40 retweets, which had my head spinning at the time.

Well, in the past month, I've had three toots that were more successful than that. And one of those went absolutely viral! I was excited about Mastodon and hoping all these new migrants would stay, so I wrote "Boost this toot if you're planning on sticking around Mastodon whether or not it becomes more popular than the birdsite.", and so far I've received 217 replies, 3,254 favourites and 5,765 boosts!

I also tooted a list of web developers worth following and that received 77 favourites and 52 boosts.

I'm not trying to brag, I just want to demonstrate that the reach and discovery on Mastodon is so much greater than Twitter. Part of that is that there is no algorithm on Mastodon, part of it is that people can browse "local" or "federated" feeds to find new posts from people they don't follow, so it's much easier for new users to reach a lot more people. I also find that the quality of interactions is higher, and the conversations more intelligent and engaging.

As another example, I tried putting a poll on Mastodon and Twitter at the same time. I had 7 people answer the Twitter poll, but 43 on Mastodon! This and other experiments I've done have cemented for me just how much more easily I can reach and connect with other like-minded people on Mastodon.

Whatever it is, I've definitely experienced a lot more joy interacting on this platform. It's wonderful that there are no ads, there's no company profiting off our use of the platform, and we can own our own content. It's not a new company trying to launch a startup to replace Twitter, it's a platform built on an open web standard that will surely be around for a very long time!

What is the platform?

As a web developer, I was excited to learn that Mastodon is actually built upon ActivityPub, a web standard produced by the W3C, the standards body behind other technologies you may have heard of, like HTML and CSS.

ActivityPub is similar to RSS but with pushing content instead of polling a feed. It allows web sites to publish content, and have other web sites subscribe to that content. When a new post is available, the content is pushed to each of the subscribers so that they immediately find out about it.

The world of systems that work with ActivityPub is referred to as the Fediverse. Mastodon is a Twitter-like interface built upon this platform. There is also Pixelfed, an Instagram-like platform, and PeerTube, a YouTube-like platform. Anybody can create new platforms that integrate with the rest of the Fediverse, just by implementing the ActivityPub protocol. There is even a WordPress ActivityPub plugin so that any WordPress blog can be followed by others on the Fediverse.

Mastodon Servers

If you've heard anything about Mastodon, you've heard about how you have to choose a server. This is a weird step for many people, at least compared to large corporate centralised social media, but it's what we already have to do for things like e-mail (though most people choose There is no central Mastodon server, so you need to choose one to get started. But the great thing is, you can move to a different server, and anyone who follows you will automatically follow your new account (though you can't move your posts). You can even run your own server!

One easy strategy is just to pick any server that is currently accepting new accounts, and then accept that you may well decide to move elsewhere once you get a feel for things and settle in and discover a server that resonates better with you.

You can go to the Mastodon website or to browse servers. You could choose one that is somewhat relevant to your interests or location, or you could choose one that is totally generic. Or just choose one that has a name that you like. Like email, it will be part of your address.

Some development-related servers include,,,, and, though the last two are closed for registrations at the time of writing this.

Back in 2019, I started off on, but decided the next day that I'd rather be on a bigger, more popular server, so I moved to But earlier this month when I started using Mastodon heavily, I actually decided I'd rather be on a smaller server focused on web dev, so that I would have a "local" feed more useful and interesting to me, so I moved back to!

Migrating to Mastodon from Twitter

If you were already active on Twitter, you'll be glad to know there are tools to help you migrate. I highly recommend you check out Movetodon, where you can log in with both your Twitter and Mastodon accounts, and you can search for and automatically follow people. Of the 1025 people I follow on Twitter, I can find 164 of them on Mastodon, and more are moving over every day.

If you do decide to move over, be sure to put your new Mastodon address in your Twitter bio, so others can find you using automated tools as well.

I really hope this migration sticks, and so I think the best thing we can do support it is to participate as heavily as we can on there, to follow interesting people, to boost interesting posts, and to be active and contribute to the conversation so that others enjoy it there and stick with it too.

Follow me!

If you'd like to follow me, you can sign up for Mastodon (or another Fediverse server) and follow me at I hope to see you there!

How I use GitHub Copilot to be more productive

March 1st, 2022

GitHub Copilot is a VS Code extension that brings machine learning into your development environment. It will upload snippets of your code to Microsoft's servers, and send back a list of suggestions of what it predicts will come next.

Some people have wondered whether our jobs as developers are doomed, now that machine learning can write code for us. Will computers be able to write all the code in the future without needing developers involved? I really don't think this will happen, but I do think our jobs will get a bit easier with help from tools like Copilot.

"Copilot" is a really good name for the tool, because although it won't write all your code for you anytime soon, it makes very helpful suggestions most of the time. Often, you'll have to make some tweaks to the suggestion to get it working correctly. You're still the pilot here, but Copilot is sitting beside you actively trying to make your life easier.

When I started using Copilot, I thought it was super creepy. I could write comments and Copilot would suggest code that does what the comment says. I'd never seen anything like this before. I also had mixed feelings about using code that seemed like it might be plagiarised directly from some GitHub project.

Three months later, it has become fully integrated into my development workflow. When I'm coding somewhere without Internet access, I'll find myself briefly pausing to see what Copilot suggests, only to realise that I'm on my own.

Generally, I write code the way I used to before, and GitHub Copilot will suggest just a few lines of code for me at a time. Much of the time, the suggestion is almost exactly what I would have typed anyway.

Even though I've been coding professionally for decades, Copilot has made me even more productive. Here are a few ways that Copilot has changed the way I work.

Don't repeat yourself, let Copilot do it for you

Probably the most reliable use of Copilot is to set up some kind of pattern and allow Copilot to repeat the pattern for you.

For example, I never have to type out something like a list of months. I can just write a descriptive variable name, and Copilot will suggest an array for me:

const MONTHS = // ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];

If you want a different format of month, you just give it an example and Copilot will suggest the rest:

const MONTHS = ['Jan.', // 'Feb.', 'Mar.', 'Apr.', 'May', 'Jun.', 'Jul.', 'Aug.', 'Sep.', 'Oct.', 'Nov.', 'Dec.'];

Notice how "May" doesn't even have a period after it? Copilot is surprisingly good at this sort of autocomplete.

In other cases, where your code has a repetitive nature to it, but you maybe don't want to over-complicate things by writing a loop, Copilot can save you the hassle. For example, if you're creating an object with property names, and the values use the name in some kind of pattern, give an initial example, Copilot will do the rest for you:

return {
    age: model.getAge(),
    address: // model.getAddress(),

With this sort of pattern, I go one at a time, pausing briefly after each property name and hitting TAB to autocomplete once Copilot figures it out. It saves me some typing and the inevitable typos too.

It finishes my sentences

VS Code is already quite good at using Intellisense to make useful suggestions, or to close parentheses and brackets for me. Copilot takes that to the next level, and often suggests the whole rest of the line for me. Sometimes it's wrong, but often it's exactly right.

For example, if I'm writing some filter statement, Copilot will make a good guess as to how the rest of it will look:

const activeItems = items.filter( // item =>;

Good guess! But if that's not how I named my variable, I might keep typing to give it more context:

const activeItems = items.filter(item => item.status // === 'active');

The more context Copilot has, the more likely it will guess correctly. At some point, Copilot generally figures out exactly what I was about to type, and when it does I can just hit TAB and move on to the next line. It's trying to read my mind, and when it gets it right, that means fewer keystrokes and probably fewer typos too.

Even if it only ends up suggesting a couple closing parentheses and a semicolon, I'm happy for the help.

Naming things is easier

Phil Karlton famously said that the two hardest problems in computer science are cache invalidation and naming things. Copilot makes at least one of these a bit easier.

You saw in the previous example, that when I was filtering on an array of items, Copilot suggested item as the argument in the filter function. This is a simple example of where Copilot gets things right almost every time.

Usually I'm not too picky about function or variable names, so if Copilot comes up with something half-decent, I'll go with it. I also think that it's probably well informed by what many others have chosen before, and I think familiar variable names are probably better names anyway.

For example, if I'm about to write a SQL query, Copilot will make up the table and column names for me as good or better than I will:

async function addBook(params) {
    await query( // `INSERT INTO books (title, author, isbn, description, image, price, stock) VALUES ('${params.title}', '${}', '${params.isbn}', '${params.description}', '${params.image}', '${params.price}', '${params.stock}')`);

Wow, it did that with no context other than "book". Obviously there must be a bunch of open source code or demos that work with books in a database. Those might not be the names I end up choosing, and I probably won't need that exact list of columns, but often they'll be pretty good, and might make me think of something I'd otherwise miss. More than once, Copilot has suggested better names than I had planned on using.

But notice that there's something really dangerous in this suggestion! The values are being inserted into the database without being escaped! This is a security flaw, and a major reason why you still need to be careful and knowledgeable about the code that Copilot is suggesting. It won't always be secure, or even good. You still need to be the pilot here. Same goes with any code you find online.

I don't need Stack Overflow as often

Speaking of finding code online, I rarely have to actively go out and search on Stack Overflow or GitHub anymore. If I'm not sure how to do something, I'll use a descriptive function name or write a comment that describes what I'm trying to do. Most of the time, Copilot will make a useful suggestion. More than once, I've learned something new from the suggested code.

function getRandomNumber(min, max) {
    // return Math.floor(Math.random() * (max - min + 1)) + min;

I think of Copilot as searching through publicly available source code for me, to find examples where someone else has done the exact same thing before. I really don't want to accidentally plagiarise a large block of code from GitHub without knowing where it came from. But I will let Copilot suggest a line or two of code for me, that does something a bit tricky but fundamental, where the code would have been essentially identical had I worked it out on my own.

It knows how I intended to use that new variable

When I'm writing a function and declare a variable, Copilot will often have a good idea about how I intended to use that variable. Often, the suggestion here will be bang on.

function processItems(items) {
    const activeItems = 0;

    for (const item of items) {
        // if ( {
        //     activeItems++;
        // }

Sometimes, I'll forget about a variable I'd declared earlier, so Copilot's suggestion ends up being a friendly reminder to use the variable. Even if the suggestion is wrong, the reminder ends up being useful.

Test-driven Copilot Development

The most surprising thing that Copilot has done, was suggest for me all the code I needed to make my tests pass, even though the tests were in a different file! I didn't know Copilot was capable of this, so it was a big surprise when it happened.

Let's say this was your test file, model.test.js:

import Model from './model.js';
import { deepEqual } from 'assert';

it('should return an empty array by default', () => {
    const model = new Model();

    deepEqual(model.get(), []);

it('should double the numbers provided', () => {
    const model = new Model();


    deepEqual(model.get(), [14]);

Open up a blank new file model.js, type export default and Copilot will automatically suggest the rest:

export default // class Model {
    // constructor() {
    // = [];
    // }

    // get() {
    //    return;
    // }

    // add(number) {
    // * 2);
    // }
// }

Tests pass without writing any code! This brings Test-Driven Development to a whole new level, where you can focus on writing good tests, and Copilot will write the code that passes the tests! It doesn't always work this well, but when it does, you can't help but giggle in delight.


When I first tried Copilot, I thought it was super creepy. Now, I see Copilot as my delightful junior assistant, the two of us collaborating on writing code. The more predictable you can be, by using descriptive function names and variables, the more likely Copilot will correctly predict what you're trying to do.

As I write this, Copilot is still in Technical Preview, and so you have to apply to be on the wait list. I only had to wait a day when I applied, but you may have to wait longer or might not be approved at all. One day, Copilot will likely cost money to use. I think I'll probably be willing to pay for it, because it does save me time and energy, ultimately making my services more valuable.

I hope you get a chance to try out Copilot for yourself. It's fun to use, and can even make you a more productive programmer too.

<< older posts newer posts >> All posts