Prefer Boring Technologies

Boring technology prevents surprises.

Surprises slow down development. Use boring technology unless overridden by another constraint.

I tend to get a lot done when I’m excited about the newness of something. I feel the excitement and get into “the zone” a lot easier when I’m trying out new tech. When it’s time to build a project for maintainability and longevity it’s best to have already gotten that out of one’s system. Know the tech that you like using the best and are most familiar with. Learn new things so that when it’s time to build something serious you have the knowledge base so fewer things will be surprises. Adopt very few “surprising” things. Surprising other developers (and future you) is a bad thing. It causes frustration and confusion. People will make assumptions about tools and libraries instead of reading documentation. So chose tools and languages and libraries that are widely understood and easy to learn about. Try not to implement things in surprising and clever ways.

Use well-maintained technology.

If the tool is simple and just “finished” then evidence of frequent maintenance releases isn’t really a problem.

Normally I want to see that maintainers of a project are putting out minor patches pretty frequently. Hopefully they are updating their dependencies and responding to support requests and merging pull requests. If the tool is very niche, and if it doesn’t have any dependencies to update then that’s actually better because there is less for the library author to maintain. But generally I want to see that some releases have happened in the last 6 months and issues do get answers or comments sometimes.

The biggest risk we are trying to mitigate with checking maintenance frequency is, If you run someone else’s code, and it runs in a dynamic context where we see frequent new and emerging interactions with other technologies, or where users and clients will be calling it directly (like an API server), then it had better be frequently updated and maintained and scanned for security vulnerabilities.


World-schooling: Life Abroad with Kids

We’re on the move again after many years. We wanted to pursue a new way of life with our kids for a while. We wanted to see if we could be happy and healthy in a Central-American country with our little ones, while I work remotely for Granular and Becca educates them. We are able to do this with the help of our friend Adriana and Chris, they wanted their kids to have the chance to see more of the world and experience life in other cultures too. Our children all get along really well, so last year we began planning and searching for the right place to go together.

In early January we first traveled to Valladolid, Mexico where a wonderful couple set up and hosted a great world-school program for 2 weeks. The whole thing went so fast. And gave us a great introduction to this lifestyle. We experienced families living together in intense community - we learned about Mayan culture and traditions, we explored ruins, cenotes, beaches and caves.

The kids grew a ton through this experience - I’m not at all worried about them missing out on important educational content. We’re taking their 6 and 8 year-old minds to places that will make them better people along so many dimensions. Becca and Adriana work hard to give them some school-like structure and to keep them focused each morning.

Now we’ve arrived in Costa Rica, and we are staying in a mountain town here for at least a month. I took time off while we were in the Yucatan peninsula, but now am back to a daily working schedule. I find that I’m way happier to wake up and start work in the morning during the last week or so. The days go quickly, and I can hop in the pool or lounge on the hammock when I need to take a break.

It’s pretty hot in Costa Rica compared to Mexico this time of year. But a strong breeze comes through in the evenings and mornings to cool things off, and tonight it’s actually very comfortable.

The cicadas are loud. Really loud.

I’m excited about exploring a new country, driving around and seeing new places, just getting to know a place and the cool things to eat here. Our hope is that we and the kids will get a big boost in our Spanish language learning here from a tutor we’ve hired. And I really hope this trip gives us energy and excitement to keep traveling and seeing more of the world. We don’t know what is in store, but I’m not going to miss this because of fear of the unknown. Also, it’s really freaking cold in Colorado. 🥶

The internet has been … kinda meh everywhere. I have to use a cellular hotspot pretty regularly. Pre-paid data in Costa Rica is about $4 USD for 10 gigs. The GlocalMe Duo Turbo is the hotspot I chose.

I brought along a few work gadgets to make my office more comfortable. Unfortunately it’s not practical to pack my office chair and standing desk, but I have this compact laptop stand from ElfAnt and I packed a Logitech MX Keys Mini Keyboard and Logitech MX Anywhere 3 For Mac Mouse. I use my Surface Headphones 2 with noise cancelling. I forgot to bring my trackpad for my left hand — and I miss it a lot.

I also have a few backup batteries that can provide USB-C PD strong enough to give my laptop a little extra time, or run a router here in the rental house if power goes out. That may have been over-kill. Power has not been a problem at all yet.

I’m excited to learn more, to see how my perspective and priorities change, and to see what we want to do as a family when our current itinerary runs out in March. Will we immediately have more to do, or will we want to go back home then?


Desk-ercise: Working on a Bike is Working Out

A few months ago I started a new job with a great company that provided some budget for setting up home-office equipment. I decided it was time to try out a standing desk for real, and I added an extra special acessory, a stationary bike that fits under a desk.

I have a real on-again-off-again relationship with fitness. I tried standing at my desk at work 8 years ago, but gave up because I didn’t have a powered desk that goes up and down easily. If I wanted to stop standing I had to move my laptop and extra monitor off the shelf. More recently I have tried Fitbit trackers over the years, but stopped wearing my Versa 2 about 6 months ago.

So I’m back into the gadget zone, I have the standing desk from Flexispot the Adjustable Standing Desk Pro Series and to go with it a Sit2Go Fitness Chair.


I started out using the bike at the 2nd difficulty setting (out of 6). And this was comfortable and fun, it got me moving and it felt easy to rack up 10+ miles on the display each day. I could still talk and think clearly during meetings without being winded. I’ve been pretty regular about using it for the last month.

Then I decided to put my fitbit again and start working towards a tracked goal. Since I don’t get to walk every day especially during the winter months, I set my primary goal as “Active Zone Miunutes”. The fitbit uses it’s heart-rate sensor to detect when you are in the fat-burn zone (worth 1 minute) or cardio zone (worth 2 minutes) and that seemed like something I can do easily each day from my desk. I set the goal to 22 minutes, which is the default, then tried to get my minutes counted.

Unfortunately, when I ride the bike normally I only get my HR up to about 100bpm. This isn’t good enough! I only earn AZM minutes on the fitbit when my HR is above 115. And I only get my 2X cardio minutes when I’m above 130. So I cranked the difficulty level up to 4 and started really pumping on those pedals. Unfortunately this means I can’t do the exercise during meetings anymore, I have to find a spot where I’m not expected to talk or think deeply for 20+ minutes. But at least I don’t have to go to the gym for it.

Also I love the standing desk, it has 3 different height settings. Of course I still don’t love how shaky and bouncy my monitor is when I move or type, but that problem could only solved by switching back to my heavy steel workbench.

ADHD Dev Journal: Module Federation Thoughts

8:52 AM

Using Task management software consistently for more than a couple weeks is hard.

9:02 AM




9:55 AM

Webpack Module Federation creates a really interesting opportunity to evaluate code ownership and maintenance in a web application. If we break up any application into small pieces then there has to be tools and processes in place that reliably reassemble those pieces together back into the running application that the user interacts with. The reasons for breaking the code apart into different modules in the first place is important. There’s several reasons:

  1. Understanding. It’s easier to understand and comprehend the scope of a function when it’s been isolated and designed with a specific interface.

  2. Engineer ownership. The actual people that do the work may not want to be slowed down by understanding and running tests for a larger code-base, they may want to write, test and deploy a piece of code that is smaller in scope so they can move faster.

  3. Isolation from side-effects. Depending on the technology and interface definition, the two different code-bases may be less impacted by bugs in each other when they are isolated.

Most of the other reasons I can think of depend on the method of isolation/separation. For instance, in module federation, JS components are loaded from an http endpoint and injected into the host application in the browser at runtime. This means the developer of the host application isn’t able to see and predict the effects of every change that happens in a federated module they are loading. Whereas if the module was loaded a build time, using webpack on the CI/CD server, then the JS code that is loaded will always be knowable and testable by developers before it is run by the user’s browser.

The big drawback of build-time integration is that fixes and updates to the module must be pulled, tested, and approved by a developer before they are deployed to any users. So, runtime integration through webpack module federation gives us back some of the freedom we had on the web before we all started using bundlers and NPM for our dependencies. Back in the day we could choose which dependencies were loaded as always the latest version, or which ones were pinned to a specific version or “fingerprint”.

<!-- This component will be cached by the browser, but can be updated by whoever can push changes to the CDN, no change to this html file is needed. -->
<script type="text/javascript" src="cdn.mydomain.com/js/always-latest-component.js"></script>
<!-- This component has a fingerprint which means if a new version is pushed, then this HTML file must be updated too -->
<script type="text/javascript" src="cdn.mydomain.com/js/pinned-component.6fe4afd32a.js"></script>

That’s a simplified example of what we’re talking about. It wasn’t an issue when the html file and JS file were maintained and owned by the same team. But, as organizations grow and ownership is divided further and further, the repo and build process responsible for the html file may not be the same as the JS file. This can cause terrible slowdowns when a component developer can’t see their changes in production until the upstream team adopts them and deploys them.

The adoption of webpack and NPM set the default for modern applications to always have every dependency pinned and fingerprinted at build time. This type of bundling and compilation step made the end result more predictable for web developers by simplifying the mental model of where your code comes from.

Changing that model to include runtime dependencies through webpack module federation, modern ES Modules in the browser, or a script tag with a src that wasn’t compiled in webpack will complicate the maintenance and debugging story for an application, while offering certain advantages in letting different developers update and maintain different parts of an application independently.

ADHD Dev Journal: After a long weekend

Getting away with my wife for some relaxation and eating out was truly special. We had some close friends offer to watch the kids for a couple days. It’s been over a year since we’ve gotten to completely unplug and relax like that for more than a couple hours. Our favorite things to do were eating out, and shopping for little decorations to go around the house.

Some articles I’ve been looking at this morning.


wikimedia threats?


Keybase… belongs to zoom?







Home Ventilation Project

10:44 AM

Time to write up some recommendations for authentication steps.

9:43 PM

I spent a little more time on the self-hosted budgeting app Firefly-iii. Setting it up was not quite as straight-forward as I had hoped. Basically the author is aggressively moving forward with minimum system requirements and forcing PHP 8 for the latest version, which isn’t available on my 8 year old NAS chip architecture. Had to figure out how to roll back, since PHP will still attempt to execute the new code but will fail on newer syntax. Also there are always little gotchas if you don’t keep each element of the application up to date, so since I was running a version of MariaDB that was old, it didn’t install correctly at one point. That troubleshooting process took a while, and then for some reason the CSV-Importer application that is a sort of side-car to the main application is erroring out without showing me the message, and that makes it very difficult to troubleshoot. Without CSV importing I’m not sure it’s worth setting up the budget app at all. I’m certainly not going to enter transactions manually. I’m not even certain I’m willing to import them on a monthly basis based on my past patterns with these types of finance apps.

ADHD Dev Journal: Middle of the Hackathon

The amazing thing about PHP and MySQL web apps is that I can troubleshoot and fix them even though I know so very little about PHP. It’s a really robust ecosystem. I don’t want to manage my own application servers for everything but the PHP applications are the simplest to manage. And searching stackoverflow returns just about everything you could imagine.

It’s good because I staked a part of my business on a self-hosted paid PHP application 5 years ago: Pancake and it’s still going strong and relatively easy for me to fix even when it’s running on an 8 year old Synology DiskStation.

This looks like an interesting budgeting app to try out. Firefly-iii

ADHD Dev Journal: Starting a Hackathon

I need to remember to get up and move and exercise sometime today when I’m starting to lose focus. I woke up late, stayed up late working last night, but it was fun. I’m looking forward to expaining what I did to some of my coworkers.

Kip peering around computer monitor

ADHD Dev Journal: Serverless Next.js

Doing a little catching up on the weekend, trying to get this demo site working for a hackathon. My preferred stack is nextjs + prisma. I’ve always deployed it on Vercel before, but at my current company we use AWS directly and extensively. I am finally trying out the serverless tool for deploying apps, and it has not been the easy straightforwrad experience I hoped for.

First, I needed to sort out the authentication thing, and of course a big corporate IT organization manages their AWS access in a very particular way, which was a little confounding to me coming from the startup - quick and dirty way of doing things.

Second was the fact that I was using a newer configuration thing called “serverless components“ and specifically the one for NextJS which is supposed to take all the config for a nextjs app and abstract it into a single line with good defaults.

Unfortunately I ended up running into an edge case because the client binaries for Prisma are not copied into the deployment package that is uploaded to AWS Lambda. There is an example workaround in this repo config which almost worked. But for some reason I had to copy the client files directly into the root of my deployment directory, otherwise Prisma couldnt find it and I would get errors int the logs like:

ERROR   PrismaClientInitializationError3 [PrismaClientInitializationError]: Query engine binary for current platform "rhel-openssl-1.0.x" could not be found.
This probably happens, because you built Prisma Client on a different platform.
(Prisma Client looked in "/var/task/chunks/query-engine-rhel-openssl-1.0.x")

Searched Locations:


You already added the platforms "darwin", "rhel-openssl-1.0.x" to the "generator" block
in the "schema.prisma" file as described in https://pris.ly/d/client-generator,
but something went wrong. That's suboptimal.

Please create an issue at https://github.com/prisma/prisma/issues/new
at cb (/var/task/chunks/930.js:36253:17)


Anyway, you see this is a big pain and it requires customizing the serverless config with custom shell scripts. And if there’s one thing I’ve learned it’s that writing shell scripts in .yml files is sign that things are going off the rails in a bad way.

Here’s my serverless config

component: "@sls-next/serverless-component@3.3.0"
- PDIR=node_modules/.prisma/client/;
if [ "$(ls -A $LDIR)" ]; then
cp "$PDIR"query-engine-rhel-* $LDIR;
cp "$PDIR"schema.prisma $LDIR/chunks/;
- PDIR=node_modules/.prisma/client/;
if [ "$(ls -A $LDIR)" ]; then
cp "$PDIR"query-engine-rhel-* $LDIR;
cp "$PDIR"schema.prisma $LDIR/chunks/;

This puts the files in the place that prisma is looking for them on the lambda.

Of course you still need to make sure your project can actually access your database and is in the same VPC with the lambdas. There is no end to the configuration power you have with AWS, but, I heartily recommend just using Vercel and some publicly accessible hosted Postgres Database.

Or maybe I should have just used a serverlss configuraiton that put a Create-React-App build into an S3 bucket and a seperate Express API on a lambda instead of trying to put them together into a single project. My current approach could be an example of too much magic again.

AWS security roles are such a pain to deal with. It’s after midnight now but I feel like I really accomplished something. A NextJS application deployed on lambdas and cloudfront, where the API handlers connect to a postgres database using Prisma DB client. Was that so much to ask for? Apparently it is. Tomorrow I’ll probably just scrap the whole thing and put it on a plain EC2 instance. But this CI deployment script should be super simple compared to what it would take to deploy a whole next app to a EC2 instance. npm ci && npx serverless

ADHD Dev Journal: API Keys

9:24 AM

  • Learned that for Rest endpoints, the Pancacke App API key is passed in through the HTTP Header X-API-KEY

10:43 AM

Absorbing more information about carbon and climate change.

Brighten the Clouds? - don’t forget that it reflects energy back onto the earth that would have been radiated out…

Sequestration of plant material may not actually work if you just bury it.

Olivine seems fine… but it’s impurities are kinda toxic I guess?

Parasols in spaaaaace!

Recyling… not our finest idea

What a mess. Global Analysis Paralysis has set in… and for good reason.

10:56 AM

Discussion of a hackathon project for next week. I’m good at starting new things from scratch.

2:29 PM

Been setting up a new application environment in AWS for the hackathon. Trying to make lots of decisions.

decisions whiteboard

4:32 PM

Always double-check the region in the AWS console. And RDS with Postgres and RDS Aurora with Postgres are two totally different things.

ADHD Dev Journal: Dentistification

Going to the dentist today to fill a cavity.

bear brushing teeth

Spent time trying to write a node CLI tool script to simulate web calls to my time tracking app, and failed to get authorization cookies to stick around. So annoying. I don’t want to build a whole fake authentication lifecycle, but that’s probably the best option since there’s no real API. Well, their API “documentation” doesn’t have any details on auth tokens.

I thought I could add a custom menubar app to my mac that allowed me to track my time and stay on focus better. It’s a classic way of spending time on a productivity tool instead of being productive. It’s amazing that after a few weeks of not doing much coding I have to go back to documentation for things that I’m sure I had memorized before.


Now I’m reading about magnetic-confinement for fusion. Fusion energy, man! Such an exciting mad-scientist type of thing to think about.

the sun

I want to lay out all the areas of work in my big project on the whiteboard and think about a cascade of issues that need to be solved. I enjoy zooming out on the problems more than writing code some days. If I do that for too long then I swing back and then just want to write code. It’s hard to do any one thing for too long.

Wow that was a really unfocused day. I had such a hard time getting anything useful done. We had a sick kid that messed up our sleep last night. Maybe that was the problem. It’s hard have days like this where my mind wandered so much. I need to find ways to apply my energy towards useful things.

ADHD Dev Journal: Off & On

Great 3-day weekend. Played with my kids, picnicked with neighbors. It’s amazing how much easier it is to enjoy the weekend with this new job compared to working for an early stage startup.

Lots to catch up on today. Feeling a little overwhelmed again.

Over the weekend I read some more about ADD and considered a few different things to try.

  1. Large daily doses of a multi-vitamin like EMP+

  2. A desk bike like the Flexispot, as reviewed on ars.

What about a standing desk? Hmm might need to do some business expenses at the end of the year. Wait… is my LG 5K actually VESA mount compatible? Is the built-in stand tall enough for standing desk configuration?

9:03 AM

I’m very interested in Watermelon DB. I actually tried using Nozbe (they own this github repo) as my task manager like 10 years ago. It was very powerful.

watermelon db logo

So it’s a database for making react-native apps fast that would be slowed down by loading and unloading large persisted caches into Redux stores. Multi-threading, native threads, indexing. What is it using for it’s DB on native? On the web it can use Loki.js.

Is the app I’m building really a offline-first app?

Watermelon does not really take care of syncing. Wait they have flow types? Not typescript? Wat?

So if we want to build the app with strong offline support we need to consider if it needs a full offline database? Doe the use-cases support that? Does data get created and updated on the mobile client that will then be synced to the back-end eventually? And I know we have sync endpoints for reading data but do we have endpoints for bulk updating data that was changed locally?

Checked into PouchDB years ago. I don’t think Couch DB on the server is a viable option for this app. It’s not a great, or feature-full production app database.

11:21 AM

Having trouble caring about work at the moment.

2:12 PM

Looking up information about OAuth and react-native.

2:52 PM

Thinking about digital nomad life in Costa Rica. Apparently cost of living isn’t actually that low any more. New digital nomad visa doesn’t really apply since I would be spending less than 6 months anyway.

3:12 PM


Microsoft Authentication Library (MSAL)

React Native MSAL

4:06 PM

SolidJS - I like that people are still perfecting the front-end functional reactive programming paradigm.

4:19 PM

Oh wow. “Moonfall”. This new Roland Emmerich film looks like exactly the kind of escapist nonsense I want to see.