---
title: Is effract for you?
description: An honest look at where effract fits, where it doesn't, and what it costs to adopt.
group: Start
order: 4
---

effract is a specific bet: components as Effect programs, state and side effects in services, obligations
checked by the type system. That bet pays off for some teams and is overhead for others. This page is the
honest version — including when to walk away.

## A great fit

effract earns its keep when your app already leans on Effect, or when you'd benefit from what Effect makes
possible in the UI:

- **You already use Effect.** Your services, your error channel, your layers — effract lets a component
  `yield*` them directly, in the render pass. There's no adapter layer and no second way to model effects;
  the runtime the rest of your app uses is the runtime your components read from.
- **You want typed UI obligations.** A component that reads an async service carries its errors and its
  loading state in the type. A missing [`.catch`](/docs/errors/) for a failure `_tag`, or an unhandled
  pending state, is a compile error — not a runtime surprise or a forgotten `if (error)`. The obligations
  the UI owes the user are checked before you ship.
- **You want renderer-free tests.** Because state and logic live in plain Effect services, you test them as
  plain Effect programs — `@effect/vitest` with `TestClock` for timing, no DOM, no render harness, no
  `act()`. The interpreter and the services are unit-tested without mounting anything.
- **You render across SPA, SSR, and RSC from one component.** The same REC body and the same `mount` run
  in the browser, during server rendering, and — resolved up front — as a React Server Component. You write
  the component once and choose where it runs, rather than maintaining server and client variants.

## A fine, incremental fit

You do not rewrite your app to try effract, and you do not convert components wholesale.

Plain React components stay plain. A button, a card, a layout — anything presentational — remains an
ordinary function used as `<Component />` JSX. You never touch it. You reach for `rec(...)` only where a
component actually needs the runtime: it wants an Effect service, or a hook bridged through Effect. Those
components become RECs; everything else stays as it is.

The two compose in one tree. A REC places plain components as normal JSX in its returned markup, and a
plain component renders a REC the same way any island renders. You can adopt effract one component at a
time, in the corner of the app that most wants a service, and leave the rest untouched. If it doesn't earn
its place there, you've changed one file.

## Not yet, and by design

effract is a component-plus-state-in-Effect model. It is deliberately **not** a form library, a router, or
a sync engine, and it doesn't pretend to be. Where another tool is the right answer, use it:

- **Form state.** Reach for [React Hook Form](https://react-hook-form.com/) or
  [TanStack Form](https://tanstack.com/form). Keep the keystroke-level state of a form in a form library,
  where it belongs; when the user submits, hand the validated values to a service and let Effect own what
  happens next. effract does not try to own the input-by-input lifecycle of a form.
- **URL state.** Reach for [nuqs](https://nuqs.dev/). The URL is a first-class store with its own semantics
  (history, shareability, the back button); a dedicated library models it better than a service would.
- **Local-first sync.** A local-first sync engine — offline writes, conflict resolution, replication — is
  not in v1 and isn't on the critical path for what effract is. If that's the core of your product today,
  effract is not the piece that solves it.

None of these are gaps effract is racing to fill. They're boundaries: effract models components and their
state in Effect, and composes cleanly with the libraries that own the rest.

## The onboarding cost, stated plainly

The honest cost is not effract — it's Effect.

Effect v4 is roughly **20 kB** and, more importantly, a real paradigm: generators, services, and layers,
with a genuine learning curve. The generator body — writing a component as `function*` and reading
dependencies with `yield*` — reads as unusual the first few times, even to people comfortable with React.
If your team has never touched Effect, that is the budget item. Plan for a ramp, and consider adopting
effract in one area first (see the incremental path above) rather than across the whole app at once.

effract's own surface, by contrast, is small. The whole API is about **7 kB** min+gzip (a minimal app
~5 kB), and the API you learn is three primitives — `rec`, `hook`, and `mount` — plus the atom toolkit for
reactive state. Once the Effect
mental model clicks, there is very little _effract_ left to learn. So the question is rarely "is effract
worth it" on its own; it's "is Effect worth it for this team, on this app." If the answer is yes, effract is
a thin, well-scoped layer on top. If your team wants nothing to do with generators and services, that's a
fair reason to walk away — and better to know now than three components in.

## Where to next

- [effract vs. the alternatives](/docs/vs-alternatives/) — how it compares to the tools you'd otherwise
  reach for.
- [Getting started](/docs/getting-started/) — install it and write your first REC.
