diff --git a/build.sbt b/build.sbt
new file mode 100644
index 0000000..0153d1d
--- /dev/null
+++ b/build.sbt
@@ -0,0 +1,16 @@
+enablePlugins(ScalaJSPlugin)
+
+name := "Scala.js Tutorial"
+scalaVersion := "3.3.3"
+
+// This is an application with a main method
+scalaJSUseMainModuleInitializer := true
+
+libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "2.8.0"
+
+// Add support for the DOM in `run` and `test`
+jsEnv := new org.scalajs.jsenv.jsdomnodejs.JSDOMNodeJSEnv()
+
+// uTest settings
+libraryDependencies += "com.lihaoyi" %%% "utest" % "0.8.2" % "test"
+testFrameworks += new TestFramework("utest.runner.Framework")
diff --git a/project/build.properties b/project/build.properties
new file mode 100644
index 0000000..04267b1
--- /dev/null
+++ b/project/build.properties
@@ -0,0 +1 @@
+sbt.version=1.9.9
diff --git a/project/plugins.sbt b/project/plugins.sbt
new file mode 100644
index 0000000..6df9fb3
--- /dev/null
+++ b/project/plugins.sbt
@@ -0,0 +1,3 @@
+addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.16.0")
+
+libraryDependencies += "org.scala-js" %% "scalajs-env-jsdom-nodejs" % "1.1.0"
diff --git a/scalajs-tutorial-fastopt.html b/scalajs-tutorial-fastopt.html
new file mode 100644
index 0000000..b28d999
--- /dev/null
+++ b/scalajs-tutorial-fastopt.html
@@ -0,0 +1,11 @@
+
+
+
+
+ The Scala.js Tutorial
+
+
+
+
+
+
diff --git a/scalajs-tutorial.html b/scalajs-tutorial.html
new file mode 100644
index 0000000..90f0879
--- /dev/null
+++ b/scalajs-tutorial.html
@@ -0,0 +1,11 @@
+
+
+
+
+ The Scala.js Tutorial
+
+
+
+
+
+
diff --git a/src/main/scala/tutorial/webapp/TutorialApp.scala b/src/main/scala/tutorial/webapp/TutorialApp.scala
new file mode 100644
index 0000000..ac34cfd
--- /dev/null
+++ b/src/main/scala/tutorial/webapp/TutorialApp.scala
@@ -0,0 +1,33 @@
+package tutorial.webapp
+
+import org.scalajs.dom
+import org.scalajs.dom.document
+
+object TutorialApp {
+ def main(args: Array[String]): Unit = {
+ document.addEventListener("DOMContentLoaded", { (e: dom.Event) =>
+ setupUI()
+ })
+ }
+
+ def setupUI(): Unit = {
+ val button = document.createElement("button")
+ button.textContent = "Click me!"
+ button.addEventListener("click", { (e: dom.MouseEvent) =>
+ addClickedMessage()
+ })
+ document.body.appendChild(button)
+
+ appendPar(document.body, "Hello World")
+ }
+
+ def appendPar(targetNode: dom.Node, text: String): Unit = {
+ val parNode = document.createElement("p")
+ parNode.textContent = text
+ targetNode.appendChild(parNode)
+ }
+
+ def addClickedMessage(): Unit = {
+ appendPar(document.body, "You clicked the button!")
+ }
+}
diff --git a/src/test/scala/tutorial/webapp/TutorialTest.scala b/src/test/scala/tutorial/webapp/TutorialTest.scala
new file mode 100644
index 0000000..47503fc
--- /dev/null
+++ b/src/test/scala/tutorial/webapp/TutorialTest.scala
@@ -0,0 +1,35 @@
+package tutorial.webapp
+
+import utest._
+
+import scala.scalajs.js
+
+import org.scalajs.dom
+import org.scalajs.dom.document
+import org.scalajs.dom.ext._
+
+object TutorialTest extends TestSuite {
+
+ // Initialize App
+ TutorialApp.setupUI()
+
+ def tests = Tests {
+ test("HelloWorld") {
+ assert(document.querySelectorAll("p").count(_.textContent == "Hello World") == 1)
+ }
+
+ test("ButtonClick") {
+ def messageCount =
+ document.querySelectorAll("p").count(_.textContent == "You clicked the button!")
+
+ val button = document.querySelector("button").asInstanceOf[dom.html.Button]
+ assert(button != null && button.textContent == "Click me!")
+ assert(messageCount == 0)
+
+ for (c <- 1 to 5) {
+ button.click()
+ assert(messageCount == c)
+ }
+ }
+ }
+}