esteban@devtrillo:~/blog/writing$
← cd -
$ cat learning-effect-9-run-effects-at-the-edge.md

Part 9: Run Effects at the Edge

Jul 18, 2026·1 min read
$ tail -f learning-effect-9-run-effects-at-the-edge/readers
connecting…

An Effect does not run when you create it.

That was the first weird part.

The next question is where to run it.

My current answer:

Run Effects at the edge.

The edge is where the outside world calls you

An HTTP handler is an edge.

A CLI command is an edge.

A cron job is an edge.

That is where you turn the Effect description into real work.

export async function GET(request: Request) {
const program = handleRequest(request);
const response = await Effect.runPromise(program);
return response;
}

Which line starts the work?

Helpers should usually return Effects

This is the trap:

const getUser = async (id: number) => Effect.runPromise(fetchUser(id));

That throws away a lot.

Now the caller gets a Promise. The typed error is gone. The requirement handling is hidden. Composition gets worse.

Better:

const getUser = (id: number) => fetchUser(id);

Let the edge run it.

Should a low-level helper usually call runPromise?

Why this feels familiar

This is like keeping business logic out of your route handler.

The route handler receives the world.

The program describes the work.

The runner starts it.

That split keeps the center of the app easier to test and easier to read.