What You’ll Build
You’ll create a user management service that:- Fetches user data with type-safe error handling
- Uses dependency injection with services and layers
- Implements structured logging
- Demonstrates Effect’s generator syntax
Prerequisites
Make sure you’ve installed Effect and have a TypeScript project set up.Building the Application
Define custom errors
First, create typed errors using
Schema.TaggedErrorClass. This makes errors part of your type signatures:index.ts
Schema.TaggedErrorClass creates serializable error types that work seamlessly with Effect’s error handling.Create a service
Services encapsulate your application’s capabilities. Define a
UserRepository service:index.ts
Effect.fn is used to define functions that return Effects. It provides better stack traces and automatic tracing.Add error handling
Handle errors gracefully with Effect’s error handling combinators:
index.ts
Effect.catchTag lets you handle specific error types. The error type is removed from the signature after handling.Provide dependencies and run
Finally, provide the service implementation and run the program:
index.ts
Effect.provide injects the service implementation. Effect.runPromise executes the Effect and returns a Promise.Complete Example
Here’s the full code in one place:View complete example
View complete example
index.ts
Key Concepts Demonstrated
This example showcases several important Effect patterns:Effect.gen & Effect.fn
Use generator functions for imperative-style code with
yield* to unwrap Effects.Services & Layers
Define services with
ServiceMap.Service and provide implementations with Layer.effect.Tagged Errors
Create type-safe errors with
Schema.TaggedErrorClass and handle them with Effect.catchTag.Dependency Injection
Use
Effect.provide to inject service implementations, making code testable and modular.What’s Next?
Now that you’ve built your first Effect application, explore more advanced topics:Core Concepts
Deep dive into the Effect type and its capabilities
Services & Layers
Master dependency injection and service composition
Error Handling
Learn advanced error handling patterns
Testing
Write tests for your Effect applications
Common Patterns
Running in Node.js with NodeRuntime
For production applications, useNodeRuntime.runMain instead of Effect.runPromise:
Creating Effects from Promises
Wrap existing Promise-based APIs:Testing with Mock Services
Replace real implementations with test doubles:Troubleshooting
Type errors with yield*
Type errors with yield*
Make sure you’re using
yield* (with asterisk) to unwrap Effects, not just yield. The asterisk is required for TypeScript to infer types correctly.Service not found errors
Service not found errors
If you get runtime errors about missing services, ensure you’ve called
Effect.provide() with all required service layers before running the program.Error handling doesn't work
Error handling doesn't work
Remember that
Effect.catchTag only catches errors that are in the Effect’s error channel. Use the correct error tag name (must match the first parameter to TaggedErrorClass).