- Note•
Concurrency in transactions
There’s a temptation to make independent database operations concurrent:
await db.transaction(async (tx) => { await Promise.all([ tx .update(accounts) .set({ balance: sql`${accounts.balance} - 100.00` }) .where(eq(accounts.name, 'Dan')), tx .update(accounts) .set({ balance: sql`${accounts.balance} + 100.00` }) .where(eq(accounts.name, 'Andrew')), ]); });TypeScriptInside a transaction, though, there usually isn’t any point. Even if both promises fire at once, the driver still has to send the statements down a single connection.
Anything not bound to the database connection can still run concurrently:
await db.transaction(async (tx) => { await Promise.all([ otherAsyncWork(), tx .update(accounts) .set({ balance: sql`${accounts.balance} + 100.00` }) .where(eq(accounts.name, 'Andrew')), ]); });TypeScriptBut you probably shouldn’t do other I/O in the middle of a transaction anyway if you can avoid it (especially writes). It keeps the transaction open for longer, and any external side effects won’t be rolled back.
- Note•
Avoiding prettified logs
It’s common to pretty-print logs to stdout during development:
[10:42:18] INFO Request started method: GET path: /api/posts requestId: req_123Then switch to structured logs in production:
{"time":"2026-05-24T10:42:18.120Z","level":"info","message":"Request started","method":"GET","path":"/api/posts","requestId":"req_123"}JSONPretty logs are nice when an app is small, but they become painful once things scale. Thousands of lines fly past, terminal search only gets you so far (your scrollback needs to be set absurdly high), and when the terminal closes, the logs are gone.
I’ve started to prefer writing structured logs to disk during development. Send them over to something like Logdy (if you want something lightweight), or VictoriaLogs (if you want something a bit more capable).
Then you get the same filtering, grouping, and JSON-attribute goodness you rely on in production. It’s also very useful to be able to point your agent at the logs of an already running process.
- Note•
Distributed Zod discriminated unions
Here’s a trick that seems obvious in retrospect. If you want to represent a type like this in Zod:
type Order = { name: string } & ( | { orderType: 'DELIVERY'; details: DeliveryOrderDetails } | { orderType: 'PICKUP'; details: PickupOrderDetails } );TypeScriptYou can just create the union type separately and then intersect it:
const OrderDetails = z.discriminatedUnion('orderType', [ z.object({ orderType: z.literal('DELIVERY'), details: DeliveryDetailsSchema, }), z.object({ orderType: z.literal('PICKUP'), details: PickupDetailsSchema, }), ]); const OrderSchema = z.object({ name: z.string() }).and(OrderDetails); // Or this: // const OrderSchema = z.intersection(z.object({ name: z.string() }), OrderDetails);TypeScriptNeat if you’re forced to keep the type discriminator top-level.
- Note•
Vitest async fixture destructuring
Vitest’s custom fixture support is great. Originally inspired by Playwright’s fixture setup, it’s now evolved into an auto-typed flexible builder:
const test = baseTest .extend('client', () => new UserClient()) .extend('user', async ({ client }) => client.getUser()) test('Does the thing', async ({ user }) => { // No need to await user, it's already resolved. })TypeScriptI’ve long wondered how they manage to lazily initialise fixtures based on object destructuring — even with a Proxy or similar it’s not possible to hide the async part. Today I finally took a look, and it’s actually pretty cursed:
// https://github.com/vitest-dev/vitest/blob/v4.1/packages/runner/src/fixture.ts#L646 let fnString = filterOutComments(implementation.toString())TypeScriptThe trick is to stringify the function and extract with regex the names of the fixtures requested. Vitest can then build up the fixture dependency tree and resolve these before passing them to your test fixture.
It’s also why this doesn’t work:
test('Does the thing', async (ctx) => { // No proxy magic or anything wild, so this won't work - // only the function arguments are parsed. const { user } = ctx })TypeScriptTurns out Playwright does the extact same thing.