type me = "davidblass"type reverse<s extends string> = s extends `${infer head}${infer tail}` ? `${reverse<tail>}${head}` : "" type me = reverse<"ssalbdivad">computed by the compiler at buildTS 6.0.3// TypeScript engineer · Boston, MA

David Blass

I write the TypeScript types other libraries depend on- and lately, the agents that write the rest.

author
ArkType (TypeScript's 1:1 validator) · ArkRegex · Attest
co-creator
Standard Schema · one interface for every TS validator
co-founder
Pullfrog · AI agents in GitHub Actions
consultant
TypeScript performance · 2023–25 · for tRPC, Prisma, Drizzle & more

const arktypeDownloads: 9_055_997npm downloads of arktype, Sep 13, 2026 – Oct 12, 20267.4× since May 2025: 1.07M downloads that month, 8.01M in Sep 2026.@see api.npmjs.org/downloads/point/2026-09-13:2026-10-12/arktypesnapshot · 2026-10-14 12:52 UTCnpm

ArkType downloads a month

npm · 30 days to Oct 12

const specDownloads: 551_490_697npm downloads of @standard-schema/spec, Sep 13, 2026 – Oct 12, 202671× since May 2025: 6.64M downloads that month, 472M in Sep 2026.Downloads of the spec package itself. Mostly transitive, as a runtime dependency of packages like Vercel's AI SDK (@ai-sdk/provider-utils) and Redux Toolkit.@see api.npmjs.org/downloads/point/2026-09-13:2026-10-12/@standard-schema/specsnapshot · 2026-10-14 12:52 UTCnpm

Standard Schema spec downloads a month

@standard-schema/spec · via AI SDK, Redux Toolkit

const answerOverflow: { before: "6.66s"; after: "3.29s"; runs: 5 }I found, minimized and benchmarked this slowdown and drove the fix; Mateusz Burzyński (@Andarist) wrote the compiler patch. AnswerOverflow's dashboard, type-checked on TS 5.8 vs. the #61505 build. Mean of 5 runs each; the ranges don't overlap.Jake Bailey (TS team) measured the same repo independently: 7.67s → 3.79s.@see microsoft/TypeScript#61535 (comment)@see typescript-go#1358 (Jake Bailey's run)public recordsourced

faster type-checks on real tRPC apps in TS 5.9

6.7s → 3.3s · 5 runs · found & drove it

const arkregexLaunch: { views: 733_569; likes: 3_119; reposts: 392 }The ArkRegex launch post on X, Oct 28, 2025.Read from the public fxtwitter mirror. The launch post alone; quotes and reposts not counted.@see x.com/arktypeio/status/1983210635266498649as of · 2026-10-13sourced

views on the ArkRegex launch post

@arktypeio on X · Oct 28, 2025

arkregex · regex with typeshover any nametap any name
import { 
type regex<pattern extends string = string, ctx extends RegexContext = RegexContext> = Regex<pattern, ctx>

const regex: RegexParser
regex
} from "arkregex"
const
const version: Regex<`${number}.${number}`, {
    captures: [`${number}`, `${number}`];
    names: {
        major: `${number}`;
        minor: `${number}`;
    };
}>
version
=
regex<"^(?<major>\\d+)\\.(?<minor>\\d+)$", "">(src: "^(?<major>\\d+)\\.(?<minor>\\d+)$", flags?: "" | undefined): Regex<`${number}.${number}`, {
    captures: [`${number}`, `${number}`];
    names: {
        major: `${number}`;
        minor: `${number}`;
    };
}>
regex
(
"^(?<major>\\d+)\\.(?<minor>\\d+)$" ) const {
const groups: {
    major: `${number}`;
    minor: `${number}`;
}
groups
} =
const version: Regex<`${number}.${number}`, {
    captures: [`${number}`, `${number}`];
    names: {
        major: `${number}`;
        minor: `${number}`;
    };
}>
version
.
Regex<`${number}.${number}`, { captures: [`${number}`, `${number}`]; names: { major: `${number}`; minor: `${number}`; }; }>.exec(s: string): RegexExecArray<[`${number}.${number}`, `${number}`, `${number}`], {
    major: `${number}`;
    minor: `${number}`;
}, ""> | null (+1 overload)
exec
("2.2")!

inferred from the pattern: real compiler outputTS 6.0.3 · arkregex 0.0.13

01 // work

Things people install

ArkType⛵

author · 2022–

TypeScript's 1:1 validator, optimized from editor to runtime. You write types as TypeScript syntax, in strings. A parser written in the type system reads them as you type; at runtime they compile to JIT-friendly validation code. Agents can learn it too: npx skills add arktypeio/arktype

const arktypeDownloads: 9_055_997npm downloads of arktype, Sep 13, 2026 – Oct 12, 20267.4× since May 2025: 1.07M downloads that month, 8.01M in Sep 2026.@see api.npmjs.org/downloads/point/2026-09-13:2026-10-12/arktypesnapshot · 2026-10-14 12:52 UTCnpmdownloads / mo

const arktypeStars: 7_874GitHub stars on arktypeio/arktype@see github.com/arktypeio/arktypesnapshot · 2026-10-14 12:52 UTCGitHubGitHub stars

arktype · the real parser, running livetype anything

✓ an email address

'david@arktype.io' extends string.email → true · union reduced

// "It's true- our static parser is the most flagrant abuse of the type system in a mainstream library." — @arktypeio

A drop-in replacement for new RegExp() with types. The first library to validate and infer regex from TypeScript's type system: capture groups come back typed, and a malformed pattern is a type error. (That's it up top.)

const arkregexLaunch: { views: 733_569; likes: 3_119; reposts: 392 }The ArkRegex launch post on X, Oct 28, 2025.Read from the public fxtwitter mirror. The launch post alone; quotes and reposts not counted.@see x.com/arktypeio/status/1983210635266498649as of · 2026-10-13sourcedlaunch-post views

3,119likes

Type-level benchmarks and assertions for TypeScript. Instantiation counts are deterministic: the same number on every machine, every run, so CI can fail the PR that makes your types 20% slower. It's the tool behind every case study below- and other people's: i18next used it to take one type const i18nextType: { before: 218_121; after: 278 }Instantiations for one i18next type, in a contributor's initial attest benchmark of the refactor that shipped as i18next's selector API.@see i18next/i18next#2317 (comment)@see i18next/i18next#2322public recordsourced.

const attestDownloads: 427_538npm downloads of @ark/attest, Sep 13, 2026 – Oct 12, 2026@see api.npmjs.org/downloads/point/2026-09-13:2026-10-12/@ark/attestsnapshot · 2026-10-14 12:52 UTCnpmdownloads / mo

ArkSchema

The set-theoretic type system underneath. Intersections, subtyping and union discrimination at runtime- it can compare arbitrary pairs of types for assignability. The 13-minute version is my Effect Days talk

Standard Schema

co-creator · 2024–

One interface, so any TypeScript validator plugs into any framework. Colin McDonnell (Zod) came up with the idea; Fabian Hiller (Valibot) and I designed it with him. Then we co-authored Standard JSON Schema, so any validator can define tool inputs for AI agents and MCP.

const specDownloads: 551_490_697npm downloads of @standard-schema/spec, Sep 13, 2026 – Oct 12, 202671× since May 2025: 6.64M downloads that month, 472M in Sep 2026.Downloads of the spec package itself. Mostly transitive, as a runtime dependency of packages like Vercel's AI SDK (@ai-sdk/provider-utils) and Redux Toolkit.@see api.npmjs.org/downloads/point/2026-09-13:2026-10-12/@standard-schema/specsnapshot · 2026-10-14 12:52 UTCnpmspec downloads / mo

const standardSchemaStars: 3_650GitHub stars on standard-schema/standard-schema@see github.com/standard-schema/standard-schemasnapshot · 2026-10-14 12:52 UTCGitHubGitHub stars

Diagram. Without a shared interface, 4 validators and 8 tools need 32 adapters, one per pair. With Standard Schema each implements or accepts one interface, so 12 integrations connect every validator to every tool.

validatorsframeworks & toolsZodValibotArkType⛵Effect SchematRPCTanStack FormTanStack RouterHonoReact Hook FormElysiaNuxt UIAI SDK+ more+ more

StandardSchemaV1 · one interface

const email = type("string.email")

email["~standard"].StandardSchemaV1<Input = unknown, Output = Input>.Props<string, string>.validate: (value: unknown, options?: StandardSchemaV1<Input = unknown, Output = Input>.Options | undefined) => StandardSchemaV1.Result<string> | Promise<StandardSchemaV1.Result<string>>validate(
	"david@arktype.io"
)
12 integrations instead of 32 adapters · const standardSchemaEcosystem: { validators: "30+"; tools: "60+" }Libraries listed on standardschema.dev as implementing or accepting the spec.Rounded down from a count of 33 and 64 on the live list.@see standardschema.dev/schemaas of · 2026-10-13sourced
the diagram as a table
Integrations with and without Standard Schema
without a standardwith Standard Schema
validatorsZod, Valibot, ArkType, Effect Schema
toolstRPC, TanStack Form, TanStack Router, Hono, React Hook Form, Elysia, Nuxt UI, AI SDK
integrations4 × 8 = 324 + 8 = 12
  1. rivalsonce you go type("string") you never go z.back()— @arktypeio
  2. co-authorswritten collaboratively by the creators of Zod (👋), Valibot, and ArkType— Colin, announcing Standard Schema 1.0
  3. co-founderssounds fake but I'm starting a company with my nemesis Colin P. Zod— me
  4. BETRAYAL— @arktype.io

Pullfrog🐸

co-founder · 2025–

AI coding agents that run in your GitHub Actions. Pullfrog wraps vanilla Claude Code, Codex and OpenCode to review PRs, triage issues, fix CI, resolve merge conflicts and test UIs in a headless browser. Your infrastructure, your keys, your costs. I co-founded it with Colin McDonnell (Zod) and built the model-agnostic agent runtime: BYOK, MCP tools, GitHub App/OIDC auth, sandboxed CI.Used by Sanity, Trigger.dev, Zed, Unkey, Remotion and Inkeep.

const pullfrogStars: 1_310GitHub stars on pullfrog/pullfrog@see github.com/pullfrog/pullfrogsnapshot · 2026-10-14 12:52 UTCGitHubGitHub stars

const pullfrogDownloads: 211_712npm downloads of pullfrog, Sep 13, 2026 – Oct 12, 2026@see api.npmjs.org/downloads/point/2026-09-13:2026-10-12/pullfrogsnapshot · 2026-10-14 12:52 UTCnpmnpm downloads / mo

02 // perf

Why your types are slow

"our two-step process for fast typescript types: 1️⃣ build a type‑level benchmarking library 2️⃣ spend the prime of your life on cache optimizations" @arktype.io

Clients have included tRPC, Drizzle, Prisma, Convex, AWS Amplify, Speakeasy, Stately, wevm, Vanta and Cloudinary. Most of that work is private; these three cases are public.

case 01TypeScript compiler2025

Two innocent-looking useMutation calls took about 2 seconds each to type-check.

Chained Zod- and tRPC-style types made the compiler redo every earlier link- O(3N) instantiations, ending in error TS2589: Type instantiation is excessively deep and possibly infinite.What TypeScript 5.8.2 says about 13 chained .merge() calls: the bench below, reproduced Oct 13, 2026. 5.9 checks the same chain without a word.tsc 5.8.2 · reproducedTS 5.9.3: 0 errors errors.

I traced it into TypeScript itself, minimized the repro, benchmarked it with Attest and argued it through review- including my reply to Anders Hejlsberg: "…if there are O(3^N) of them, they will eventually dominate the check time of the entire type." Mateusz Burzyński (@Andarist) wrote the compiler patch; it shipped in TypeScript 5.9 and was ported to the Go compiler.

"in case anyone was curious what O(3^N) looks like": type instantiations for chained .merge() calls, TypeScript 5.8.2 vs 5.9.3
show the bench
bench · chained11 calls
type merge<base, props> =
	Omit<base, keyof props & keyof base>
	& props

type Type<t> = {
	merge: <r>(r: r) => Type<merge<t, r>>
}

declare const 
const a: Type<{
    a: 1;
}>
a
: Type<{ a: 1a: 1 }>
const
const c1: Type<merge<{
    a: 1;
}, {
    b: number;
}>>
c1
=
const a: Type<{
    a: 1;
}>
a
.merge({ b: 2 })
const
const c2: Type<merge<merge<{
    a: 1;
}, {
    b: number;
}>, {
    c: number;
}>>
c2
=
const c1: Type<merge<{
    a: 1;
}, {
    b: number;
}>>
c1
.merge({ c: 3 })
const
const c3: Type<merge<merge<merge<{
    a: 1;
}, {
    b: number;
}>, {
    c: number;
}>, {
    d: number;
}>>
c3
=
const c2: Type<merge<merge<{
    a: 1;
}, {
    b: number;
}>, {
    c: number;
}>>
c2
.merge({ d: 4 })
const
const c4: Type<merge<merge<merge<merge<{
    a: 1;
}, {
    b: number;
}>, {
    c: number;
}>, {
    d: number;
}>, {
    e: number;
}>>
c4
=
const c3: Type<merge<merge<merge<{
    a: 1;
}, {
    b: number;
}>, {
    c: number;
}>, {
    d: number;
}>>
c3
.merge({ e: 5 })
const c5 =
const c4: Type<merge<merge<merge<merge<{
    a: 1;
}, {
    b: number;
}>, {
    c: number;
}>, {
    d: number;
}>, {
    e: number;
}>>
c4
.merge({ f: 6 })
const c6 = c5.merge({ g: 7 }) const c7 = c6.merge({ h: 8 }) const c8 = c7.merge({ i: 9 }) const c9 = c8.merge({ j: 10 }) const c10 = c9.merge({ k: 11 }) const c11 = c10.merge({ l: 12 }) const c12 = c11.merge({ m: 13 }) const c13 = c12.merge({ n: 14 }) const c14 = c13.merge({ o: 15 }) const c15 = c14.merge({ p: 16 })
TS 5.8.2⛳ Result: 1,596,004 instantiations
TS 5.9.3⛳ Result:       976 instantiations
type instantiations

Line chart. As chained .merge() calls increase from 1 to 15, TypeScript 5.8.2's type instantiations roughly triple with each call, from 98 to 4,784,888 at 12 calls, then fail with error TS2589 from 13 calls on. TypeScript 5.9.3 stays under 1,700 throughout: 976 at 11 calls and 1,632 at 15.

Instantiation counts from @ark/attest 0.57.0: deterministic, the same on every machine. Bench from microsoft/TypeScript#61505; re-run on 5.8.2 and 5.9.3, Oct 13, 2026.

Data
Type instantiations by number of .merge() calls (attest 0.57.0). "TS2589" means the checker bailed; the count it reported is in parentheses and isn't real work.
callschained 5.8.2chained 5.9.3functional 5.8.2functional 5.9.3
198363014
2250857733
352414416355
41,13621336080
52,734292884108
67,2623812,383139
720,5524806,801173
860,10058919,970210
9178,39470859,386250
10532,898837177,537293
111,596,004976531,887339
124,784,8881,1251,594,828388
13TS2589
(9,785,026)
1,2844,783,536440
14TS2589
(14,785,170)
1,45314,349,539495
15TS2589
(14,785,298)
1,632TS2589
(24,349,567)
553
What it did to real appscheck time on TS 5.9, as a share of TS 5.8 · shorter is faster

TypeScript check time after the 5.9 fix, as a share of 5.8: a tRPC monorepo, 13.04 to 6.00 seconds in one run; AnswerOverflow, 6.66 to 3.29 seconds, mean of 5 runs each; Klarna, 395.48 to 132.09 seconds, self-reported.

A tRPC monorepo I testedconst trpcMonorepo: { before: "13.04s"; after: "6.00s"; runs: 1 }A tRPC monorepo I tested, TS 5.8 vs. the #61505 build.A single run.@see microsoft/TypeScript#61505 (comment)public recordsourced2.1×single run
AnswerOverflow dashboard (public repo)const answerOverflow: { before: "6.66s"; after: "3.29s"; runs: 5 }I found, minimized and benchmarked this slowdown and drove the fix; Mateusz Burzyński (@Andarist) wrote the compiler patch. AnswerOverflow's dashboard, type-checked on TS 5.8 vs. the #61505 build. Mean of 5 runs each; the ranges don't overlap.Jake Bailey (TS team) measured the same repo independently: 7.67s → 3.79s.@see microsoft/TypeScript#61535 (comment)@see typescript-go#1358 (Jake Bailey's run)public recordsourced2.0×5 runs each, no overlap
Klarna appconst klarna: { before: "395.48s"; after: "132.09s" }Klarna's app, reported by one of their engineers: "This was a game-changer PR for us."Third-party and self-reported, in one comment.@see microsoft/TypeScript#61505 (comment)@see microsoft/TypeScript#61505 (Klarna, follow-up)public recordsourced2.9×self-reported, in one comment
Data
appTS 5.8TS 5.9shareruns
A tRPC monorepo I tested13.04s6.00s46.0%single run
AnswerOverflow dashboard (public repo)6.44s / 6.58s / 6.99s / 6.33s / 7.00s3.25s / 3.34s / 3.21s / 3.24s / 3.43s49.4%5 runs each, no overlap
Klarna app395.48s132.09s33.4%self-reported, in one comment

Compiler patch by Mateusz Burzyński (@Andarist) · microsoft/TypeScript#61505 · TS 5.9 notes · typescript-go#1358

The ~2× is 5 runs per side with no overlap. My 13.04s → 6.00s is one run. Klarna's ~3× is self-reported, in one comment.

"Please contact @ssalbdivad. He is probably the best TypeScript performance consultant in the world…"
a stranger in Prisma's issue tracker · prisma/orm#29011
case 02viem + MUD2024

One type. Nine type parameters.
const getVariancesWorker: { ms: 1_866; typeParams: 9 }Time TypeScript spent computing the variance of viem's SimulateContractReturnType, in a trace of MUD's build: 1.86s, truncated.@see latticexyz/mud#2956@see wevm/viem#2557public recordsourced

In MUD's build, TypeScript spent 1.86s just computing the variance of one viem type, and instantiation counts never showed it. Only a trace did. With variance annotated by hand, the entire file checked in 1.28s. Explicit in/out annotations now ship in viem itself, so every consumer skips that work.

"avoiding the variance checks reduced the check time for a simple repo by over a second locally."
— me, in wevm/viem#2557
Trace of MUD's build: one viem type's variance computation before, the whole file after.

Trace comparison. Before: one type's variance computation, getVariancesWorker, took 1,866 milliseconds. After adding variance annotations, the whole file setupNetwork.ts checked in 1,288 milliseconds.

Data
tracksliceduration
beforecheckSourceFile · setupNetwork.tsnot published
beforegetVariancesWorker · SimulateContractReturnType (9 type parameters)1,866 ms
aftercheckSourceFile · setupNetwork.ts (annotated)1,288 ms

Slices aligned at 0; offsets within the original Perfetto trace omitted. Source: latticexyz/mud#2956.

case 03Prisma ORM + Mongoose2025

Prisma: 45% less check time on the generated file we restructured.

const commonInputTypes: { checkSourceFile: "4064µs → 2218µs"; lines: "339 → 82" }One file of Prisma's generated client, before and after the restructuring.One file, not the whole client.@see prisma.io/blog (type-check performance)@see prisma/orm#27046@see Prisma 6.16.0 release notespublic recordsourced

"We've worked with TypeScript expert David Blass to find ways for improving the type checking performance in Prisma ORM…"
— Prisma 6.16.0 release notes
Prisma · commonInputTypes, % of before

The 45% is one file (commonInputTypes), not the whole client. Measured in prisma/orm#27046; Prisma reports the same result on its blog.

Data
µs or lines
beforeafter
checkSourceFile4,064 µs2,218 µs
createSourceFile796 µs246 µs
bindSourceFile607 µs164 µs
lines of code339 LOC82 LOC
Also shipped: Mongoose 8.19, InferRawDocType, const inferRawDocType: { simple: "501 → 320"; mixed: "1626 → 535"; nested: "4214 → 2097" }Instantiations on Mongoose's attest benches for InferRawDocType.The maintainer's whole-repo count was flat (+0.9%).@see Automattic/mongoose#15588public recordsourced.

On its benchmarks. The maintainer's whole-repo count was flat (+0.9%). Automattic/mongoose#15588.

Data
instantiations
beforeafter
simple schema501320
mixed schema1,626535
nested schema4,2142,097
03 // agents

How I work with agents

I build Pullfrog by running many coding agents in parallel, every day, through Ntwine- a local tool I maintain that puts every agent thread on one board and queues the ones that need me. It continues Colin McDonnell's Frizz; the queue, the board and the principles behind them are his design. These are the rules I've added on top, for the agents and for me.

  1. 01Size work by scope, never in days.

    Agents do the building, so hours are the wrong unit. Scope is the code paths a change touches, its risk, and what needs a human decision.

  2. 02Report honest effect sizes.

    Say how strong a claim is right next to it, and treat pushback as a bug report on the measurement before defending the result. (The case studies above say which numbers are single runs.)

  3. 03Lead with what changed.

    An agent's report leads with what changed or what is true. The why goes in the commit message and code comments, where the next reader will find it- not in the chat.

  4. 04Preserve evidence.

    Never delete or rewrite a stored measurement. Experiments are temporary: record the conclusion and its numbers, then delete the harness.

This page was built that way.

  • research 6
  • design 5
  • build 36
  • review 50
  • tool call
22:0023:0000:0001:0002:0003:0004:0005:0006:0007:0008:00perf-case-studies → research-perf.md · 11m · 77 tool callstalks-media → research-media.md · 11m · 79 tool callsvoice-buzz → research-voice.md · 20m · 85 tool callsbrand-local → research-brand.md · 10m · 71 tool callsstats-apis → research-stats.md · 4m 54s · 33 tool callstech-stack → research-stack.md · 14m · 75 tool callsstory → design-story.md · 7m 50s · 16 tool callsdelight → design-delight.md · 9m 46s · 28 tool callsvisual → design-visual.md · 16m · 71 tool callsdataviz → design-dataviz.md · 14m · 31 tool callssynthesis → concept.md · 10m · 22 tool callswork → Work.tsx · 37m · 137 tool callsperf → Perf.tsx · 28m · 104 tool callsagents-talks → Agents.tsx · 27m · 122 tool callseggs → Eggs.tsx · 24m · 129 tool callsdesign review · 40m · 219 tool callsrecruiter review · 18m · 95 tool callshonesty review · 18m · 97 tool callsa11y review · 35m · 180 tool callsinteractions review · 52m · 133 tool calls · stopped without a resultperfcode review · 53m · 72 tool calls · stopped without a resultverifier · 20m · 75 tool callsverifier · 12m · 78 tool callsverifier · 17m · 74 tool calls · stopped without a resultverifier · 12m · 69 tool calls · stopped without a resultinteractions review · 1h 13m · 138 tool callsverifier · 29m · 134 tool callsperfcode review · 45m · 136 tool callsverifier · 11m · 80 tool callsverifier · 16m · 84 tool callsverifier · 18m · 99 tool callswork · fixes → Work.tsx · 4m 19s · 21 tool callsperf · fixes → Perf.tsx · 6m 24s · 43 tool callsagents-talks · fixes → Agents.tsx · 8m 16s · 47 tool callseggs · fixes → Eggs.tsx · 1m 57s · 16 tool callsshell · fixes → styles.css · 33m · 127 tool callseggs · fixes → Eggs.tsx · 6m 01s · 33 tool callsverifier · 20m · 72 tool callswork · fixes → Work.tsx · 24m · 52 tool callsperf · fixes → Perf.tsx · 42m · 166 tool callsagents-talks · fixes → Agents.tsx · 6m 31s · 12 tool callseggs · fixes → Eggs.tsx · 0m 32s · 6 tool callsshell · fixes → styles.css · 24m · 73 tool callsverifier · 15m · 78 tool callseggs · fixes → Eggs.tsx · 1m 02s · 7 tool callsdesign review · round 2 · 1h 00m · 270 tool callsrecruiter review · round 2 · 24m · 108 tool callshonesty review · round 2 · 18m · 105 tool callsa11y review · round 2 · 49m · 172 tool callsinteractions review · round 2 · 1h 42m · 137 tool callsperfcode review · round 2 · 48m · 143 tool callsverifier · round 2 · 8m 26s · 47 tool callsverifier · round 2 · 12m · 45 tool callsverifier · round 2 · 19m · 56 tool callsverifier · round 2 · 28m · 91 tool callsverifier · round 2 · 21m · 91 tool callsagents-talks · fixes → Agents.tsx · 1m 36s · 8 tool callseggs · fixes → Eggs.tsx · 1m 49s · 9 tool callsshell · fixes → styles.css · 13m · 29 tool callsverifier · round 2 · 16m · 56 tool callsshell · fixes → styles.css · 36m · 139 tool callsperf · fixes → Perf.tsx · 17m · 69 tool callswork · fixes → Work.tsx · 18m · 56 tool callsagents-talks · fixes → Agents.tsx · 7m 13s · 27 tool callseggs · fixes → Eggs.tsx · 5m 40s · 23 tool callsdesign review · round 3 · 33m · 208 tool callsrecruiter review · round 3 · 25m · 129 tool callshonesty review · round 3 · 18m · 126 tool callsa11y review · round 3 · 1h 14m · 222 tool callsinteractions review · round 3 · 1h 34m · 150 tool callsperfcode review · round 3 · 1h 09m · 164 tool callsverifier · round 3 · 6m 32s · 48 tool callsverifier · round 3 · 8m 05s · 43 tool callsagents-talks · fixes → Agents.tsx · 25m · 81 tool callseggs · fixes → Eggs.tsx · 6m 20s · 31 tool callsverifier · round 3 · 12m · 79 tool callsshell · fixes → styles.css · 7m 53s · 28 tool callsperf · fixes → Perf.tsx · 2m 13s · 15 tool callsverifier · round 3 · 18m · 53 tool callsverifier · round 3 · 16m · 86 tool callsshell · fixes → styles.css · 8m 08s · 33 tool callsperf · fixes → Perf.tsx · 9m 42s · 15 tool callswork · fixes → Work.tsx · 3m 56s · 18 tool callsagents-talks · fixes → Agents.tsx · 1m 44s · 11 tool callsverifier · round 3 · 18m · 69 tool callsshell · fixes → styles.css · 6m 57s · 27 tool callswork · fixes → Work.tsx · 7m 25s · 21 tool callsperf · fixes → Perf.tsx · 2m 30s · 12 tool callscontent check · 17m · 71 tool callsvisual check · 17m · 94 tool callsinteract check · 53m · 110 tool callssweep check · 34m · 116 tool callsverifier · 6m 04s · 24 tool callsverifier · 2m 15s · 23 tool callsverifier · 8m 11s · 40 tool callsverifier · 22m · 31 tool callsagents-talks · fixes → Agents.tsx · 2m 20s · 7 tool calls27m idle≈27m idleresearch · 6design · 5build · 4review · 10fixes · 5Eggs.tsxfixes · 6review · 8Agents.tsxEggs.tsxstyles.cssreview · 12fixes · 5fixes · 4fixes · 4review · 12styles.cssWork.tsxPerf.tsxreview · 8Agents.tsx@personal-page22:0023:0000:0001:0002:0003:0004:0005:0006:0007:0008:00perf-case-studies → research-perf.md · 11m · 77 tool callstalks-media → research-media.md · 11m · 79 tool callsvoice-buzz → research-voice.md · 20m · 85 tool callsbrand-local → research-brand.md · 10m · 71 tool callsstats-apis → research-stats.md · 4m 54s · 33 tool callstech-stack → research-stack.md · 14m · 75 tool callsstory → design-story.md · 7m 50s · 16 tool callsdelight → design-delight.md · 9m 46s · 28 tool callsvisual → design-visual.md · 16m · 71 tool callsdataviz → design-dataviz.md · 14m · 31 tool callssynthesis → concept.md · 10m · 22 tool callswork → Work.tsx · 37m · 137 tool callsperf → Perf.tsx · 28m · 104 tool callsagents-talks → Agents.tsx · 27m · 122 tool callseggs → Eggs.tsx · 24m · 129 tool callsdesign review · 40m · 219 tool callsrecruiter review · 18m · 95 tool callshonesty review · 18m · 97 tool callsa11y review · 35m · 180 tool callsinteractions review · 52m · 133 tool calls · stopped without a resultperfcode review · 53m · 72 tool calls · stopped without a resultverifier · 20m · 75 tool callsverifier · 12m · 78 tool callsverifier · 17m · 74 tool calls · stopped without a resultverifier · 12m · 69 tool calls · stopped without a resultinteractions review · 1h 13m · 138 tool callsverifier · 29m · 134 tool callsperfcode review · 45m · 136 tool callsverifier · 11m · 80 tool callsverifier · 16m · 84 tool callsverifier · 18m · 99 tool callswork · fixes → Work.tsx · 4m 19s · 21 tool callsperf · fixes → Perf.tsx · 6m 24s · 43 tool callsagents-talks · fixes → Agents.tsx · 8m 16s · 47 tool callseggs · fixes → Eggs.tsx · 1m 57s · 16 tool callsshell · fixes → styles.css · 33m · 127 tool callseggs · fixes → Eggs.tsx · 6m 01s · 33 tool callsverifier · 20m · 72 tool callswork · fixes → Work.tsx · 24m · 52 tool callsperf · fixes → Perf.tsx · 42m · 166 tool callsagents-talks · fixes → Agents.tsx · 6m 31s · 12 tool callseggs · fixes → Eggs.tsx · 0m 32s · 6 tool callsshell · fixes → styles.css · 24m · 73 tool callsverifier · 15m · 78 tool callseggs · fixes → Eggs.tsx · 1m 02s · 7 tool callsdesign review · round 2 · 1h 00m · 270 tool callsrecruiter review · round 2 · 24m · 108 tool callshonesty review · round 2 · 18m · 105 tool callsa11y review · round 2 · 49m · 172 tool callsinteractions review · round 2 · 1h 42m · 137 tool callsperfcode review · round 2 · 48m · 143 tool callsverifier · round 2 · 8m 26s · 47 tool callsverifier · round 2 · 12m · 45 tool callsverifier · round 2 · 19m · 56 tool callsverifier · round 2 · 28m · 91 tool callsverifier · round 2 · 21m · 91 tool callsagents-talks · fixes → Agents.tsx · 1m 36s · 8 tool callseggs · fixes → Eggs.tsx · 1m 49s · 9 tool callsshell · fixes → styles.css · 13m · 29 tool callsverifier · round 2 · 16m · 56 tool callsshell · fixes → styles.css · 36m · 139 tool callsperf · fixes → Perf.tsx · 17m · 69 tool callswork · fixes → Work.tsx · 18m · 56 tool callsagents-talks · fixes → Agents.tsx · 7m 13s · 27 tool callseggs · fixes → Eggs.tsx · 5m 40s · 23 tool callsdesign review · round 3 · 33m · 208 tool callsrecruiter review · round 3 · 25m · 129 tool callshonesty review · round 3 · 18m · 126 tool callsa11y review · round 3 · 1h 14m · 222 tool callsinteractions review · round 3 · 1h 34m · 150 tool callsperfcode review · round 3 · 1h 09m · 164 tool callsverifier · round 3 · 6m 32s · 48 tool callsverifier · round 3 · 8m 05s · 43 tool callsagents-talks · fixes → Agents.tsx · 25m · 81 tool callseggs · fixes → Eggs.tsx · 6m 20s · 31 tool callsverifier · round 3 · 12m · 79 tool callsshell · fixes → styles.css · 7m 53s · 28 tool callsperf · fixes → Perf.tsx · 2m 13s · 15 tool callsverifier · round 3 · 18m · 53 tool callsverifier · round 3 · 16m · 86 tool callsshell · fixes → styles.css · 8m 08s · 33 tool callsperf · fixes → Perf.tsx · 9m 42s · 15 tool callswork · fixes → Work.tsx · 3m 56s · 18 tool callsagents-talks · fixes → Agents.tsx · 1m 44s · 11 tool callsverifier · round 3 · 18m · 69 tool callsshell · fixes → styles.css · 6m 57s · 27 tool callswork · fixes → Work.tsx · 7m 25s · 21 tool callsperf · fixes → Perf.tsx · 2m 30s · 12 tool callscontent check · 17m · 71 tool callsvisual check · 17m · 94 tool callsinteract check · 53m · 110 tool callssweep check · 34m · 116 tool callsverifier · 6m 04s · 24 tool callsverifier · 2m 15s · 23 tool callsverifier · 8m 11s · 40 tool callsverifier · 22m · 31 tool callsagents-talks · fixes → Agents.tsx · 2m 20s · 7 tool calls27m idle≈27m idleresearch · 6design · 5build · 4review · 10fixes · 5fixes · 1fixes · 6review · 8fixes · 3review · 12fixes · 5fixes · 4fixes · 4review · 12fixes · 3review · 8fixes · 1@personal-page

A braid of the session that built this page. One root thread, @personal-page, fans out to 97 sub-agents across research, design, build, review; each strand's length is its real duration and each tick is one tool call. The table below lists every strand.

08:49:46verifier → findings · 31 tool calls97 sub-agents · 7,900 tool calls · 11h 00m wall clock
UTC · Oct 13–14, 2026
Replay of the agent session that built this page

Researched, designed, built and reviewed by one agent thread that fanned out to 97 sub-agents: 7,900 tool calls, 34h 05m of agent time in 11h 00m of wall clock. I set the bar in one brief and a follow-up; they did the legwork. Every strand, tick and timestamp above is from the session.

// scripts/replay.ts reads the session's transcript metadata (labels, timestamps, tool-call counts) into a snapshot taken 2026-10-14 08:49 UTC. It reads message text only to tell mine from automated check-ins, and stores none of it.

Every strand, as a table
strandphaseUTClengthtool callshanded back
@personal-pageroot21:49:19–08:49:4611h 00m438this page
perf-case-studiesresearch21:52:06–22:03:0311m77research-perf.md
talks-mediaresearch21:52:06–22:02:4811m79research-media.md
voice-buzzresearch21:52:06–22:11:3720m85research-voice.md
brand-localresearch21:52:06–22:02:0910m71research-brand.md
stats-apisresearch21:52:06–21:57:004m 54s33research-stats.md
tech-stackresearch21:52:06–22:06:0314m75research-stack.md
storydesign22:14:37–22:22:277m 50s16design-story.md
delightdesign22:14:37–22:24:239m 46s28design-delight.md
visualdesign22:14:37–22:30:3416m71design-visual.md
datavizdesign22:14:37–22:28:5514m31design-dataviz.md
synthesisdesign22:30:35–22:40:5610m22concept.md
workbuild22:54:50–23:32:0437m137Work.tsx
perfbuild22:55:08–23:22:4728m104Perf.tsx
agents-talksbuild22:55:26–23:22:0227m122Agents.tsx
eggsbuild22:55:47–23:19:2624m129Eggs.tsx
design reviewreview23:38:14–00:18:3440m219findings
recruiter reviewreview23:38:15–23:56:1618m95findings
honesty reviewreview23:38:15–23:56:3118m97findings
a11y reviewreview23:38:15–00:13:4335m180findings
interactions reviewreview23:38:15–00:30:2952m133stopped, no result
perfcode reviewreview23:38:15–00:30:5353m72stopped, no result
verifierreview23:56:16–00:16:4120m75findings
verifierreview23:56:31–00:08:0212m78findings
verifierreview00:13:44–00:30:2117m74stopped, no result
verifierreview00:18:34–00:30:1812m69stopped, no result
interactions reviewreview00:57:28–02:10:461h 13m138findings
verifierreview00:57:28–01:26:0629m134findings
perfcode reviewreview00:57:29–01:42:1145m136findings
verifierreview00:57:29–01:08:2811m80findings
verifierreview00:57:29–01:13:5116m84findings
verifierreview00:57:29–01:15:0018m99findings
work · fixesbuild00:59:21–01:03:394m 19s21Work.tsx
perf · fixesbuild00:59:25–01:05:496m 24s43Perf.tsx
agents-talks · fixesbuild00:59:30–01:07:468m 16s47Agents.tsx
eggs · fixesbuild00:59:35–01:01:311m 57s16Eggs.tsx
shell · fixesbuild01:00:01–01:32:5933m127styles.css
eggs · fixesbuild01:38:16–01:44:176m 01s33Eggs.tsx
verifierreview01:42:11–02:02:0420m72findings
work · fixesbuild02:09:40–02:33:4524m52Work.tsx
perf · fixesbuild02:09:45–02:51:3342m166Perf.tsx
agents-talks · fixesbuild02:09:48–02:16:196m 31s12Agents.tsx
eggs · fixesbuild02:09:51–02:10:230m 32s6Eggs.tsx
shell · fixesbuild02:09:56–02:33:3224m73styles.css
verifierreview02:10:46–02:25:4115m78findings
eggs · fixesbuild02:26:15–02:27:181m 02s7Eggs.tsx
design review · round 2review02:53:28–03:53:061h 00m270findings
recruiter review · round 2review02:53:29–03:17:0824m108findings
honesty review · round 2review02:53:29–03:11:5218m105findings
a11y review · round 2review02:53:29–03:42:4149m172findings
interactions review · round 2review02:53:29–04:35:191h 42m137findings
perfcode review · round 2review02:53:29–03:41:5748m143findings
verifier · round 2review03:11:52–03:20:188m 26s47findings
verifier · round 2review03:17:08–03:28:5112m45findings
verifier · round 2review03:41:57–04:01:0719m56findings
verifier · round 2review03:42:41–04:10:1328m91findings
verifier · round 2review03:53:06–04:13:5121m91findings
agents-talks · fixesbuild03:54:38–03:56:141m 36s8Agents.tsx
eggs · fixesbuild03:54:43–03:56:321m 49s9Eggs.tsx
shell · fixesbuild03:54:51–04:07:5113m29styles.css
verifier · round 2review04:35:19–04:51:1116m56findings
shell · fixesbuild04:52:07–05:28:3436m139styles.css
perf · fixesbuild04:52:10–05:08:4617m69Perf.tsx
work · fixesbuild04:52:13–05:10:2518m56Work.tsx
agents-talks · fixesbuild04:52:17–04:59:307m 13s27Agents.tsx
eggs · fixesbuild04:52:19–04:57:595m 40s23Eggs.tsx
design review · round 3review05:30:44–06:03:3933m208findings
recruiter review · round 3review05:30:46–05:56:0325m129findings
honesty review · round 3review05:30:46–05:48:4118m126findings
a11y review · round 3review05:30:46–06:44:401h 14m222findings
interactions review · round 3review05:30:46–07:04:301h 34m150findings
perfcode review · round 3review05:30:46–06:40:081h 09m164findings
verifier · round 3review05:48:41–05:55:136m 32s48findings
verifier · round 3review05:56:03–06:04:088m 05s43findings
agents-talks · fixesbuild06:01:58–06:26:5825m81Agents.tsx
eggs · fixesbuild06:02:06–06:08:256m 20s31Eggs.tsx
verifier · round 3review06:03:39–06:15:2412m79findings
shell · fixesbuild06:27:27–06:35:197m 53s28styles.css
perf · fixesbuild06:27:29–06:29:422m 13s15Perf.tsx
verifier · round 3review06:40:08–06:58:0018m53findings
verifier · round 3review06:44:40–07:00:2516m86findings
shell · fixesbuild07:02:16–07:10:248m 08s33styles.css
perf · fixesbuild07:02:22–07:12:049m 42s15Perf.tsx
work · fixesbuild07:02:27–07:06:233m 56s18Work.tsx
agents-talks · fixesbuild07:02:31–07:04:161m 44s11Agents.tsx
verifier · round 3review07:04:30–07:22:5818m69findings
shell · fixesbuild07:23:15–07:30:126m 57s27styles.css
work · fixesbuild07:23:20–07:30:447m 25s21Work.tsx
perf · fixesbuild07:23:22–07:25:522m 30s12Perf.tsx
content checkreview07:32:47–07:49:2917m71findings
visual checkreview07:32:48–07:50:1317m94findings
interact checkreview07:32:48–08:26:1753m110findings
sweep checkreview07:32:48–08:06:3634m116findings
verifierreview07:49:29–07:55:346m 04s24findings
verifierreview07:50:13–07:52:282m 15s23findings
verifierreview08:06:36–08:14:478m 11s40findings
verifierreview08:26:17–08:47:5022m31findings
agents-talks · fixesbuild08:34:46–08:37:062m 20s7Agents.tsx
04 // talks

Talks

ArkType: Bringing TypeScript to Runtime

TypeScript Congress 2023

How the type-level parser works, from top-down to shift-reduce, and what it buys you at runtime.

05 // said

Said in public

06 // before

Before all this

  1. 2019–21Redo

    Founded it. We built a desktop app that turned recorded user interactions into UI tests. ArkType's git history still starts in Redo's repo, June 2019.

  2. 2017–19Amazon

    SDET II, Alexa Devices. Built PyEcho, Amazon's standard test-automation framework for Alexa devices.

  3. 2011–15Tufts

    Computer Science, Entrepreneurial Leadership, Philosophy.

07 // contact

Say hi

Building something hard in TypeScript or AI? I'd love to hear about it.