diff --git a/README.md b/README.md
index d113879..6cfc0aa 100644
--- a/README.md
+++ b/README.md
@@ -3,3 +3,273 @@ Rebel
#### _Vive la_ REPL!
Build applications that use the Scala REPL as a user interface.
+--------------------------------------------------------------------------------
+
+The Scala REPL is a great tool. We can use it to run random code, test out
+theories, and other quick Scala tasks. We can even run scripts in the REPL to
+set up more complex code. The REPL can also be used as the command line user
+interface for applications. Anyone who has used sbt has used a customized Scala
+REPL. Wouldn't it be nice if we could leverage this powerful tool and the
+powerful Scala language for our user interfaces?
+
+Using the Scala REPL in this way is not well documented, but it is able to be
+incorporated into your Scala code. This library, rebel, is intended to expose
+parts of the REPL in an easy to access place so that you too can utilize the
+REPL for powerful user interfaces.
+
+## Usage
+[![Badge-SonatypeReleases]][Link-SonatypeReleases]
+
+Add the dependency to your product:
+
+- sbt
+ ```scala
+ libraryDependencies += "com.potenciasoftware" %% "rebel" % "[[version]]"
+ ```
+- Maven
+ ```xml
+
+ com.potenciasoftware
+ rebel_2.13
+ [[version]]
+
+ ```
+
+Extend `BaseRepl` and override its protected members to customize the REPL
+according to your needs. Call `run()` on an instance of your customized REPL
+class to start the REPL.
+
+```scala
+import com.potenciasoftware.rebel.BaseRepl
+
+object Main {
+
+ class MyRepl extends BaseRepl {
+ // Customize the REPL here.
+ }
+
+ def main(args: Array[String]): Unit = {
+ new MyRepl().run()
+ }
+}
+```
+
+## Customization
+
+### updateSettings(settings: Settings): Unit
+
+This allows full access to the compiler settings prior to instantiation of the
+REPL. See `scalac -help` and its more specific variants (e.g. `scalac -X`) for
+details. All of the options described in the help output are available from the
+`Settings` instance that is passed to `updateSettings()`.
+
+Also note, the `Settings` instance is mutable, just set the desired values on
+the properties you want to change.
+
+As an example, the below code will cause the REPL to use VIM keybindings rather
+than Emacs keybindings:
+
+```scala
+class MyRepl extends BaseRepl {
+
+ import scala.tools.nsc.Settings
+
+ override protected def updateSettings(settings: Settings): Unit = {
+ // This corresponds to the -Xjline command line option of the scala command.
+ settings.Xjline.value = "vi"
+ }
+}
+```
+
+Please note that if you leave `Settings.classpath` set to the default value,
+`BaseRepl` will automatically include the full classpath of your running
+application as the classpath of the REPL. This is usually what you want.
+
+### banner: String
+
+By default when the REPL starts up, it prints out a standard banner including
+information about the version of Scala and the JVM running the REPL. Override
+`banner` to customize this startup banner. Including the value of
+`super.banner` will cause the inclusion of the default information.
+
+### prompt: String
prompt_=(newValue: String): Unit
+
+You may want to set the prompt to something other than the default (`scala> `).
+You may also want to change the prompt to indicate some change in state within
+your application. The `prompt` getter and setter members (`def prompt: String`
+and `def prompt_=(String): Unit` may be used for these purposes.
+
+### boundValues: Seq[Parameter]
+
+You may want to bind objects from within your application to values that are
+accessable from the REPL. Override `boundValues` to provide a list of the
+values to bind.
+
+Example:
+```scala
+class ApplicationSettings {
+ var prettyPrintResults: Boolean = false
+}
+
+class MyRepl extends BaseRepl {
+
+ import com.potenciasoftware.rebel.BaseRepl.Parameter
+
+ val settings = new ApplicationSettings
+
+ override protected val boundValues: Seq[Parameter] =
+ Seq(Parameter[ApplicationSettings](
+ name = "settings",
+ value = settings))
+}
+```
+
+### startupScript: String
+
+Often you want to run a set of commands whenever your REPL starts. For instance
+you may want to automatically run imports so that the contents of your packages
+will be immediately available to the REPL user.
+
+Example:
+```scala
+class MyRepl extends BaseRepl {
+ override protected val startupScript: String =
+ """
+ |import com.example.Utils._
+ |import com.example.Implicits._
+ |""".stripMargin
+}
+```
+
+### executionWrapper: ExecutionWrapper
+
+Every command entered into the REPL is turned into a larger piece of Scala code
+that is then compiled and executed. An execution wrapper is a method that takes
+`=> Any` and returns `String` which gives you the ability to participate in the
+generation of that code.
+
+When an execution wrapper method is set on the REPL interpreter, each command
+entered into the REPL will be wrapped with a call to that method effectively
+passing each command to the method's `=> Any` parameter and returning the
+`String` that the method returns.
+
+The execution wrapper method must be able to be statically referenced (i.e.
+from a static global value or a public object) because the fully qualified path
+to the execution wrapper method is provided as part of the code that the REPL
+compiles and executes.
+
+The trait `ExecutionWrapper` provides a place to define this fully qualified
+path, `def code: String`. A typical use of the trait would be to:
+
+ 1. Extend `ExecutionWrapper` on a public object.
+ 2. Define the execution wrapper method as part of that object.
+ 3. Override `def code: String` on the object with the fully qualified path to
+ the method from step 2.
+ 4. Override `val executionWrapper: ExecutionWrapper` on your REPL class to
+ return the object.
+
+```scala
+package com.example
+
+import com.potenciasoftware.rebel.executionWrapper.ExecutionWrapper
+
+object Main {
+
+ object MyExecutionWrapper extends ExecutionWrapper {
+
+ def execute(a: => Any): String = {
+ // do something before each command
+ val result = a
+ // do something after each command
+ result.toString
+ }
+
+ override def code: String =
+ "com.example.Main.MyExecutionWrapper.execute"
+ }
+
+ class MyRepl extends BaseRepl {
+ override val executionWrapper: ExecutionWrapper = MyExecutionWrapper
+ }
+
+ def main(args: Array[String]): Unit = {
+ new MyRepl().run()
+ }
+}
+```
+
+Included in this library is an `ExecutionWrapper` implementation,
+`ExecuteInFiber`, which executes each command in a ZIO fiber which can be
+interrupted with the INT signal (Ctrl-C). When this `ExecutionWrapper` is
+installed, the user may cancel a long running (or hung) command with Ctrl-C
+without causing the REPL to exit as it normally would.
+
+```scala
+import com.potenciasoftware.rebel.executionWrapper.ExecuteInFiber
+
+object MyExecutionWrapper extends ExecuteInFiber
+
+object Main {
+
+ class MyRepl extends BaseRepl {
+ override val executionWrapper: ExecutionWrapper = MyExecutionWrapper
+ }
+
+ def main(args: Array[String]): Unit = {
+ new MyRepl().run()
+ }
+}
+```
+
+Note: If you need to debug your execution wrapper method, one thing that can be
+helpful is to tell the REPL to output the code that will be compiled by
+appending `// show` at the end of your command like this:
+
+```
+scala> 1 + 1 // show
+```
+
+### customCommands: Seq[LoopCommand]
+
+The REPL provides commands like `:load` and `:type` out of the box. This method
+may be used to provide additional commands.
+
+Example:
+```scala
+class MyRepl extends BaseRepl {
+
+ import com.potenciasoftware.rebel.BaseRepl.LoopCommand
+
+ override protected val customCommands: Seq[LoopCommand] =
+ Seq(LoopCommand(
+ name = "answer",
+ usage = "[question]",
+ help = "Gives the answer to any question you have regarding " +
+ "Life, the Universe, and Everything.",
+ f = input => {
+ println("42")
+ LoopCommand.Result(true, None)
+ }))
+}
+```
+
+### onQuit(): Unit
+
+When a user enters the command `:quit` into the REPL it will exit. Your
+application may want to do some quick clean up before the REPL exits. Override
+the `onQuit()` method for this.
+
+Note: Since users of the REPL expect it to close pretty quickly, `BaseRepl`
+will automatically call `sys.exit()` after 5 seconds has elapsed. Your cleanup
+code needs to be fast enough to finish in that time.
+
+```scala
+class MyRepl extends BaseRepl {
+ override protected def onQuit(): Unit = {
+ println("Goodbye")
+ }
+}
+```
+
+[Link-SonatypeReleases]: https://s01.oss.sonatype.org/content/repositories/releases/com/potenciasoftware/rebel_2.13/
+[Badge-SonatypeReleases]: https://img.shields.io/nexus/r/https/s01.oss.sonatype.org/com.potenciasoftware/rebel_2.13.svg "Sonatype Releases"