Colin McDonnell @colinhacks
https://colinhacks.com
Founder of Bagel Health, creator of Zod, open-sourcer, poptimist, movie buff. Wanna go to Taco Bell?
フィード
Live types in a TypeScript monorepo
Colin McDonnell @colinhacks
EDIT: A previous version of this post recommended publishConfig, operating under the mistaken belief that it could be used to override "exports" during npm publish. As it turns out, npm only uses "publishConfig" to override certain .npmrc fields like registry and tag, whereas pnpm has expanded its use to override package metadata like "main", "types", and "exports". There are a number of reasons you may not wish to strongly couple your deployment logic to pnpm (detailed in the publishConfig section below). My updated recommendation is to use a custom export condition plus customConditions in tsconfig.json.Jump into the code: https://github.com/colinhacks/live-typescript-monorepoIn development, your TypeScript code should feel "alive". When you update your code in one file, the effects of that change should propagate to all files that import it instantaneously, with no build step. This is true even for monorepos, where you may not be importing things from a file, but from a local packag
7ヶ月前
An email regex for reasonable people
Colin McDonnell @colinhacks
I maintain Zod, which is a schema library. Zod let's people declare an email schema like this:import {z} from 'zod';z.string().email();A lot of people think every technically valid email address should pass validation by that schema. I used to think that too.Over the years I've merged several PRs to make the email regex more "technically correct". Most recently, I merged a PR that adds support for IPv6 addresses as the domain part of an email. They look like this and I hate them:jonny@[ipv6:7e95:0559:10f2:21e9:9dab:7309:c116:ca3b]Turns out that PR also broke plain old subdomains: [email protected]. That means Zod currently fails to parse my mom's current email address but Jonny up there can parse his freakish IPv6 email.This caused a spiritual crisis and made me re-evaluate my whole stance on what z.string().email() should do. Zod's users are mostly engineers who are building apps. When you're building an app, you want to make sure your users are providing normal-ass email addr
2年前
From README to documentation site in 10 minutes
Colin McDonnell @colinhacks
Spoiler alert: GitHub Pages and GitHub actions are not involved.I recently set out to build a proper documentation site for Zod with a short and eminently reasonable list of goals:The site should be generated from the README. Zod's README.md is the "source of truth".The site should automatically update whenever the master branch is updated.I didn't want to worry about building or maintaining a complex build workflow in GitHub Actions, if possible.Despite the eminent reasonability, I had a hard time finding a simple solution. After a lot of research and false starts, I've found what I think is the lowest-effort, highest-reward way to publish a documentation site for your GitHub-hosted project.Let's jump in.1. Add this index.html to your repoCreate a file called index.html in your project root and paste the following contents into it.Replace all occurrences of user/repo with your project's name. And maybe write up a slightly more detailed meta description :)<!DOCTYPE html><html lang="en"
3年前
Building an end-to-end typesafe API — without GraphQL
Colin McDonnell @colinhacks
In the mid-2010s, the pendulum of web development swung massively in the direction of increased type safety.First, we all switched back to relational DBs after recovering from an embarrassingly long collective delusion that NoSQL was cool. Then TypeScript started its meteoric rise after years of quiet development. Shortly thereafter GraphQL was announced and quickly became the de facto way to implement typesafe APIs.TLDR: I published a new library called tRPC that makes it easy to build end-to-end typesafe APIs without code generation, by leveraging the power of modern TypeScript. To jump straight to the tRPC walkthrough, click here.GraphQL's TypeScript problemGraphQL's biggest competitive advantage is that it's a spec, not a library. It's designed to be universal and language-agnostic. If you use different languages for your client and server, then by all means stick with GraphQL! It remains the best language-agnostic way to build typesafe data layers.But the vast majority of projects
4年前
Why Zod 2 isn't leaving beta
Colin McDonnell @colinhacks
Zod's v2 has been in beta since September 2020 (around 3 months as of this writing). The people are starting to talk.The backgroundThe reason Zod 2 has been in beta for so long (well, one of the reasons anyway!) is that I’ve been increasingly unsatisfied with Zod’s implementation of transformers. Transformers are a mechanism within Zod to convert data from one type to another. For the sake of rigor, I decided it was paramount for transformers to encapsulate both pre- and post-transform validation; to create one, you gave it an input schema A, and output schema B, and a transformation function (arg: A)=>B.Multiple issues have cropped up that have led me to re-evaluate the current approach. At best, transformers are a huge footgun and at worst they’re fundamentally flawed.ContextIn version 1, a Zod schema simply let you define a data type you'd like to validate. Under the hood, it magically inferred the static TypeScript type for your schema. More technically, there is a base class (ZodT
4年前
Next.js, nested routes, and the war on SPAs
Colin McDonnell @colinhacks
Edit: 2022 The issues described here have been largely solved by layouts in Next.js 13.I recently set out to implement a single-page application (SPA) on top of Next.js.To clarify, I'm using the term "SPA" in a very specific way. I'm referring to the "classical" SPA model: an application that handles all data fetching, rendering, and routing entirely client-side.Turns out, Next.js does not make this easy.To actually learn how to build a single-page application on top of Next.js, checkout my tutorial! Building a single-page application with Next.js.Why not use Next's routerNext's built-in router isn't as flexible as React Router! React Router lets you nest routers hierarchically in a flexible way. It's easy for any "parent" router to share data and provide an outer layout to its "child" routes. This is true for both top-level routes (e.g. /about and /team) and nested routes (e.g. /settings/team and /settings/user).This isn't possible with Next's built-in router! Instead, all shared stat
4年前
Building a single-page application with Next.js and React Router
Colin McDonnell @colinhacks
Update 2023 — Updated for Next.js 13, React Router 6, and React 18.Update 2022 — Next.js 13 now supports nested routes via the /app directory. However, it requires a server to render React Server Components, and thus doesn't qualify as a "single-page application" as defined in this post.I recently set out to implement a single-page application (SPA) on top of Next.js.To clarify, I'm using the term "SPA" in a very specific way. I'm referring to the "old school" SPA model: an application that handles all data fetching, rendering, and routing entirely client-side.Turns out, Next.js does not make this easy.Why not use Next.js routing?Next.js is not as flexible as React Router! React Router lets you nest routers hierarchically in a flexible way. It's easy for any "parent" router to share data with all of its "child" routes. This is true for both top-level routes (e.g. /about and /team) and nested routes (e.g. /settings/team and /settings/user).This isn't possible with Next's built-in router
4年前
Authenticated server-side rendering with Next.js and Firebase
Colin McDonnell @colinhacks
**Update: November 29, 2020**>> I have an idea for a SaaS product related to Next.js and authentication, and I'm looking for a co-founder! Ideally you'd be intimately familiar with Next.js, TypeScript, and SQL, and perhaps have some previous entrepreneurial experience. I'm an open-source maintainer and a previous YC founder, and I feel strongly about finding the right partner before starting a new endeavor. If you're interested shoot me an email at [email protected] with a bit about yourself! --> Feb 24, 2021: a previous version of this post contained a bug where a new cookie would be created each time you signed out and back in again. These (identical) cookies would stack up cause problems. If you're having issues, pass the { path: '/' } option to nookies.set call — details below.I had a hell of a time figuring out how to get Firebase Auth, Next.js, tokens, cookies, and getServerSideProps to play nice together. I'm hoping this breakdown will spare you the same suffering!To jump str
4年前
Sponsor pools: a new funding model for open source software
Colin McDonnell @colinhacks
Check out the HN discussion here.This article has been translated into Japanese and Russian.The existing open-source funding models don't work well for small projects.Big projects — operating systems, frameworks, CMSs, or fully self-hostable applications — are in a privileged position to extract more value from their users, especially corporate ones. Since entire APIs and products are built on top of them, they inspire enough appreciation (or, more likely, fear of obsolescence!) to net a sustainable income from one-off or monthly donations.¹But most OSS projects aren't big. The typical project on GitHub is better described as a utility — an apt term, given the infrastructural role these projects play in the world. It is a small tool that does one thing really well. Over the course of building a complex application, you may end up using dozens of these utilities — and they'll save you hundreds of hours of development time.Unfortunately, utilities like these rarely bring in any meaningfu
4年前
Why you shouldn't use @emotion/core
Colin McDonnell @colinhacks
A maintainer of Emotion published a very thoughtful response to a version of this post! I encourage you to check that out here. The essay below has modified to address some of his points.Emotion is my favorite CSS-in-JS library.It's easy to define style classes — both inline or in separate files. You can powerfully compose classes in powerful ways with the cx utility (the Emotion equivalent of Jed Watson's classnames). You sprinkle in your styles using the standard className attribute. There's no need to modify your markup/JSX — as it should be! You only need to install a single module (yarn add emotion). And there's no complicated Babel plugin or config file to set up.import { css, cs } from 'emotion';const redBorder = css({ border: '1px solid red' });const blueText = css({ color: 'blue' });const MyComp = () => { return <div className={cx(redBorder, blueText)}>hello</div>;};I'm currently building a Tailwind-style CSS-in-JS utility styling library with a maniacal focus on brevity and d
5年前
Choosing a tech stack for my personal dev blog in 2020
Colin McDonnell @colinhacks
Check out the HN roast discussion here! 🤗This article has been translated into Russian.I recently set out to build my personal website — the one you're reading now, as it happens!Surprisingly, it was harder than expected assemble a "tech stack" that met my criteria. My criteria are pretty straightforward; I would expect most React devs to have a similar list. Yet it was surprisingly hard to put all these pieces together.Given the lack of a decent out-of-the-box solution, I worry that many developers are settling for static-site generators that place limits on the interactivity and flexibility of your website. We can do better.tl;dr https://github.com/colinhacks/devii.Let's quickly run through my list of design goals:React (+ TypeScript)I want to build the site in React and TypeScript. I love them both wholeheartedly, I use them for my day job, and they're gonna be around for a long time. Plus writing untyped JS makes me feel dirty.I don't want limitations on what my personal website c...
5年前
Designing the perfect Typescript schema validation library
Colin McDonnell @colinhacks
Update 2023 — Many of the problems with other libraries have been solved since this post was originally published.There are a handful of wildly popular validation libraries in the Javascript ecosystem with thousands of stars on GitHub.When I started my quest to find the ideal schema declaration/validation library, I assumed the hardest part would be identifying the Most Great option from a sea of excellent ones.But as I dug deeper into the many beloved tools in the ecosystem, I was surprised that none of them could provide the features and developer experience I was looking for.tl;dr: I made a new Typescript validation library that has static type inference and the best DX this side of the Mississippi. To jump straight to README, head over to https://github.com/colinhacks/zodA pinch of contextI'm building an API for a healthcare application with Typescript. Naturally I want this mission-critical medical software to be rock-solid, so my goal is to build a fully end-to-end typesafe data
5年前