effect
Effect-TS Best Practices
Opinionated patterns for Effect-TS codebases. Effect provides typed functional programming with composable errors, dependency injection, and observability.
Critical Rules
- NEVER use
anyor type casts (as Type) - UseSchema.make()for branded types,Schema.decodeUnknown()for parsing - Don't use
catchAllwhen error type isnever- No errors to catch - Never use global
Errorin Effect channels - UseSchema.TaggedErrorfor domain errors - Ban
{ disableValidation: true }- Lint against this - Don't wrap safe operations in Effect - Only use
Effect.try()for throwing operations - Use
mapErrornotcatchAllCause- Distinguish expected errors from bugs - Never silently swallow errors - Failures MUST be visible in the Effect's error channel E
Quick Reference
| Pattern | DON'T | DO |
|---|---|---|
| Service definition | Context.Tag |
Effect.Service with dependencies array |
| Error types | Generic Error |
Schema.TaggedError with context fields |
| Branded IDs | Raw string |
Schema.String.pipe(Schema.brand("@Ns/Entity")) |
| Running effects | runSync/runPromise in services |
Return Effect, run at edge |
| Logging | console.log |
Effect.log with structured data |
| Configuration | process.env |
Config with validation |
| Method tracing | Manual spans | Effect.fn("Service.method") |
| Nullable results | null/undefined |
Option types |
| State | Mutable variables | Ref |
| Time | Date.now(), new Date() |
Clock service |
Service Pattern
class UserService extends Effect.Service<UserService>()("UserService", {
dependencies: [DatabaseService.Default],
effect: Effect.gen(function* () {
const db = yield* DatabaseService
return {
findById: Effect.fn("UserService.findById")(
(id: UserId) => db.query(/* ... */)
),
}
}),
}) {}
// Usage - dependencies auto-provided
UserService.findById(userId)
Error Handling
// Define domain-specific errors
class UserNotFoundError extends Schema.TaggedError<UserNotFoundError>()(
"UserNotFoundError",
{ userId: UserId, message: Schema.String }
) {}
// Handle with catchTag (preserves type info)
effect.pipe(
Effect.catchTag("UserNotFoundError", (e) => /* handle */),
Effect.catchTag("AuthExpiredError", (e) => /* handle */)
)
Schema Pattern
// Branded ID
const UserId = Schema.String.pipe(Schema.brand("@App/UserId"))
// Domain entity with Schema.Class
class User extends Schema.Class<User>("User")({
id: UserId,
email: Schema.String,
createdAt: Schema.DateFromSelf,
}) {
get displayName() { return this.email.split("@")[0] }
}
Layer Composition
// Declare dependencies in service, not at usage
const MainLayer = Layer.mergeAll(
UserServiceLive,
AuthServiceLive,
DatabaseLive
)
// Run program
Effect.runPromise(program.pipe(Effect.provide(MainLayer)))
Detailed Guides
- Anti-Patterns - Forbidden patterns with fixes
- Error Patterns - Domain errors, rich context, HTTP mapping
- Schema Patterns - Branded types, transforms, validation
- Service Patterns - Effect.Service, dependency injection
- Layer Patterns - Composition, memoization, testing
- Observability Patterns - Logging, tracing, metrics
- SQL Patterns - Database integration, transactions
- Testing Patterns - effect-vitest, property testing, Testcontainers
- Atom Patterns - React state management with Effect
- RPC & Cluster Patterns - Distributed systems
More from michaelvessia/nixos-config
proxmox
|
15mermaid-to-png
Convert mermaid diagrams in markdown files to PNG images. Use when the user wants to export markdown with mermaid to formats that don't support mermaid (Google Docs, PDF, etc).
14paperless
Search and manage documents in Paperless-ngx document management system. Use when the user asks about documents, invoices, receipts, tax forms, bills, or wants to search their document library.
13obsidian-save
|
12qmd
|
11home-assistant-manager
Expert-level Home Assistant configuration management with efficient deployment workflows (git and rapid scp iteration), remote CLI access via SSH and hass-cli, automation verification protocols, log analysis, reload vs restart optimization, and comprehensive Lovelace dashboard management for tablet-optimized UIs. Includes template patterns, card types, debugging strategies, and real-world examples.
11