EffectWeb 0.8.0 shrinks the API to what applications use, compiles every JSX file, adds four authoring APIs that replace patterns consumers had been writing by hand, and speeds up the renderer.
Breaking changes and migration
- Every file containing JSX is compiled and linted unless a
@jsxImportSourcepragma names another runtime. A view file that imported only sibling components used to be skipped and then fail inside the bundler. TheallJsxcompiler and lint option is removed. classNameis removed; writeclass.renderListis removed; importlist.defineTasks(owner, definitions)is nowownedTasks(owner, definitions);defineTaskskeeps only the component builder form.program,modelOwneranddefineTasksno longer acceptname; it only fed the removed tracing.- Removed from
effectweb/advanced:mapTransition,mapCommand,defineFieldand the field types,observeBindings,inspectBindings,mountBindingInspector,observePrograms,fromStream,fromAtom,fromSubscriptionRef,makeDomMount,makeDomBinding,makeEffectHandler. Pass auiRuntime(context)todomMount,domBindingandeffectEventfor services; observe streams and atoms from a controller that publishes into amodelOwner. - The lint preset reports every rule as an error and adds
effectweb/no-hook-names.
Additions
list(rows, identity, render)keys rows with an inline identity;collection(identity)is for rows that are also shared withshare.controllerView({ create, view, identity })creates a controller from a view's props and disposes it with the view.domHandle()gives a controller an element reference throughuse={handle.mount}andhandle.element().ownedTasks(owner, { save: { run, policy } })binds named actions to an owner's slots.commandSlotsreleases keys nobody references any more, so long-lived applications do not accumulate one slot per entity.- Lint: EW3004 covers
collectionandcommandSlotscreated inside a view; EW3005 flagssequencerows with editable controls or filtered components; EW3006 flags index-derived identity; EW3007 (no-hook-names) flagsuseXnames. EW3003 also catches a slot held in a local and run once.
Renderer
Single-element content keeps no comment markers, event handlers no longer allocate a scope each, attribute reconciliation is a single pass, and teardown under a removed ancestor skips per-node work. On the 1000-row benchmark, mount went from 35.3 to 30.6 ms and removing all rows from 16.8 to 9.9 ms.
Tooling
npm run build:js writes each package to dist.next and renames it into place, so linked consumers never see a half-written dist. Evaluate-only renderer specs run under happy-dom in tests/unit; only browser-dependent behavior stays in Playwright. AUTHORING.md documents the new APIs, the make* naming convention, domMount timing and the no-hooks rule, and every snippet compiles in authoring-guide.typecheck.tsx.
All 15 npm packages share version 0.8.0. The Effect peer remains effect@4.0.0-rc.112. Native compiler packages support glibc Linux x64/arm64, macOS x64/arm64, and Windows x64.
Packaging
The release workflow verified all platforms and published all 15 packages with npm provenance.