better-effect

Getting Started

Install better-effect and build a complete typed workflow.

Install the two building blocks

better-effect builds on better-result, so install both packages:

bun add better-effect better-result
bash bun add better-effect better-result

The public TypeScript peer range starts at 5.2. better-effect also uses the standard Symbol.dispose and Symbol.asyncDispose declarations for disposable resources, so your tsconfig should include a modern JavaScript library such as ESNext.Disposable.

A tiny complete application

This example has one dependency and one program. The type of program records that it needs GreetingService; the Runtime is accepted only when its Layer provides that Service.

import { Result } from 'better-result'
import { Effect, Layer, Runtime, Service } from 'better-effect'
import { MemoryLayerBackend } from 'better-effect/testing'

class GreetingService extends Service<GreetingService>()('GreetingService') {
  greet(name: string) {
    return `Hello, ${name}!`
  }
}

const GreetingLive = Layer.make(GreetingService)

const program = Effect.gen(function* () {
  const greeting = yield* GreetingService

  return Result.ok(greeting.greet('Ada'))
})

const runtime = await Runtime.make(GreetingLive, new MemoryLayerBackend())
const result = await runtime.run(() => program)
await runtime.dispose()

if (Result.isOk(result)) {
  console.log(result.value) // Hello, Ada!
}

MemoryLayerBackend is exported from better-effect/testing; the root export does not include test-only backends. Import it explicitly in a real project:

import { MemoryLayerBackend } from 'better-effect/testing'

Project shape

main.ts

Keep behavior in Services and keep construction in Layers. Your application entry point should be the place where a concrete backend and Runtime are selected.

Next steps

  1. Learn how Services become typed dependency tokens.
  2. Compose implementations with Layers.
  3. Understand execution and shutdown in Runtime.
  4. Add ownership to connections and files with Scope and Resource.

On this page