effect-patterns-tooling-and-debugging
Effect-TS patterns for Tooling And Debugging. Use when working with tooling and debugging in Effect-TS applications.
Install
mkdir -p .claude/skills/effect-patterns-tooling-and-debugging && curl -L -o skill.zip "https://mcp.directory/api/skills/download/4875" && unzip -o skill.zip -d .claude/skills/effect-patterns-tooling-and-debugging && rm skill.zipInstalls to .claude/skills/effect-patterns-tooling-and-debugging
About this skill
Effect-TS Patterns: Tooling And Debugging
This skill provides 8 curated Effect-TS patterns for tooling and debugging. Use this skill when working on tasks related to:
- tooling and debugging
- Best practices in Effect-TS applications
- Real-world patterns and solutions
🟢 Beginner Patterns
Read Effect Type Errors
Rule: Effect errors are verbose but structured - learn to extract the key information.
Rationale:
Effect type errors can be long, but they follow a pattern. Learn to scan for the key parts.
Effect's type system catches many bugs at compile time, but:
- Effect types are complex - Three type parameters
- Errors are nested - Multiple layers of generics
- Messages are verbose - TypeScript shows everything
Understanding the pattern makes errors manageable.
Set Up Your Effect Development Environment
Rule: Install the Effect extension and configure TypeScript for optimal Effect development.
Rationale:
Set up your development environment with the Effect extension and proper TypeScript configuration for the best experience.
A well-configured environment helps you:
- See types clearly - Effect types can be complex
- Get better autocomplete - Know what methods are available
- Catch errors early - TypeScript finds problems
- Navigate easily - Go to definitions, find references
🟡 Intermediate Patterns
Supercharge Your Editor with the Effect LSP
Rule: Install and use the Effect LSP extension for enhanced type information and error checking in your editor.
Good Example:
Imagine you have the following code. Without the LSP, hovering over program might show a complex, hard-to-read inferred type.
import { Effect } from "effect";
// Define Logger service using Effect.Service pattern
class Logger extends Effect.Service<Logger>()("Logger", {
sync: () => ({
log: (msg: string) => Effect.log(`LOG: ${msg}`),
}),
}) {}
const program = Effect.succeed(42).pipe(
Effect.map((n) => n.toString()),
Effect.flatMap((s) => Effect.log(s)),
Effect.provide(Logger.Default)
);
// Run the program
Effect.runPromise(program);
With the Effect LSP installed, your editor would display a clear, readable overlay right above the program variable, looking something like this:
// (LSP Inlay Hint)
// program: Effect<void, never, never>
This immediately tells you that the final program returns nothing (void), has no expected failures (never), and has no remaining requirements (never), so it's ready to be run.
Anti-Pattern:
Going without the LSP. While your code will still compile and work perfectly fine, you are essentially "flying blind." You miss out on the rich, real-time feedback that the LSP provides, forcing you to rely more heavily on manual type checking, tsc runs, and deciphering complex inferred types from your editor's default tooltips. This leads to a slower, less efficient development cycle.
Rationale:
To significantly improve your development experience with Effect, install the official Effect Language Server (LSP) extension for your code editor (e.g., the "Effect" extension in VS Code).
Effect's type system is incredibly powerful, but TypeScript's default language server doesn't always display the rich information contained within the A, E, and R channels in the most intuitive way.
The Effect LSP is a specialized tool that understands the semantics of Effect. It hooks into your editor to provide a superior experience:
- Rich Inline Types: It displays the full
Effect<A, E, R>signature directly in your code as you work, so you always know exactly what an effect produces, how it can fail, and what it requires. - Clear Error Messages: It provides more specific and helpful error messages tailored to Effect's APIs.
- Enhanced Autocompletion: It can offer more context-aware suggestions.
This tool essentially makes the compiler's knowledge visible at a glance, reducing the mental overhead of tracking complex types and allowing you to catch errors before you even save the file.
Use Effect DevTools
Rule: Use Effect's built-in debugging features and logging for development.
Good Example:
1. Enable Debug Mode
import { Effect, Logger, LogLevel, FiberRef, Cause } from "effect"
// ============================================
// 1. Verbose logging for development
// ============================================
const debugProgram = Effect.gen(function* () {
yield* Effect.logDebug("Starting operation")
const result = yield* someEffect.pipe(
Effect.tap((value) => Effect.logDebug(`Got value: ${value}`))
)
yield* Effect.logDebug("Operation complete")
return result
})
// Run with debug logging enabled
const runWithDebug = debugProgram.pipe(
Logger.withMinimumLogLevel(LogLevel.Debug),
Effect.runPromise
)
// ============================================
// 2. Fiber supervision and introspection
// ============================================
const inspectFibers = Effect.gen(function* () {
// Fork some fibers
const fiber1 = yield* Effect.fork(Effect.sleep("1 second"))
const fiber2 = yield* Effect.fork(Effect.sleep("2 seconds"))
// Get fiber IDs
yield* Effect.log(`Fiber 1 ID: ${fiber1.id()}`)
yield* Effect.log(`Fiber 2 ID: ${fiber2.id()}`)
// Check fiber status
const status1 = yield* fiber1.status
yield* Effect.log(`Fiber 1 status: ${status1._tag}`)
})
// ============================================
// 3. Trace execution with spans
// ============================================
const tracedProgram = Effect.gen(function* () {
yield* Effect.log("=== Starting traced program ===")
yield* Effect.gen(function* () {
yield* Effect.log("Step 1: Initialize")
yield* Effect.sleep("100 millis")
}).pipe(Effect.withLogSpan("initialization"))
yield* Effect.gen(function* () {
yield* Effect.log("Step 2: Process")
yield* Effect.sleep("200 millis")
}).pipe(Effect.withLogSpan("processing"))
yield* Effect.gen(function* () {
yield* Effect.log("Step 3: Finalize")
yield* Effect.sleep("50 millis")
}).pipe(Effect.withLogSpan("finalization"))
yield* Effect.log("=== Program complete ===")
})
// ============================================
// 4. Error cause inspection
// ============================================
const debugErrors = Effect.gen(function* () {
const failingEffect = Effect.gen(function* () {
yield* Effect.fail(new Error("Inner error"))
}).pipe(
Effect.flatMap(() => Effect.fail(new Error("Outer error")))
)
yield* failingEffect.pipe(
Effect.catchAllCause((cause) =>
Effect.gen(function* () {
yield* Effect.log("=== Error Cause Analysis ===")
yield* Effect.log(`Pretty printed:\n${Cause.pretty(cause)}`)
yield* Effect.log(`Is failure: ${Cause.isFailure(cause)}`)
yield* Effect.log(`Is interrupted: ${Cause.isInterrupted(cause)}`)
// Extract all failures
const failures = Cause.failures(cause)
yield* Effect.log(`Failures: ${JSON.stringify([...failures])}`)
return "recovered"
})
)
)
})
// ============================================
// 5. Context inspection
// ============================================
import { Context } from "effect"
class Config extends Context.Tag("Config")<Config, { debug: boolean }>() {}
const inspectContext = Effect.gen(function* () {
const context = yield* Effect.context<Config>()
yield* Effect.log("=== Context Contents ===")
yield* Effect.log(`Has Config: ${Context.getOption(context, Config)._tag}`)
})
// ============================================
// 6. Custom logger for development
// ============================================
const devLogger = Logger.make(({ logLevel, message, date, annotations, spans }) => {
const timestamp = date.toISOString()
const level = logLevel.label.padEnd(7)
const spanInfo = spans.length > 0
? ` [${[...spans].map(([name]) => name).join(" > ")}]`
: ""
const annotationInfo = Object.keys(annotations).length > 0
? ` ${JSON.stringify(Object.fromEntries(annotations))}`
: ""
console.log(`${timestamp} ${level}${spanInfo} ${message}${annotationInfo}`)
})
const withDevLogger = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
effect.pipe(
Effect.provide(Logger.replace(Logger.defaultLogger, devLogger))
)
// ============================================
// 7. Runtime metrics
// ============================================
const showRuntimeMetrics = Effect.gen(function* () {
const runtime = yield* Effect.runtime()
yield* Effect.log("=== Runtime Info ===")
// Access runtime configuration
const fiberRefs = runtime.fiberRefs
yield* Effect.log("FiberRefs available")
})
// ============================================
// 8. Putting it all together
// ============================================
const debugSession = Effect.gen(function* () {
yield* Effect.log("Starting debug session")
// Run with all debugging enabled
yield* tracedProgram.pipe(
withDevLogger,
Logger.withMinimumLogLevel(LogLevel.Debug)
)
yield* debugErrors
yield* Effect.log("Debug session complete")
})
Effect.runPromise(debugSession)
Debug Output Example
2024-01-15T10:30:00.000Z DEBUG [initialization] Step 1: Initialize
2024-01-15T10:30:00.100Z DEBUG [processing] Step 2: Process
2024-01-15T10:30:00.300Z DEBUG [finalization] Step 3: Finalize
2024-01-15T10:30:00.350Z INFO Program complete
Rationale:
Use Effect's built-in debugging capabilities, logging, and fiber introspection for development.
Effect DevTools help you:
- See fiber state - What's running, blocked, completed
- Trace execution - Follow the flow of effects
- Debug errors - Understand failure chains
- Profile performance - Find slow operations
Configure Linting for Effect
Rule: Use B
Content truncated.
More by PaulJPhilp
View all skills by PaulJPhilp →You might also like
flutter-development
aj-geddes
Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.
drawio-diagrams-enhanced
jgtolentino
Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.
ui-ux-pro-max
nextlevelbuilder
"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."
godot
bfollington
This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.
nano-banana-pro
garg-aayush
Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.
fastapi-templates
wshobson
Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.
Related MCP Servers
Browse all serversAI-driven control of live Chrome via Chrome DevTools: browser automation, debugging, performance analysis and network mo
Use Chrome DevTools for web site test speed, debugging, and performance analysis. The essential chrome developer tools f
XcodeBuild streamlines iOS app development for Apple developers with tools for building, debugging, and deploying iOS an
Connect Supabase projects to AI with Supabase MCP Server. Standardize LLM communication for secure, efficient developmen
Use iOS Simulator for testing with tools like UI interaction and device info retrieval. Perfect as an iPhone emulator fo
Securely join MySQL databases with Read MySQL for read-only query access and in-depth data analysis.
Stay ahead of the MCP ecosystem
Get weekly updates on new skills and servers.