Effect · Coding with AI
Getting coding agents to write Effect code I can keep
The repo setup I use to make good patterns easier to follow and mistakes easier to catch.
First, check which Effect it thinks it’s using.
A coding agent can write very convincing code for a version of Effect I haven’t installed. The imports look reasonable. The explanation sounds confident. The compiler has a few questions.
Before changing models or writing a longer prompt, I check the context I’ve given it.
This matters during the move from Effect v3 to v4. Examples, package locations and APIs differ. “Use Effect best practices” leaves rather a lot to guess.
Put the right source within reach.
In this website’s repo, I keep a read-only copy of Effect’s source, pinned to the installed release. The agent can inspect actual implementations and examples when it gets stuck. I also keep the matching Foldkit source nearby.
I start with Effect’s LLMS.md and point to the relevant examples. I don’t ask the agent to read the entire library before moving a button.
A Git subtree is one way to keep that reference available in a normal clone. It adds repository weight, so I’d use it where the library is central to the project. A small dependency may only need its installed types and docs.
The important detail is the pin. Tracking the latest branch can give the agent tomorrow’s API for today’s dependency. When I upgrade the package, I update the reference too. Reference code stays out of application imports and build inputs.
Show one complete feature.
A good example answers more than “how do I write Effect.gen?”
I want the agent to see where input is decoded, how a service is provided, and how an expected failure reaches the user. I include the test, so it can see what the behaviour is meant to be.
For a booking feature, that might mean a BookingUnavailable error handled at the HTTP boundary. It shouldn’t become a generic error halfway through the service, losing the reason the booking failed.
I keep the repo instructions short. An illustrative entry might say:
Effect references: repos/effect/LLMS.md
Read the matching example before adding a new pattern.
Use the installed package, never import from repos/.
Keep expected failures in the error channel.
Run bun run check before handing back the change.
Report any check you could not run.I’d add the path to the team’s example feature. That is usually more helpful than a long list of rules with no code behind them.
Let the tools give useful feedback.
I use strict TypeScript checks and tests for the behaviour that matters. Effect-specific diagnostics can catch additional mistakes, provided the tooling supports the installed version.
The same checks should run in CI. Instructions can ask an agent to validate its work. A failing check can actually stop the merge.
I also look at what changed to make a check pass. Adding any, casting away a service requirement, or weakening an assertion can hide the original problem very efficiently.
Review the decision as well as the code.
I still ask whether the failure should be retried, whether the abstraction earns its place, and whether a teammate could follow the feature next week.
For longer tasks, I want a short handover: what changed, what was checked, and what remains unresolved. That helps the next session start from facts.
The result I’m after is less time correcting conventions and more time thinking about the product. The repo setup helps with the first part. I’m still responsible for the second.
Give the agent version-matched examples and useful feedback. Keep the code review about the product, not another round of fixing invented APIs.
Working on something similar?
Get in touch