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

@typesugar/effect

v0.1.0

Published

🧊 Effect-TS adapter for typesugar - do-notation and comprehension syntax

Downloads

42

Readme

@typesugar/effect

Deep Effect-TS integration with typesugar's compile-time macro system.

Overview

@typesugar/effect provides comprehensive integration between typesugar and Effect-TS:

  • @service — Zero-boilerplate service definitions with Context.Tag generation
  • @layer — Declarative dependency injection with automatic registration
  • resolveLayer() — Automatic layer composition from dependency graph
  • Enhanced do-notationlet:/yield: syntax with proper E/R type inference
  • @derive macros — Auto-generate Schema, Equal, Hash implementations
  • Extension methods — Fluent API for Effect types
  • Typeclass instances — Bridge Effect to typesugar's generic FP typeclasses

Installation

npm install @typesugar/effect
# or
pnpm add @typesugar/effect

Requires Effect-TS as a peer dependency:

npm install effect

Quick Start

@service — Define Services

import { service } from "@typesugar/effect";

@service
interface HttpClient {
  get(url: string): Effect.Effect<Response, HttpError>
  post(url: string, body: unknown): Effect.Effect<Response, HttpError>
}

// Generates:
// - HttpClientTag (Context.Tag class)
// - HttpClient.get, HttpClient.post (accessor functions)

@layer — Define Layers

import { layer } from "@typesugar/effect";

@layer(HttpClient)
const httpClientLive = {
  get: (url) => Effect.tryPromise(() => fetch(url)),
  post: (url, body) => Effect.tryPromise(() => fetch(url, { method: "POST", body })),
};
// Generates: Layer.succeed(HttpClientTag, { ... })

@layer(UserRepo, { requires: [Database] })
const userRepoLive =
let: {
  db << Database;
}
yield: ({ findById: (id) => db.query(sql`SELECT * FROM users WHERE id = ${id}`) })
// Generates: Layer.effect(UserRepoTag, ...)
// + registers dependency for automatic resolution

resolveLayer() — Automatic Layer Composition

import { resolveLayer } from "@typesugar/effect";

const program: Effect<void, Error, UserRepo | HttpClient> = ...;

// Automatically resolve and compose all required layers:
const runnable = program.pipe(
  Effect.provide(resolveLayer<UserRepo | HttpClient>())
);

Do-Notation with E/R Inference

// Error and requirement types are correctly accumulated:
let: {
  user << getUserById(id); // Effect<User, NotFound, UserRepo>
  posts << getPostsForUser(user.id); // Effect<Post[], DbError, PostRepo>
}
yield: ({ user, posts });

// Result type: Effect<{ user: User, posts: Post[] }, NotFound | DbError, UserRepo | PostRepo>

@derive Macros

import { EffectSchema, EffectEqual, EffectHash } from "@typesugar/effect";

@derive(EffectSchema)
interface User { id: string; name: string; age: number; }
// Generates: export const UserSchema = Schema.Struct({ ... })

@derive(EffectEqual)
interface Point { x: number; y: number; }
// Generates: export const PointEqual: Equal.Equal<Point> = { ... }

@derive(EffectHash)
interface Point { x: number; y: number; }
// Generates: export const PointHash: Hash.Hash<Point> = { ... }

Extension Methods

import { EffectExt, OptionExt, EitherExt } from "@typesugar/effect";

// Fluent method chaining (transformer rewrites to direct calls)
effect
  .map((x) => x + 1)
  .flatMap((x) => Effect.succeed(x * 2))
  .tap((x) => Effect.log(`Got: ${x}`))
  .orElseSucceed(() => 0);

Typeclass Instances

import { effectFunctor, effectMonad, effectMonadError, chunkFoldable } from "@typesugar/effect";

// Use with generic FP functions
const mapped = genericMap(effectFunctor<never, never>(), effect, f);

API Reference

Attribute Macros

| Macro | Description | | ------------------------ | ------------------------------------------------------------ | | @service | Generate Context.Tag and accessor namespace for an interface | | @layer(Service, opts?) | Wrap a const in Layer.succeed/effect/scoped | | @derive(EffectSchema) | Generate Effect Schema.Struct for a type | | @derive(EffectEqual) | Generate Equal.Equal instance for a type | | @derive(EffectHash) | Generate Hash.Hash instance for a type |

Expression Macros

| Macro | Description | | ------------------- | ----------------------------------------------- | | resolveLayer<R>() | Automatically compose layers for requirements R |

Registries

| Export | Description | | --------------------------- | ---------------------------------- | | serviceRegistry | Map of registered services | | layerRegistry | Map of registered layers | | registerService(info) | Manually register a service | | registerLayer(info) | Manually register a layer | | getService(name) | Look up service metadata | | getLayer(name) | Look up layer metadata | | getLayersForService(name) | Get all layers providing a service |

Extension Namespaces

| Export | Description | | ----------- | ------------------------------------- | | EffectExt | Extension methods for Effect.Effect | | OptionExt | Extension methods for Effect's Option | | EitherExt | Extension methods for Effect's Either |

Typeclass Instances

| Export | Description | | --------------------------- | ----------------------------- | | effectFunctor<E, R>() | Functor for Effect.Effect | | effectApplicative<E, R>() | Applicative for Effect.Effect | | effectMonad<E, R>() | Monad for Effect.Effect | | effectMonadError<E, R>() | MonadError for Effect.Effect | | chunkFunctor | Functor for Chunk | | chunkFoldable | Foldable for Chunk | | chunkTraverse | Traverse for Chunk | | effectOptionFunctor | Functor for Option | | effectOptionMonad | Monad for Option | | effectEitherFunctor<E>() | Functor for Either | | effectEitherMonad<E>() | Monad for Either |

HKT Types

| Export | Description | | ------------------------ | ------------------------------ | | EffectF<E, R> | HKT for Effect.Effect | | ChunkF | HKT for Chunk | | EffectOptionF<E, R> | HKT for Effect wrapping Option | | EffectEitherF<L, E, R> | HKT for Effect wrapping Either | | StreamF<E, R> | HKT for Stream |

Vision

See the Effect Integration Vision Doc for the full design including:

  • Track 1: Deep Effect-TS integration (current implementation)
  • Track 2: Fx compile-away system (future)

License

MIT