I recently went through the gauntlet this is trying to build and package an Electron app. I say gauntlet as the entire process of figuring out all the different ways there are to package an app for distribution was quite exhausting and a bit frustrating.

The main problem I had was that there are lots of different tools and ways to package an app. There’s electron-forge, election-packager, and election-builder. Each one claims to be either a “complete tool” or “complete solution” to create, package, and distribute an Electron app. …


While working on Keridwen, an accessible JavaScript puzzle game, I needed to get the absolute position of a game object in Phaser 3. That is, I had a large scrolling scene and I needed to know where the game object was drawn relative to the top-left corner of the canvas.

Looking through the Phaser docs I couldn’t find an API that would give me that information, so I decided to try to calculate the position myself. After a few hours of trail and error I was finally able to to do it.

My initial attempts at calculating the position involved…


Recently axe-core decided to adopt a size budget as part of an ongoing effort to improve our performance. We noted that axe-cores file size had more than doubled since the last major release and that we needed to start monitoring our size better.

With the budget in place, I started investigating ways to reduce the file size. We use webpack to bundle axe-core so I used webpack-bundle-analyzer to see a detailed view of how large each file was.

As you may have noticed, there are a few large files that make up our core codebase. The largest of those is…


Kontra.js v7 was released a few weeks ago. With it brings a host of new functionality and components as well as a new way to reduce the overall file size.

For a complete list of changes, see the v7 release notes.

TypeScript Support

One of the new features this release is TypeScript support. I was surprised last year by how many users wanted to use Kontra.js with TypeScript so I made sure to include support for it.

New Functionality

The Sprite component got a few new features this version. The biggest one is group support, allowing you to add children to other Sprites and…


I recently wanted to know if it was possible to create a custom 404 page for a website if you didn’t have access to the backend server. I thought it might be difficult since without a server you wouldn’t be able to catch the request for pages and return the 404 page based on a failed request.

After my research didn’t turn up anything, I had an idea that I thought might work.

I remembered that Service Workers could intercept network requests and respond with cached resources. Typically this is used to serve a custom offline page when the user…


Last month I participated in the Australian Bushfire Charity Jam. The premise of the game jam was to create a game in two weeks that would be sold as part of a bundle, with all proceeds going to bushfire related charities.

Now that the bundle sale has finished, I wanted to take some time to discuss how I came up with the concept of my incremental survival game Ravaged Space, how I designed it, and how I executed the idea.

But first, if you haven’t played the game yet you should head over to itch.io and play it a few…


Over the past year, I’ve been making significant performance improvements to axe-core. A few of our rules were very slow on large pages (10k+ DOM nodes), and could even freeze the page if it was too large. Slowly but surely I’ve been able to greatly improve the performance of all but one of these rules.

A few weeks ago we merged the largest and most significant performance improvement to axe-core, a culmination of over 6 months of work, and were finally able to resolve the slowest rule we had: color-contrast.

I wanted to take some time to talk about the…


While working on axe-core, an accessibility testing library, we ran into an interesting problem. We needed to be able to detect when a string of text had been replaced by a ligature icon.

A ligature icon is a special type of ligature where instead of a combination of letters it displays an icon. For example, a ligature icon for the word “file” would replace the word with an icon of a file. Examples of a ligature icon fonts include Material Icon, Ligature Symbols, and Symbolset.

The problem with ligature icons is that there is no easy way to detect when…


Every year at the end of the Js13kGames competition, participants are encouraged to write a postmortem about their experience making a small game in one month. This year I too was encouraged to write a postmortem. But not about making a game, but about Kontra.js and my experience writing and maintaining a Js13kGames game library.

Where it All Began

Back in 2015, after a few years of learning how to create JS games, I decided I was tired of copying the same code into every new game. The year before I had entered my first game for Js13kGames and noticed that there weren’t any…


I’ve been learning Vue.js recently by building a small app. Part of my app displays information using a table, so I extracted out the row into its own functional component using a render function that returns multiple root nodes. That worked great except when it came time to test the component.

<!-- Cell.vue -->
<script>
export default {
functional: true,
props: ['cellData'],
render: function (h, context) {
return [
h('td', context.props.cellData.category),
h('td', context.props.cellData.description)
]
}
}
</script>

The first tricky part was that I discovered that you can’t use propsData to pass props to a functional component. …

Steven Lambert

Web developer, HTML5 game developer, JavaScript enthusiast. Creator of the kontra.js game mirco-library https://github.com/straker/kontra

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store