Skip to main content
@craft-ts
LearnLearn with EffectAI agentsGuideReference
@craft-ts/core@craft-ts/component@craft-ts/dev-tools@craft-ts/effect@craft-ts/style@craft-ts/style-testing@craft-ts/i18n@craft-ts/i18n-effect@craft-ts/mcp
ExamplesMigrationEffect compatibility & maturityAdopting CraftTS progressivelyPress kitRoadmapBacklog
Beta
  • Learn
  • Learn with Effect
  • AI agents
  • Guide
  • Reference
  • Packages
  • Resources

i.Resources

  • Examples
  • Coding agents
  • Migration
  • Renames: _tag and providedIn
  • Effect compatibility & maturity
  • Adopting CraftTS progressively
  • Press kit
  • Roadmap
  • Backlog
  1. Resources
  2. Adopting CraftTS progressively

Adopting CraftTS progressively#

You do not need to rewrite an Effect application before evaluating CraftTS. Keep the domain programs and Layers intact, then introduce Craft at the browser boundary one feature at a time.

Recommended path#

0. Establish the constraints#

Before changing application code, confirm the compatibility matrix. In particular, check the Effect 4 release-candidate requirement, the Node version and whether SSR is a hard requirement.

1. Keep the domain in Effect#

Select one existing operation with a clear type:

ts
Effect<Output, BusinessError, RequiredServices>

Keep its Context.Service, Layer, tagged errors and tests. The first Craft change should be an adapter, not a rewrite of the business logic.

2. Add the Craft boundary#

Install @craft-ts/effect, install the bridge once at bootstrap, and expose the operation through queryEffect, mutationEffect or asyncProcessEffect.

The component should call the domain operation. It should not resolve the repository, call Effect.runPromise, start a fiber from a click handler or duplicate the domain state in a Craft state.

3. Pilot one read-only feature#

Start with a page that has:

  • one query;

  • one application or route Layer;

  • one loading state;

  • one typed business error;

  • one technical error path;

  • one executable test.

This exposes the real cost of the Craft UI model without mixing in forms, optimistic updates or server-function transport.

4. Add writes and forms#

Once the read path is stable, add mutationEffect, then connect it to Craft forms and insertReactOnMutation. Keep validation responsibilities explicit:

  • Effect Schema or methodSchema validates a boundary payload;

  • Craft owns field state, validity and interaction;

  • Effect typed errors represent business rejection;

  • defects remain technical failures.

5. Introduce route and feature scopes#

Move a Layer to the narrowest scope that owns it. Add the compile-time Effect requirements proof for the route, and inline single-use route providers so the typed route collection can preserve them for the type checker.

Do this after the first feature works. The proof is valuable, but introducing it before the boundary is understood makes the first experiment look more complex than it is.

6. Evaluate server functions separately#

Treat the current server-function integration as a separate experiment. Its transport, file conventions, middleware API and deployment integration are not final. Never treat a client Layer as an authentication or authorization boundary; the server must verify claims again.

What can stay and what changes?#

Existing Effect application assetDuring a Craft pilot
Domain types and business operationsKeep
Tagged errors and error unionsKeep; map at the Craft boundary
Context.Service contractsKeep
Live and test LayersKeep; expose through provideLayer
Effect unit testsKeep
Existing UI components and templatesKeep outside the pilot; replace only the selected Craft feature
UI loading, cancellation and rendering stateMove to Craft resources
URL state and form interactionModel with Craft primitives and forms

Go / no-go signals#

Proceed when the pilot has a clear resource boundary, an executable Layer setup and tests that distinguish business errors from defects.

Pause and resolve the issue before expanding when:

  • the project is still on Effect 3 without an isolation plan;

  • SSR is mandatory but no SSR host has been selected;

  • the team cannot explain which side owns a piece of state;

  • every feature requires a custom bridge or manual subscription;

  • typecheck time or type errors make the feedback loop unacceptable.

←Effect compatibility & maturityPress kit→

On this page

  • Recommended path
  • 0. Establish the constraints
  • 1. Keep the domain in Effect
  • 2. Add the Craft boundary
  • 3. Pilot one read-only feature
  • 4. Add writes and forms
  • 5. Introduce route and feature scopes
  • 6. Evaluate server functions separately
  • What can stay and what changes?
  • Go / no-go signals

@craft-ts · MIT licensed

GitHubnpm

Search