There are three parts to this:
- 
sbt-scala-relay- Adds sbt tasks to run the relay-compiler and generate Scala.js facades (relayCompilerandrelayConvert).addSbtPlugin("com.goodcover.relay" % "sbt-scala-relay" % "<version>") 
- 
scala-relay-core- Contains the Scala.js equivalent to relay types as well as the@graphqlannotation which allows GraphQL definitions to be defined inline.libraryDependencies += "com.goodcover.relay" %%% "scala-relay-core" % "<version>" ℹ️ This is added automatically by sbt-scala-relay.
- 
scala-relay-macros- Contains thegraphqlGenmacro which is similar to the@graphqlannotation but is able to return the type of the GraphQL definition. This also includes an IntelliJ plugin that makes the types available to the IDE.libraryDependencies += "com.goodcover.relay" %%% "scala-relay-macros" % "<version>" ℹ️ This has to be added manually. 
Add the sbt-scala-relay sbt plugin to project/plugins.sbt:
addSbtPlugin("com.goodcover.relay" % "sbt-scala-relay" % "<version>")Enable the ScalaRelayPlugin on your frontend project:
enablePlugins(ScalaRelayPlugin)Add the path to the schema:
relaySchema := resourceDirectory.value / "graphql" / "schema.graphqls"Optionally specify the command to run relay-compiler and include a dependency on the task that installs it. For
example, if you are using scalajs-bundler add:
relayCompilerCommand := s"node ${(Compile / npmInstallDependencies).value}/node_modules/.bin/relay-compiler"Add the relay dependencies to your node package manager. For scalajs-bundler add:
Compile / npmDevDependencies ++= (Compile / relayDependencies).valueYou will need to configure your bundler so that it is able to resolve @JSImport("__generated__/...") to the
relayCompileDirectory. For example, for webpack you might add:
  "resolve": {
    "modules": [
        "node_modules",
        "../../resource_managed/main"
    ]
  }The first task is relayExtract which processes all the @graphql annotations and graphqlGen macros within your
Scala sources (unmanagedSources) and extracts the GraphQL definitions into their own .graphql file.
The second task is relayWrap which takes all the extracted .graphql files as well as any others from
unmanagedResources and wraps them with the graphql tagged template and outputs them as
.js files (or .ts if relayTypeScript := true). We do this because relay-compiler is rather fussy about where the
executable definitions come from. The only reliable way to get it to work is to have all your executable definitions
come from the same type of file as the target language.
The final two tasks, relayConvert and relayCompile, are the main tasks you will interact with and they each depend
on the output of tasks above, relayExtract and relayWrap, respectively.
relayConvert takes all the GraphQL definitions and generates Scala.js facades for them. These are equivalent to the
TypeScript or Flow types that relay-compiler produces.
relayCompile takes all the GraphQL definitions wrapped with the graphql tagged template and passes those to
relay-compiler. The resulting sources are imported via @JSImport("__generated__/...") annotations from the Scala.js
facades generated by relayConvert.
For an example on multi-project setup, with GraphQL definitions from one project used by another, take a look at the multi-project sbt scripted test.
You need to make relayConvert aware of the GraphQL definition from the dependency by setting:
Compile / relayGraphQLDependencies ++= (dependencyProject / Compile / relayGraphQLFiles).valueℹ️ This will add a task dependency on
dependencyProject / Compile / relayExtract.
Then make relayCompile aware of the unmanaged GraphQL definitions:
Compile / relayInclude ++= {
  val base = relayBaseDirectory.value.toPath
  (dependencyProject / Compile / unmanagedResourceDirectories).value.map { dir =>
    base.relativize(dir.toPath).toString + "/**"
  }
}As well as the extracted ones:
Compile / relayInclude +=
  relayBaseDirectory.value.toPath.relativize((dependencyProject / Compile / relayExtractDirectory).value.toPath).toString + "/**"This does not add a task dependency on dependencyProject / Compile / relayExtract. Although technically only
relayExtra is required, it is more convenient to depend on relayCompile since you will need to run it at some point
before bundling the dependent project:
Compile / relayCompile := ((Compile / relayCompile) dependsOn (dependencyProject / Compile / relayCompile)).valueDo not forget to update your bundler configuration to also include the relayCompileDirectory of the dependency:
  "resolve": {
    "modules": [
        "node_modules",
        "../../resource_managed/main",
        "../../../../../../dependencyProject/target/scala-2.13/resource_managed/main",
    ]
  }ℹ️ You should probably use path.resolve against the base directory but that is an exercise for you to figure out.