This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
crystal is a Scala library that provides a toolbelt for building reactive UI apps in Scala. It
targets Scala 3 and cross-compiles to both the JVM and Scala.js. Publishing (organization,
versioning, Maven Central release) is handled by the sbt-lucuma-lib plugin under the edu.gemini
organization — the com.rpiaggio coordinate in the README badge is outdated. The README has
extensive, authoritative API documentation — read it before changing public APIs.
Core abstractions:
Pot[A]/PotOption[A](modules/core/shared): sum types for delayed/requested values (Pending/Ready/Error, plusReadyNoneforPotOption).ViewF[F, A]and variantsViewOptF/ViewListF(viewF.scala): a value plus an effectful modify callback(A => A) => F[Unit], withzoom(via Monocle optics) to drill into substructure.View[A]is theCallback-fixed alias used by the react layer.Reuse[A](modules/core/js): attaches a hiddenBwith aReusability[B]to a value so that types without a naturalReusability(functions,VdomNode) can participate in reuse.- Throttling:
Throttler,ThrottlingViewF,ViewThrottlerF,Deglitchercoordinate UI vs. server-driven updates. - scalajs-react hooks (
modules/core/js/.../react/hooks): monadic hooks integratingcats-effectIOandfs2.Streamwith scalajs-react (e.g.useSingleEffect,useStreamView,useStreamResource,useEffectStream,useSignalStream). New hooks are added only in their monadic form; builder-style is being phased out.
The library assumes scalajs-react's core-bundle-cb_io bundle (sync effect CallbackTo, async
effect IO).
Three cross-projects (JVM + JS), defined in build.sbt:
core(modules/core): the library.shared/holds platform-agnostic code (Pot,ViewF, throttling);js/holds the scalajs-react integration (react/, hooks,Reuse). There is no meaningfuljvm/-only source — the JS layer is where react lives.testkit(modules/testkit): ScalaCheckArbitrary/Eqinstances for the core types, published for downstream test use. Depends oncore.tests(modules/tests): the test suite (MUnit + discipline law checks). Not published. JS tests run in a JSDOM environment. Depends ontestkit.
The build uses sbt via the bundled sbt-launch.jar and the sbt-lucuma-lib plugin (which derives
versioning, CI config, scalafmt/scalafix config, and publishing). Dependency versions are
centralized in project/Settings.scala. JS tests require npm ci first (provides jsdom, react,
react-dom).
sbt compile # compile all (JVM + JS)
sbt test # run all tests (JVM + JS)
sbt rootJVM/test # only JVM tests
sbt rootJS/test # only JS tests (requires `npm ci` first)
sbt "tests / Test / testOnly crystal.PotSpec" # a single test suite
sbt scalafmtAll # format
sbt scalafmtCheckAll # verify formatting (CI gate)
sbt "scalafixAll OrganizeImports" # organize imports (the configured scalafix rule)Notes:
- Scala 3 only (
3.3.8cross-version inbuild.sbt).maxColumn = 100; vertical alignment is on. - Don't hand-edit
.scalafmt*.conf/.scalafix*.conf— they are generated bysbt-lucuma. - CI (
.github/workflows/ci.yml) sets up Node 24 +npm cionly for therootJSmatrix project. - Both
coreandtestkitare published; treat their public APIs as compatibility-sensitive.