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

effect-view

v0.1.4

Published

Write React function components with Effect

Readme

Effect View brings Effect's typed services, resource safety, concurrency, and data modeling into React 19 without replacing React's component model. Yield Effects and services from a component body, let scopes follow the React lifecycle, and return ordinary JSX.

Effect v4 RC: Effect View is built for the Effect v4 release candidate. If your application uses Effect v3, use the legacy effect-fc package instead.

npm install effect-view effect@rc react

Effect View does not depend on react-dom. Install the renderer used by your application—for example, react-dom for the web:

npm install react-dom

You can use Effect View with React Native or any other React renderer instead.

What it looks like

An Effect View component is an Effect program that produces JSX. It can create scoped state, access services, and use React-facing hooks without leaving the generator model:

import { Effect, SubscriptionRef } from "effect"
import { Component, Lens } from "effect-view"
import { runtime } from "./runtime"

const CounterValueView = Component.make("CounterValue")(
  function* ({ count }: { readonly count: Lens.Lens<number> }) {
    yield* Component.useOnMount(() =>
      Effect.addFinalizer(() =>
        Effect.log("CounterValue unmounted"),
      ),
    )

    const [value, setValue] = yield* Lens.useState(count)

    return (
      <button onClick={() => setValue((n) => n + 1)}>
        Count: {value}
      </button>
    )
  },
)

const CounterView = Component.make("Counter")(function* () {
  const count = yield* Component.useOnMount(() =>
    Effect.map(
      SubscriptionRef.make(0),
      Lens.fromSubscriptionRef,
    ),
  )

  const CounterValue = yield* CounterValueView.use

  return <CounterValue count={count} />
})

export const Counter = CounterView.pipe(
  Component.withContext(runtime.context),
)

CounterView composes another Effect View component by yielding its .use Effect, then renders the resulting component as ordinary JSX. The child can access the current Effect context and receives its own component scope.

Effect.addFinalizer uses the scope already provided to the component body, so the finalizer above runs when CounterValue unmounts.

At the outer boundary, Counter is still a normal React component and its Effect requirements remain typed until they reach the runtime.

Build the runtime and render your first component →

Why Effect View

| | Capability | What it gives you | | --- | --- | --- | | Effect components | Component.make | Yield Effects and typed services directly, then return JSX. | | Managed lifecycles | Scope.Scope | Finalizers, fibers, subscriptions, and resources close with their component or dependency lifecycle. | | One application runtime | ReactRuntime | Build your Layer once and make its services available throughout the UI. | | Reactive state | Lens and View | Focus large state models into small writable values and subscribe only where React needs them. | | Server state | Query and Mutation | TanStack Query-style caching, invalidation, staleness, and mutations with typed Effects underneath. | | Schema-driven forms | MutationForm and LensForm | Keep input-friendly encoded values while application code receives validated, decoded types. | | Async rendering | Async and Memoized | Integrate asynchronous Effects with Suspense while retaining Effect errors and cancellation. |

Designed for both ecosystems

Effect View does not hide Effect behind callbacks or recreate React around a new rendering model. React still owns rendering, JSX, hooks, Suspense, and events. Effect owns services, errors, resource safety, concurrency, streams, and schemas. Effect View provides the lifecycle-aware boundary between them.

Documentation

The complete documentation is available at thila.dev/effect-view.

Requirements

  • React 19.2 or newer
  • Effect v4 RC (effect@rc)
  • TypeScript and @types/react for TypeScript projects

Effect View is renderer-independent and does not require react-dom.

Project status

Effect View is currently beta software. The main APIs are available, but breaking changes and rough edges are still possible before a stable release.

Issues, ideas, and contributions are welcome on GitHub.

License

MIT