Archive for May, 2022

What’s in a monorepo?

Tuesday, May 31st, 2022

I think there is more talk about the how of monorepos than the why or the what.

Once you know that you’re going to go (or convert to) the monorepo format, there are all sorts of interesting technical challenges like sharing packages (or not), shared config, and whatnot. But why do it at all? That it isn’t painfully obvious. Like, what even is a monorepo, and under what circumstances would I need one?

My first and only experience with monorepos is at CodePen where we’re now fully using a monorepo. It became most obvious to me in this situation:

- Next.js Site
— Ruby on Rails Site
— Shared Design System
— Shared Utilities

Those are the top-level folders of very important actively developed things. In other words, rather than each of them being a literal repo, we nested them all together in a single repo with a single parent, like:

— cp (Monorepo)
  — cpadmin (Next.js Site)
  — cprails (Ruby on Rails Site)
  — cplibrary (Bunch of React Components)
  — cputil (Bunch of JavaScript/JSON files)

So all these important things are essentially side-by-side. I don’t want to nest my Next.js site within my Ruby on Rails site. I maybe could, but it feels weird and is off-the-beaten-path for the involved frameworks. Even weirder to put a Ruby on Rails site underneath a Next.js root site. That type of file system nesting just feels unnatural and can cause actual problems like file watchers and build systems getting confused about what it’s seeing.

It’s even more clear when you look at things the “Sites” share. If you have a design system, it feels best to have it live at the same level as the multiple sites that are reaching for it. It would be extra weird (and likely present real challenges to things like deployment) for one site to reach up not only outside its own root, but then back down again into some other site to pluck out components.

In actuality, our own repo is more like this:

— cp (Monorepo)
  — cpadmin (Next.js Site)
  — cpxxx (More Future Next.js Sites)
  — cprails (Ruby on Rails Site)
  — cplibrary (Design System Components)
  — cputil (Bunch of JavaScript/JSON utility files)
  — cpclient (Shared Components/Hooks)
  — cpprocessors (Bunch of AWS Lambdas)
  — cpworkers (Bunch of Cloudflare Workers)
  — cpgo (API and other servers)
  — cpicons (Shared icons)
  — cpstyles (Shared CSS)
  — cpshots (Screenshot engine)
  — cpsearch (Search engine)

There is more. There is a lot of stuff that powers CodePen. Those integration tests gotta go somewhere to, ya know, test… the… integrations. It would be a pain in the ass if all this stuff was in separate repos. I would know, I was there. Now you pull, you got it all. It’s just easier.

What’s complicated is… a lot of stuff. Now for deployment, I can’t just “deploy everything in the repo”, which is a pretty common setup for tools like that. There needs to be code that detects when files in certain folders have changed and only deploy the changes in that folder in special particular ways. That’s non-trivial. Another complication is that not all site-building frameworks are designed to pluck files from outside their own root. I could go on and on, as the challenges of a monorepo are many.

But instead of getting more complex, let’s get less complex.

A monorepo could just be two things.

For example:

— Monorepo
  — Docs Site
  — Main Site

Two sites, but you just can’t be troubled to deal with them separately. Or it’s easier to have them both open and in sync all the time because you work on them together mostly.

Or maybe like:

— Monorepo
  — Main Site
  — Design System

Design systems are great, and it can make a lot of sense to keep them independent. Or even if the design system is baked into the main site, it still could be like:

— Monorepo
  — Main Site
  — Storybook

Your Storybook doesn’t need to be inside the main root because it doesn’t need to be deployed and changes to it probably shouldn’t trigger a deploy.

Or maybe it’s just one little thing that goes somewhere else like:

— Monorepo
  — WordPress Site
  — Cloudflare Worker

Those two things are going to be deployed very differently, and thus should probably be sibling folders rather than nested in one another.

Isn’t being fat just unhealthy?

Monday, May 30th, 2022

So goes the question in zeitgeist. A lot to unpack, as they say. I was thinking about this after staring at a slide Virgie Tovar posted to Instagram that reframes instead of directly answering:

View this post on Instagram

Here are a few from that slide.

Better questions:

Q: Why do we use BMI — a tool created in the 1800s by a European man whose work went on to become the basis of eugencics — as a measure of health?

Q: Why are thin people who smoke less stigmatized than higher weight people who don’t?

Q: Why do doctors prescribe weight-loss, a treatment with a 90-99% failure rate and that is correlated with anxiety, depression and an increased liklihood of developing an eating disorder?

That’s gut-wrenching stuff to me. It’s the kind of stuff they get into on Aubrey Gordon and Michael Hobbes’ Maintenance Phase podcast and that Roxane Gay masterfully dissects.

So the problem with the question is partially that “fat” and “unhealthy” aren’t particularly well defined, and that phrasing leans into a steaming pile of stigma that, ughkgh, really needs to get torn down despite near-zero progress on that by any metric.

As a fat, I’m mostly I’m annoyed at the world for all the fatphobia. Fat jokes, like gay jokes and trans jokes, tend to be incredibly lazy. Haha the cartoon fat kid likes cake! The cake-liking is the joke! Shopping for us fats is largely relegated to embarrassing experiences of digging to the very bottom of stacks of clothing praying for the off chance this stack has something that will fit, or even going to special sections or special stores, none of which concern themselves with actual style. Not to mention, ya know, all the bigger systemic problems that the smart people above talk about.

And yet. The question haunts me still. I’ve yo-yo’d a number of times in my life, occasionally flirting with being close to traditionally healthy and fit. During those times, I’m afraid I need to report: I felt healthier. I could do more, physically. I could run, at least a 5k. I felt like I could bike anywhere. I could ski. I was strong. I could fit into more stylish clothes and it helped my confidence. I felt sleepy when I put in a long hard day, not at noon on a Wednesday after sitting in a chair all morning. My blood pressure didn’t cause my dentist to worryingly suggest they might not even be able to clean my teeth if it doesn’t come down.

So even though I feel like the world has a lot of progress to make, I can’t help but think, for myself, that being fat is kinda unhealthy. And then that thought makes me feel like I’m feeding the stigma that I largely want to disagree with and it’s all a big mess in my head.

I think I’m thinking about all this more right now because my back has been killing me. I’ve been to the doctor and physical therapist over and over. I’m on meds. I’m doing exercises. But my brain goes: you know the real answer, it’s unfat yourself.

Anyway, Ruby and I just went hiking so it’s not like… all bad.


Friday, May 27th, 2022

The local community college had a STEM night the other night. A friend of mine who is a librarian there and a wonderful fiddler asked me and a few other local musicians if we’d play in front of the gardens for the kids passing through.

Someone snagged a tiny bit of one of the songs and sent it to us. Cuts out right before my ripping jug band banjo solo but oh well.

The Monkey & The Engineer. Kids love it.

Spending some time this morning writing my state reps

Friday, May 27th, 2022

Embarrassingly, aside from voting, I haven’t been particularly politically active since college. But since the literal president is like boy golly gee somebody should do something (😳), instead of doing even the bare minimum, I can at least make sure everyone else whose job it is to represent me knows exactly what I want to be represented.


I’ve never reached out to a senator before. But I looked up the job description and it says: “The job of a senator is to act on behalf of the American people in legislative sessions to ensure the voice of the common citizen is heard.”

That’s me: common citizen.

We aren’t quite halfway through the year and it looks like the math is showing 27 school shootings this year. TWENTY-SEVEN.

What I find interesting and frustrating is that the solution isn’t particularly theoretical. In every other nation where gun laws tighten restrictions on gun ownership and slow down the gun buying process, gun violence goes down. Which makes a lot of sense to me. So let’s do that. You work on the laws, be very public about it, and tell us what you’re doing, and if you do a good job of that I’ll vote for you should you come up for re-election and your fellow representatives that help keep us safe.

Thanks, on behalf of myself, my wife, and my half-year-old daughter who goes to preschool here in Bend, Oregon. Let’s do work to make sure that school isn’t 28.

Looks like this dude is trying (maybe), but he’s just one of our 3 senators so I’m off to message the others and our house reps.

Scripts, Programs, and Templates

Thursday, May 26th, 2022

I don’t think there is any computer science concept that distinguishes the terms scripts, templates, and programs in any real sense.

Go code is Go code. Something runs the code, it runs. Maybe it exits in 0.01 seconds, maybe it exists in 15 hours after calculating some astrophysics equation. PHP code is PHP code. Something runs it, it runs. Maybe it exits in 2 minutes, maybe it runs for 15 years until someone unplugs a server. Same story for any language. Heck, you could make the argument that HTML is the same way. It executes in a web browser and becomes an infinitely running program (e.g. listening for events) until the tab closes.

But my brain makes a distinction between these things. They feel different.

I find myself writing PHP once in a while, because I have production sites in WordPress, or I might use PHP just for an include statement once in a while. When I’m writing PHP, I’m probably writing it as a meta-language overtop HTML.

<h2><?php the_title(); ?></h2>
<?php include "parts/metadata.php"; ?>
<div class="excerpt">
  <?php the_excerpt(); ?>

I’m really just coding a template there. If I tried to execute that PHP file directly, it would fail, because those functions are defined elsewhere. By the time this particular PHP executes, I imagine hundreds if not thousands of other PHP files have already been executed. It doesn’t feel weird, it just feels… different than coding in other ways.

I could write PHP that I manually execute.

You have to tell PHP that it’s PHP lolz.

When I do that, it feels like I’m writing a script. I call it on demand, it runs, it exits. I almost never write PHP like this (In fact, I had to brew install php in order to even run that), but I could.

I was thinking of this distinction my brain makes lately while working with Go (I’m just a beginner). I’m doing some work fleshing out a fairly large GraphQL API that is powered by Go. Rather than outputting HTML it outputs JSON, but it seems feels like templating work. Files that are part of a much larger whole and that will not run independently.

I’m also doing other work in Go that is definitely in script territory. I write Go code, I run it at the command line, and it runs.

My scripts are slightly more complicated. What I’m doing is:

  1. Connect to a Postgres database
  2. Query for all records of a particular table
  3. Pull JSON data from one of the fields of each record
  4. Manipulate that JSON data
  5. Put it back

This is written in Go because we’re writing most everything else in Go, I might as well level up the expertise there. But even if we weren’t, Go is incredibly fast, so it can run this script several orders of magnitude faster than if it was written in, say, Ruby. This is a game-changer in large data work.

So this programming work feels distinctly different, and in the script category, because:

  1. The code is designed to be run once and then tossed
  2. It runs independently and for a short time period
  3. It runs only when it is called explicitly

I’m not saying it excuses sloppiness, but, uhmm, I guess I’m not not saying that either. Code that is temporary in nature feels like, as long as it absolutely does what it needs to do perfectly, doesn’t need the same approach as code that will live and be touched by others for untold years.

I put program as a third category of code. Perhaps a bad name, but I needed to call this personal distinction something. Remember in a template the code only executes in context of larger (and probably third-party) code. Templates are just little boats in a sea of code I’ll probably never even look at. Contrast that with a script, a largely totally independent bit of code where I’m intimately familiar with every line in a single file. I’d put a program in the middle. It’s software that is largely entirely written by you and your team. A whole code base. You turn it on, you turn it off. I’m thinking of something like a video game. You run the game, play it, then your dad tells you to turn it off and do your homework and you do, so the program stops running.

So I suppose it’s like:

I’m not sure this is terribly useful, it was just on my mind.

I already can think of code that falls in the gaps. Not long ago I had to write some PHP that was intended to be run once and on-demand (a script!), but the intention was to migrate some WordPress metadata, so used copious WordPress methods to do that work, but also build and output UI, so… template?

Unexpected Folk

Wednesday, May 25th, 2022

Some Irish lads bust out the instruments at the airport to lift spirits. Fun!

There is something special about traditional folk music. There is some real by-the-people-for-the-people energy to it that people respond to. They smile. They tap their feet. They like it, even (especially?) in unexpected situations. I feel like if Coldplay was there and they busted out an acoustic guitar people would be like 🙄. Heck all this kid did was bring a banjo to the high school talent show and play some three-finger Banjo 101 songs and the blurry video is worth 20m views.

That’s a lot of jobs

Wednesday, May 25th, 2022

Daniel Howell is (was?) a Youtuber who peaced out of YouTube a couple of years ago with a brief return coming out video only to peace out again. Now has posted an explanation video Why I Quit YouTube that is a pretty interesting watch. Here’s a bit I like that I think will resonate with entrepreneurs:

The word YouTuber is almost a synonym for amateur. Embarassing. Not a real job. Not real talent. Youtubers be like “Subscribe please. Titty clickbait drama crying.” God, YouTubers are so annoying with their self-promotion. “Oh, check out my new video.” Shut the fuck up. Check out this idiot that is proud of themselves. Have you checked the app you’re on? You’re just a YouTuber.

A pop star with a record label has a gigantic machine behind them that does all of the annoying shit. They have marketing departments to promote their material and advertising. They get to look relatabe in funny interviews. And usually, unless they also have songwriters and producers, just stick to what they are supposedly good at sit back looking cool and meticulously styled.

A YouTuber might be a singer/songwriter, but they have to write the music, set up the cameras, the lights, the audio, the recording, do the performance, edit it, design the assets, post it, and promote it. Then they are annoying for having to promote their own music.

You have so many jobs as a YouTuber! Producing decent-quality video and audio is no joke. That’s a dozen jobs you could make a career out of specializing in. Daniel puts a point on that:

You’re doing 12 different jobs. You’re a camera operator, lighting designer, sound engineer, video editor, graphic designer, writer, content manager, marketing agent, social media copy editor, brand ambassador, PR, and community rep. Oh yeah, and whatever the fuck your content is about.

Wanna get into tech and build a Software-as-a-Service app? You’re doing 12 different jobs. You’re a designer, front-end developer, back-end developer, UX specialist, industry analyst, accountant, manager, copywriter, social media strategist, customer support agent, marketer, oh, and you need an extremely good idea that you can do better than anyone else.

Not to mention it’s super risky.

iPhone Snaps from Weekend at Rental House in Seal Rock, OR

Monday, May 23rd, 2022

On the drive home, some cows on a plain:

Mouthblogging Brackets

Monday, May 23rd, 2022

It can be hard to summon the correct word for the characters below such that everyone understands which characters you mean when you are speaking.

{ }Curly Brackets
[ ]Square Brackets
( )Round Brackets
< >Angle Brackets
Consider this an homage to this wonderfully HTML4 page that hasn’t changed in 16 years.

Round brackets are the easy ones. I’ve only ever heard anyone call them parentheses or parens. No debate there that I know of, except perhaps that round brackets is more British English and I just don’t hear it as an American.

Angle brackets (< >) are also fairly locked in and called exactly that. But angle brackets does use the word bracket which may introduce a smidge of confusion in case someone thinks of a bracket as something else. And hey, right angles are angles too, so I could see someone understanding the word name angle bracket as a square bracket.

I think [ ] and { } are more confusing. If you literally say “curly braces” or “square brackets”, that’s pretty clear. But you can’t just say brackets because that encompasses all four of these. You could maybe get away with just saying braces because braces isn’t some parent term and if anything refers specifically to the curly variety.

I think these are the best bets for understandability, even if some of these are technically inaccurate:

{ }Curly Braces
Runners up: “Curvy Brackets”, “Twisty Parenthesis”, “Mustaches”
[ ]Square Brackets
Runners up: “Square Braces”
( )Parentheses
Runners up: “Round Brackets”, “Parens”
< >Angle Brackets
Runners up: “HTML brackets”, “Pointy Brackets”

Cannibal Sandwiches

Thursday, May 19th, 2022

Mary Kate McCoy for Wisconsin Public Radio:

It’s the holidays and to quiet your pre-dinner hunger, someone hands you a slice of rye bread topped with a thick spread of fresh raw beef, chopped onion and a sprinkle of salt and pepper.

Cannibal sandwiches are a longtime Milwaukee tradition. Come Christmastime, Bunzel’s goes through over 1,000 pounds of raw beef and about 250 pounds of raw onions, exclusively for cannibal sandwiches.

I’m from Wisconsin, lived most of my life there, and most recently even Milwaukee and somehow missed these delights. I first saw this linked up on Kottke and he’s also from Wisconsin and had not heard of them.

I figured I’d run it past my Extremely Wisconsin family though to see if they’d heard of them. Mom:

Yep. Most definitely. I never cared for them so therefore never served them. But they we’re common especially at holiday parties back in the day.

Step dad:

When I was a young man we would make those for cocktail party hors d’oeuvres. You gotta get a good cut high end beef. I would have them grind up chuck roast. You gotta keep it cold. You would chop onion and put it inside the hamburger and lay strips of onion on top. Ryebread or specialty bread would make it more classic. I never overindulged but I like to eat them. My dad would make them and then have sardines and stuff like that, which I didn’t care for.


(Written from the floor of a Walgreens where I’m sitting waiting for the pharmacy staff to come back so I can get some muscle relaxers for my pissed off back. Good thing I don’t have a boss that will yell at me for taking too long of a lunch break.)

Observations from a Few Weeks of Learning Go

Thursday, May 19th, 2022

The syntax is kinda fun to learn. There is satisfaction involved in learning how a different language does things and comparing it to the others you already know. It makes me wonder how much of programming is a strong understanding of the syntax and built-in methods and such. 25%? The bigger chunk is knowing how to approach a problem and forming a solution, regardless of what the specifics of the implementation are.

It’s wild how much error-checking there is. Any given .go file has some version of this in it many times:

if err != nil {
  return nil, err

This isn’t just some best practice, you have to do it otherwise the program won’t run. I don’t hate it. Gives the program some feeling of stability, even if the ritual of it is a bit much. Maybe better in some future Go?

I can return multiple values? Wild. Feels better than returning an object and then having to pluck the values out of the object like you have to do in JavaScript.

It’s so fast. I know that’s kind of the point, but wow. I’m working on this script to pull some data out of a Postgres DB, pull it apart, potentially run more queries based on what it finds, manipulate data, and put data back. I have a limited set of data for testing: 15,000 rows. It’s done in less than a second. That’s great. The complete data set it has to run on in my case is only around half a million rows, so it’ll only take a couple of seconds. I don’t even know which thing is the bottleneck, if there is one, Go or Postgres?

I’ve never really written any code in a typed language before, even TypeScript. It’s kinda nice. It’s satisfying to know exactly what kind of data is bopping around and absolutely forcing you to get it right before the program will even run at all.

The in-editor (VS Code) experience is tremendous… with the Go extension enabled. It formats your code on save (or is that Prettier?). It adds import stuff for you without having to type it at all (even removes unused imports). You can hover over just about anything for useful contextual info. It gives you red squiggles for anything that will bomb the program.

It makes me wonder: would I even like this language at all without the extreme in-editor conveniences? Am I being swayed by DX outside of the language itself?

I think I get the &pointer and *pointer stuff conceptually. Addresses that point to memory storage. Efficiencies to be had, etc. But in practice, it seems mostly used for “either this type or nil” which feels like an awkward misdirection to me somehow. In GraphQL the types either just have an ! or not which seems more to the point.

A good bit of my real-world learning practice is related to fleshing out a GraphQL API in Go, so sometimes it’s confusing which parts of this are Go-isms and which are GraphQL-isms. They both are strong on types and the syntax for both are still sometimes extremely foreign-feeling to me. I’m also doing this work in the context of CodePen which has many strong Go developers who have settled on ways of doing things, so I imagine some of this learning experience is learning specifically Go-at-CodePen conventions and techniques. For example, if I add a field to our GraphQL API, it touches quite a few files. Schemas, Resolvers, Types/Interfaces, Datastore, Mocks, etc. I think that’s good separation-of-concerns stuff, but I also think that’s how we’ve just chosen to do it. It’s my goal to understand the difference between requirements and best practices.

It seems so web-forward. There is built-in HTTP / Networking stuff. There is built-in JSON handling. There is built-in URL handling. Certainly, a language that knows it’s internet-bound. It works the other direction too, with hosting that specifically supports Go, like Lambdas. Kinda feels like… might as well write Lambdas in the fast language possible.

It’s helpful to actually do the typing. I tried to manually type my way through every example in Go By Example and do the exercises in A Tour of Go. I still haven’t finished. It’s a lot!

When you’re doing the typing in VS Code, if you’ve got GitHub Copilot on, it is seriously willing to do 90% of the typing for you. These exercises and examples must have been done so many times identically, Copilot often suggests prefilling the entire exercise. I tried not to take the suggestions too much (I should have turned it off), but it’s just so tempting usually.

I can feel the vampire of getting sucked into learning without doing. I can just sit there and stare at Go tutorials on YouTube. Junmin Lee makes some killer ones. But then I’m like… did I actually learn anything?

I’ve been trying to hit learning this like anything else I’m serious about learning:

  • Read stuff
  • Watch stuff
  • Get mentoring from whoever I can
  • Do pairing, trading off who is coding
  • Write as much code as possible (hopefully as “real world” as possible also)

Just hit it from every angle possible, because no one angle is going to do it.

✍️ ⛸ 👀

Thursday, May 19th, 2022

“The best writing is rewriting”

E.B. White

I suppose, E.B. White, unless nobody ever reads it.

So you gotta toss in a little:

“I skate where the puck is going to be”

Wayne Gretsky

And you get:

« Older Entries