Skip to content

Instantly share code, notes, and snippets.


Jimmy Breck-McKye jbreckmckye

View GitHub Profile



Micro-frontends are a strategy for splitting user interfaces up into separately deployable units. This gives teams great latitude to choose their own technologies and think in terms of self-contained programs. However, the "per page frontend" approach has disadvantages: pages cannot be shared by teams; sub-frontends are hard to modal-ise; and the user must download and execute duplicate JavaScript. Nano-frontends are an alternative that give teams similar freedoms but provide opt-in optimisations to improve user experience.

Give me the gist

Write your frontends as libraries that take a) a DOM element to render in and b) a set of common dependencies to call (e.g. React). Then allow a scaffold app to render the entire thing and inject the dependencies. Libraries can be published by writing artefacts to S3 and then monitoring for changes using SNS/SQS.

What does a 'dependency injected' frontend look like?

jbreckmckye /
Last active Oct 12, 2020
TypeScript hack: getting access to the members of a union

I had some fun with TypeScript union distributions this weekend. This is a (kinda) hack around conditional types that lets you access the individual members of a union in a generic type.

A usecase for this might be when your function accepts items from a union of types, but you want all your function parameters to be consistent in which 'branch' of the union they specify.

Let's say you have a type representing some events (this is a contrived example but simple)

type Events =
  | { kind: 'loading', data: void }
jbreckmckye / fun.ts
Created Oct 11, 2020
Fun with distributions
View fun.ts
// Fun with distributions
// You probably know that TypeScript has union types
type StringsAndNumbers = string | number;
// You also probably know about 'discriminated unions' or 'tagged unions',
// representing different kinds of structs
type Eventing =
jbreckmckye / British PC Layout.keylayout
Created Jun 3, 2020
MacOS British PC keyboard mapping (put this in Library/Keyboard Layouts/)
View British PC Layout.keylayout
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE keyboard SYSTEM "file://localhost/System/Library/DTDs/KeyboardLayout.dtd">
<keyboard group="0" id="5001" name="British PC Layout" maxout="2">
<layout first="0" last="0" modifiers="48" mapSet="312" />
<modifierMap id="48" defaultIndex="0">
<keyMapSelect mapIndex="0">
<modifier keys="" />

GHCIDE & VSCode setup

1. Install Stack

curl -sSL | sh
stack upgrade

Then ensure ~/.local/bin is on your $PATH.

jbreckmckye / group.js
Last active Oct 10, 2019
Group objects by a string field
View group.js
function group (rows, discriminant) {
const asMap = rows.reduce(
(acc, item) => {
const key = item[discriminant]
return {
[key]: acc[key] ? [...acc[key], item] : [item]
jbreckmckye / groupedThrottle.js
Created Apr 24, 2019
Grouped throttle function
View groupedThrottle.js
function throttleGroup(fn, count, delay) {
let queue = [];
let nextDrain = null;
function scheduleDrain() {
nextDrain = window.setTimeout(drainQueue, delay);
function drainQueue() {
const groupSize = Math.min(count, queue.length);
View get-webgl-contexts.ts
// Get a WebGL context
import {Perhaps, None, Some, Any} from 'highly-questionable';
const canvas = document.createElement('canvas');
const context = Perhaps
.orFrom(()=> canvas.getContext('experimental-webgl'));
jbreckmckye / promise-first-truthy.ts
Created Dec 6, 2018
Get first truthy promise result
View promise-first-truthy.ts
function firstTruthy<T>(promises: Array<Promise<any>>): Promise<T|null> {
return new Promise((resolve, reject) => {
// If any promise returns truthy value, immediately resolve with it
promises.forEach(async promise => {
const result = await promise;
if (!!result) resolve(result);
// If any promise rejects, immediately throw the error
jbreckmckye / watchr.d.ts
Created Nov 22, 2018
TypeScript definition for watchr js
View watchr.d.ts
/// <reference types="node" />
declare module 'watchr' {
import {Stats, FSWatcher} from 'fs';
import {EventEmitter} from 'events';
export type ChangeType = 'update' | 'create' | 'delete';
export type State = 'pending' | 'active' | 'deleted' | 'closed';