This week project is a glimpse into the future.
In fact, this week is all about Effect. I implemented a NextJs app that allows a user to sign up to your newsletter on ConvertKit.
Let's dive in!
Effect + XState + Local First are going to change how you write #typescript code. If you are a web developer you must definitely be aware of these 3 new way of programming that are going to become the standard in Typescript in 2024. @EffectTS_ is a library that exploits the…
Tech stack
- Effect: library that exploits the full power of the Typescript type system to make your programs more reliable and easier to maintain
- ConvertKit: marketing platform that I use for this newsletter
- NextJs: React framework
Setup
The app is built using NextJs. Running npx create-next-app@latest
is enough to get started:
npx create-next-app@latest
I then switched to pnpm
instead of npm
. This just requires installing pnpm
(I used homebrew to do it), delete package-lock.json
, and then run pnpm install
. Highly recommended!
Get started
My goal was for the app to be 100% Effect. Everything is based on 3 packages in the Effect ecosystem:
effect
@effect/schema
@effect/platform
I had not previous experience with @effect/platform
.
The first step was looking at the API reference and the Github README. The README provided a clear example for an HTTP request, which was enough to get started.
The app contains a single form to submit you email. The app will send a request to the ConvertKit API to subscribe the user.
Here are the links to all the documentation needed for this project:
There is more 🤩
Timeless coding principles, practices, and tools that make a difference, regardless of your language or framework, delivered in your inbox every week.
Implementation
The mental model I followed when using Effect is:
- Plan and define all the services (
Context.Tag
) - Define all the required configuration (
Config
) - Define all the schemas (using
@effect/schema
) - Implement all the services
Implementing the services requires composing all the previously defined configurations:
- Services can be composed with each other using
Layer
Effect.config
allows to read any configuration value (Config
)- Validate all the data using schemas (with methods like
parseEither
orHttp.request.schemaBody
)
Important: A common error I often made is to use some "global" variable or function inside the implementation.
All dependencies should be composed using
Config
or services. These errors cause problems during testing, because you cannot inject fake or mocked values.
Now we have a working program. Effect collects all dependencies, errors, and return value on the Effect
type (Effect.Effect<Dependencies, Errors, ReturnValue>
).
The last steps are:
- Providing all the dependencies (
Effect.provide
) - Handling all errors (
Effect.catchTags
,Effect.catchAll
or similar) - Running the effect (
Effect.runPromise
)
Done! Effect exploits the full power of the Typescript type-system, so I was confident that no type errors meant that everything was going to work as expected ("If it complies it works").
Just to make sure, I implemented some tests. Testing with Effect is not only easy, but extremely satisfying. I used vitest
and msw
(HTTP mocking), and everything worked as expected.
👉 For all the details and code snippets you can read the full article containing all the details of the implementation.
Takeaways
- It takes some time to get used to Effect, but it's worth it
- NextJs is not necessary, any framework (or no framework) works as well. NextJs was convenient because it allows to implement client components and API routes in the same project
- A lot can go wrong with a simple API request. Effect does a great job with error handling
- It took some time to setup a working configuration to test the app (using
vitest
andmsw
), but the satisfaction of seeing the tests passing was worth it!
Fun fact: I never actually run the app, no need to. Using Effect and implementing some tests is enough to make sure that everything is working correctly. Type-safe and powerful!
You should definitely try Effect, it's the future of Typescript. I am migrating all my projects to it, so expect more news and tutorials.
That's it for this week project. Looking forward to start another one for next week!
See you next 👋