Launching Codo in early access

Codo launches as a Github marketplace app

I'm happy to announce Codo is now in early access at!

It's designed as a Github marketplace app and has a quick onboarding experience. The product builds on the open-source CLI tool, offering in particular better search features.

I've launched the product in early access and it's free to use right now. I have every intention of charging a reasonable price in the future to fund additional development in this space. Interestingly, the Github Marketplace requires me to offer the app for free for a period of time until the app has 100 installations. So I figured an early access plan will help kickstart adoption/awareness.

Check out the app, please shoot me feedback on it, and thanks in advance!

Now let's talk about some the engineering pieces of building this app.

Building a Github marketplace app

This is my first Github marketplace app. Of the projects I work on, Codo seemed like the perfect candidate for the marketplace because it pairs so well with Git.

While Codo is written in Rust, the app is written in Node.js/Typescript. The architecture is fairly simple. For example, lots of the normal application boilerplate surrounding user management I've leaned on Github for. Overall, it has been a pretty good experience integrating with Github.

Here's a friction log of sharp edges of working with Github:

  • Github published some bad SDK versions, I had to use older ones.
  • Initializing a Github client is weird. I need an app_id, app_private_key, app_webhook_secret, client_id, and client_secret plus auth tokens in various contexts. Toss in JWT and request verifying/signing bits and dang it's necessary Github ship SDKs to help with this. And the SDKs still don't make the experience great. Not to make a rant here, but Stripe processes +1 trillion dollars on behalf of huge and small companies and governments. Stripe's still rocking a single publishable_key, secret_key, and webhook_secret. I'm very wary of these sophisticated client auth schemes because very serious business is done with the simple schemes just fine.
  • Speaking of SDKs, I'm always disappointed by their complete disregard for modeling errors. I appreciate Rust/Go that force the SDK designers hand to give us as consumers something. But Github's JavaScript is try..catch city, learned the hard way from testing locally and in production over a fairly long period of time and I'm still not happy with spec-level robustness of my code.
  • Github's SDKs do shine in terms of TypeScript support. Webhook payloads and request/responses are well typed. They've embraced the features and limitations of TypeScript in how they design their JavaScript APIs. It's obvious Github does its JavaScript in TypeScript. This isn't to say the types are amazing. At the end of the day the SDK does resurface sharp edges, allowing nulls where there are never nulls, and a lack of calling context that one would encounter from the REST API spec. It's nonetheless a decent SDK.
  • Making a Github app and getting it listed in the marketplace takes two manual reviews. I was happy with the response time considering the human element they've deemed necessary. Both reviews were done in under two days and I was approved and on my way. What was frustrating was just how much of the admin interface was shielded off until I got approved. So the next steps were super unclear and it made it hard to do more work that would be coming down the line based on the docs.
  • There is noticeable slowness in the API. I'm pretty mindful of minimizing and deferring work in Codo so the experience is snappy for the most part but I'm seeing about 200ms per Github API request and those requests dominate the overall request time. I've lightly looked at optimizing with their GraphQL API without much improvement, and into my own server-side caching but now I'm trading off correctness and new complexity. I'd like a faster API.
  • Testing is an afterthought for Github apps. The testing advice is basically make the same app again. There's no help or assistance for copying over settings or anything. There's no code as infrastructure way to define these apps so it was a lot of poking, pasting, and comparing between the various versions of the app I working on.

Okay, that's everything I can think of for now. Which means overall, this API experience was pretty good!

Migrating to pure ESM

Unrelated to anything really, in the development of Codo I migrated my codebase to pure-ESM modules. This means my package.json has "type": "module" in it.

ESM has been around a long time but adoption is still not there. Over the migration hump, I'm happy with it and hope others get on the train.

It's hard to make the case for a move to ESM in a business context because, excluding subtle production facing bugs, the measurable impact of such a migration is small. I like ESM because, compared to CommonJS, it's less magic. It gets easier to do tree-shaking, there's less obscure AST walking, file path-ing is more clear. It's a bunch of small things that do and have slowed me down working in the weeds of keeping a JS build system afloat.

A large business can afford to have one unfortunate person or team watch all the transpilers and build tools and kick them along as they fall over in more and more ways. But it does seem, for the better, it does make economic sense to adopt ESM in mid-size and smaller projects.

Since 2015 when ESM was introduced, we've loved the syntax but have spent a massive effort trying to tech ourselves out of a migration. Nearing a decade since, I think we've tech'd long enough and it's time to truly embrace ESM as the much simpler future for JavaScript.

Thanks for reading!