EF

effect-patterns-tooling-and-debugging

Learn to manage Effect-TS type errors and optimize your development environment for better debugging.

Install

mkdir -p .claude/skills/effect-patterns-tooling-and-debugging && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/4875" && unzip -o skill.zip -d .claude/skills/effect-patterns-tooling-and-debugging && rm skill.zip

Installs to .claude/skills/effect-patterns-tooling-and-debugging

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Effect-TS patterns for Tooling And Debugging. Use when working with tooling and debugging in Effect-TS applications.
116 chars✓ has a “when” trigger
Beginner

Key capabilities

  • Configure IDE type inspection
  • Filter verbose type errors
  • Setup Effect-TS development environment
  • Navigate complex type hierarchies

How it works

Uses a pattern-matching approach to prune verbose TypeScript generics and provide IDE configuration guidance.

Inputs & outputs

You give it
Effect-TS code snippet or error log
You get back
Simplified error explanation or config fix

When to use effect-patterns-tooling-and-debugging

  • Debugging complex Effect-TS type errors
  • Setting up an Effect-TS development environment
  • Improving autocomplete in Effect applications

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:

  1. Effect types are complex - Three type parameters
  2. Errors are nested - Multiple layers of generics
  3. 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:

  1. See types clearly - Effect types can be complex
  2. Get better autocomplete - Know what methods are available
  3. Catch errors early - TypeScript finds problems
  4. 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:

  1. See fiber state - What's running, blocked, completed
  2. Trace execution - Follow the flow of effects
  3. Debug errors - Understand failure chains
  4. Profile performance - Find slow operations


Configure Linting for Effect

Rule: Use B


Content truncated.

When not to use it

  • Standard TypeScript debugging
  • Non-Effect applications

Prerequisites

Effect LSP extension

Limitations

  • Cannot fix logical runtime errors
  • Dependent on Effect library versioning

How it compares

It acts as an interpreter for the specific, highly complex type system of the Effect library.

Compared to similar skills

effect-patterns-tooling-and-debugging side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
effect-patterns-tooling-and-debugging (this skill)17moReviewBeginner
javascript-mastery76moNo flagsBeginner
tech-debt-analyzer59moReviewIntermediate
error-handling22moNo flagsIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

You might also like

javascript-mastery

davila7

Comprehensive JavaScript reference covering 33+ essential concepts every developer should know. From fundamentals like primitives and closures to advanced patterns like async/await and functional programming. Use when explaining JS concepts, debugging JavaScript issues, or teaching JavaScript fundamentals.

731

tech-debt-analyzer

ailabs-393

This skill should be used when analyzing technical debt in a codebase, documenting code quality issues, creating technical debt registers, or assessing code maintainability. Use this for identifying code smells, architectural issues, dependency problems, missing documentation, security vulnerabilities, and creating comprehensive technical debt documentation.

522

error-handling

EpicenterHQ

Error handling patterns using wellcrafted trySync and tryAsync. Use when writing error handling code, using try-catch blocks, or working with Result types and graceful error recovery.

27

codex-code-review

tyrchen

Perform comprehensive code reviews using OpenAI Codex CLI. This skill should be used when users request code reviews, want to analyze diffs/PRs, need security audits, performance analysis, or want automated code quality feedback. Supports reviewing staged changes, specific files, entire directories, or git diffs.

16

dead-code

parcadei

Find unused functions and dead code in the codebase

16

devtu-fix-tool

mims-harvard

Fix failing ToolUniverse tools by diagnosing test failures, identifying root causes, implementing fixes, and validating solutions. Use when ToolUniverse tools fail tests, return errors, have schema validation issues, or when asked to debug or fix tools in the ToolUniverse framework.

16

Search skills

Search the agent skills registry