npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@spilne/perfect-core

v0.2.0

Published

TypeScript effect runtime — Eff<A,S> with typed errors and dependencies, fibers, structured concurrency, pull-based streams, and messaging contracts.

Readme

@spilne/perfect-core

The Perfect effect runtime — like effect-ts or ZIO, but with a flat union type and a fluent API. Eff<A, S> is an effect producing A, where S is a flat union of effect tags: Throws<E> for typed errors, Needs<D> for typed dependencies. Compose with .flatMap(), .map(), .catch() — no pipe(). Everything else in the Perfect stack (@spilne/perfect-http, @spilne/perfect-kafka, @spilne/perfect-topology, …) is built on this package.

Install

bun add @spilne/perfect-core

Not yet published to npm — install from the workspace for now.

Quickstart

import { eff, succeed, fail, type Eff, type Throws } from "@spilne/perfect-core";

type Err = { _tag: "NotFound"; id: number };

const lookup = (id: number): Eff<string, Throws<Err>> =>
  id === 1 ? succeed("alice") : fail<Err>({ _tag: "NotFound", id });

const program = eff(function* () {
  const name = yield* lookup(1).catchTag("NotFound", (e) => succeed(`missing ${e.id}`));
  return `hello, ${name}`;
});

console.log(await program.run()); // → "hello, alice"

Handling an error removes it from the type: after .catchTag("NotFound", …) the Throws<Err> requirement is gone. Defects and interruption remain possible; never in the effect channel does not mean an operation is infallible.

Services work the same way — a dependency is an effect tag until you provide it:

import { eff, succeed, service, provide, type Eff } from "@spilne/perfect-core";

interface Greeter {
  greet(name: string): Eff<string, never>;
}
const Greeter = service<Greeter>()("Greeter");

const app = eff(function* () {
  const greeter = yield* Greeter.get;
  return yield* greeter.greet("world");
});

const wired = provide(app, Greeter, { greet: (name) => succeed(`hello, ${name}`) });
console.log(wired.runSync()); // → "hello, world"

Three syntactic styles

All compile to the same fiber walk — pick by readability:

// Generator (recommended — no build step)
const a = eff(function* () {
  return (yield* succeed(21)) * 2;
});

// Composed .flatMap (fastest)
const b = succeed(21).flatMap((x) => succeed(x * 2));

// eff($) sugar (cleanest — needs @spilne/perfect-swc-plugin or @spilne/perfect-transform)
const c = eff(($) => {
  const x = $(succeed(21));
  return x * 2;
});

Running

| Function | When to use | | --------------- | ----------------------------------------------------------------------- | | runSync(eff) | Sync only — throws if the effect suspends. | | run(eff) | Returns Promise<A>, rejects with squashed cause on failure. | | runExit(eff) | Returns Promise<Exit<unknown, A>> — preserves the full failure cause. | | runFiber(eff) | Returns a Fiber<A> you can join, interrupt, race. |

Each is also a fluent method: program.run(), .runSync(), .runExit(), .runFiber().

What's in the box

  • Constructorssucceed, fail, die, sync, suspend, async, tryPromise, fromPromise
  • ErrorsThrows<E>, .catch / .catchTag, Cause (Fail | Die | Interrupt | composites), Exit, TaggedError
  • Services + Layersservice, provide, Layer for memoized, dependency-ordered wiring
  • Concurrencyfork / forkDaemon, join, race / raceAll, all, bounded forEachPar, timeout, structured interruption with uninterruptible / uninterruptibleMask, Fiber supervision
  • ResourcesacquireRelease, scoped, ensuring, onExit, createGracefulShutdown
  • Retry + scheduleretry, RetryPolicy, Schedule, repeat, repeatUntilWithBackoff, hedged
  • StreamsStream / Chunk / Sink / Pipes: fused, lazy, effect-typed; lazy fromAsyncIterable, backpressured toAsyncIterable, mapAccumulate, backend-powered statefulMap, ordered/unordered parEvalMap, switchMap, exhaustMap, bounded/unbounded parJoin, combineLatest, withLatest, single-pass broadcastThrough, reliable observe/takeUntil, typed stream recovery, source-reacquiring retryFrom, Clock-driven time operators, and CSV/base64/binary pipes
  • CoordinationRef, Deferred, Queue, Semaphore, Latch, Barrier, PubSub, SubscriptionRef, Pool, WorkerPool
  • ResilienceCircuitBreaker, RateLimiter, Throttle, Singleflight, cached / CacheStore
  • ObservabilityLogger, Tracer / withSpan, Metrics (Counter, Gauge, Histogram) — bridge to OpenTelemetry via @spilne/perfect-otel
  • TestingTestClock, TestRandom, TestConsole, TestLogger, TestTracer, property testing with Gen / forAll
  • UtilitiesDuration, typeclasses (Eq, Ord, Show, Monoid)

Subpath exports

| Import | Contents | | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | @spilne/perfect-core | Everything above | | @spilne/perfect-core/stream | Stream, Chunk, Sink, Pipes (also re-exported from root) | | @spilne/perfect-core/retry | RetryPolicy, Schedule, retryWith, and scheduled repetition | | @spilne/perfect-core/connect | Queue-agnostic endpoint contracts (Streamable, Sinkable, Envelope, Codec, OffsetTracker, …) — implemented by @spilne/perfect-kafka, consumed by @spilne/perfect-topology | | @spilne/perfect-core/syntax | The eff comprehension entry point | | @spilne/perfect-core/worker | WorkerPool |

Links