This skill should be used when the user asks about "Effect Runtime", "ManagedRuntime", "Effect.Tag", "custom runtime", "runtime layers", "running effects", "runtime configuration", "runtime context",...
The Runtime is Effect's execution engine:
Effects run via the default runtime:
import { Effect } from "effect"
const program = Effect.succeed(42)
// Async execution
const result = await Effect.runPromise(program)
// Sync execution
const syncResult = Effect.runSync(program)
// With full Exit information
const exit = await Effect.runPromiseExit(program)
| Method | Returns | Throws on Error |
|---|---|---|
Effect.runPromise(e) |
Promise<A> |
Yes |
Effect.runPromiseExit(e) |
Promise<Exit<A, E>> |
No |
Effect.runSync(e) |
A |
Yes |
Effect.runSyncExit(e) |
Exit<A, E> |
No |
Modify runtime behavior for specific effects:
import { Logger, LogLevel } from "effect"
const program = Effect.gen(function* () {
yield* Effect.log("This appears")
yield* Effect.logDebug("This may not appear")
})
// Set log level for this effect only
const withDebug = program.pipe(
Logger.withMinimumLogLevel(LogLevel.Debug)
)
Create typed service tags for dependency injection:
import { Effect, Context } from "effect"
// Define service with Effect.Tag (newer API)
class Database extends Context.Tag("Database")<
Database,
{
readonly query: (sql: string) => Effect.Effect<unknown[]>
readonly execute: (sql: string) => Effect.Effect<void>
}
>() {}
// Use the service
const program = Effect.gen(function* () {
const db = yield* Database
const users = yield* db.query("SELECT * FROM users")
return users
})
For applications needing custom runtime configuration:
import { ManagedRuntime, Layer } from "effect"
// Define your application layer
const AppLive = Layer.mergeAll(
DatabaseLive,
LoggerLive,
ConfigLive
)
// Create managed runtime
const runtime = ManagedRuntime.make(AppLive)
// Use the runtime
const main = async () => {
const result = await runtime.runPromise(program)
console.log(result)
// Cleanup
await runtime.dispose()
}
import express from "express"
import { ManagedRuntime, Layer } from "effect"
const AppLive = Layer.mergeAll(DatabaseLive, AuthLive)
const runtime = ManagedRuntime.make(AppLive)
const app = express()
app.get("/users", async (req, res) => {
const result = await runtime.runPromise(
getUsers().pipe(
Effect.catchAll((error) =>
Effect.succeed({ error: error.message })
)
)
)
res.json(result)
})
// Cleanup on shutdown
process.on("SIGTERM", () => {
runtime.dispose().then(() => process.exit(0))
})
import { ManagedRuntime } from "effect"
import { createContext, useContext } from "react"
// Create runtime context
const RuntimeContext = createContext<ManagedRuntime<AppServices> | null>(null)
// Provider component
export function AppProvider({ children }: { children: React.ReactNode }) {
const [runtime] = useState(() => ManagedRuntime.make(AppLive))
useEffect(() => {
return () => { runtime.dispose() }
}, [])
return (
<RuntimeContext.Provider value={runtime}>
{children}
</RuntimeContext.Provider>
)
}
// Hook to use runtime
export function useRuntime() {
const runtime = useContext(RuntimeContext)
if (!runtime) throw new Error("Runtime not provided")
return runtime
}
// Usage in components
function UserList() {
const runtime = useRuntime()
const [users, setUsers] = useState<User[]>([])
useEffect(() => {
runtime.runPromise(fetchUsers()).then(setUsers)
}, [])
return <ul>{users.map(u => <li key={u.id}>{u.name}</li>)}</ul>
}
import { Runtime, FiberRef } from "effect"
const customRuntime = Runtime.defaultRuntime.pipe(
Runtime.withFiberRef(FiberRef.currentLogLevel, LogLevel.Debug)
)
Runtime.runPromise(customRuntime)(program)
const runtimeWithServices = Runtime.defaultRuntime.pipe(
Runtime.provideService(Database, databaseImpl),
Runtime.provideService(Logger, loggerImpl)
)
Effect provides these services automatically:
import { Clock, Random, Tracer, Console } from "effect"
const program = Effect.gen(function* () {
// Clock - time operations
const now = yield* Clock.currentTimeMillis
// Random - random number generation
const rand = yield* Random.next
// Console - console output
yield* Console.log("Hello")
})
// No requirements - defaults provided
import { TestClock } from "effect"
// For testing - control time
const testProgram = program.pipe(
Effect.provide(TestClock.layer)
)
// Advance time manually
const testWithTime = Effect.gen(function* () {
const fiber = yield* Effect.fork(Effect.sleep("1 hour"))
yield* TestClock.adjust("1 hour")
yield* Fiber.join(fiber)
})
// Fork with interruption
const program = Effect.gen(function* () {
const fiber = yield* Effect.fork(longRunningTask)
// Later...
yield* Fiber.interrupt(fiber)
})
// Uninterruptible region
const critical = Effect.uninterruptible(
Effect.gen(function* () {
yield* startTransaction()
yield* doWork()
yield* commitTransaction()
})
)
For comprehensive runtime documentation, consult ${CLAUDE_PLUGIN_ROOT}/references/llms-full.txt.
Search for these sections: