diff --git a/CHANGELOG.md b/CHANGELOG.md
index 19dc726..ba02b98 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,22 +3,7 @@ All notable changes to this project will be documented in this file. This change
 
 ## [Unreleased]
 ### Changed
-- Add a new arity to `make-widget-async` to provide a different widget shape.
+- Document public API [#28](https://github.com/phronmophobic/membrane.term/issues/28)
 
-## [0.1.1] - 2021-10-21
-### Changed
-- Documentation on how to make the widgets.
-
-### Removed
-- `make-widget-sync` - we're all async, all the time.
-
-### Fixed
-- Fixed widget maker to keep working when daylight savings switches over.
-
-## 0.1.0 - 2021-10-21
-### Added
-- Files from the new template.
-- Widget maker public API - `make-widget-sync`.
-
-[Unreleased]: https://github.com/com.phronemophobic.membrane/term/compare/0.1.1...HEAD
-[0.1.1]: https://github.com/com.phronemophobic.membrane/term/compare/0.1.0...0.1.1
+## [0.9.0] - 2021-11-30
+- Initial release to clojars
diff --git a/README.md b/README.md
index 05890fe..ef3e743 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,9 @@
 # membrane.term
 
+[![cljdoc](https://cljdoc.org/badge/com.phronemophobic/membrane.term)](https://cljdoc.org/d/com.phronemophobic/membrane.term)
+[![clojurians slack](https://img.shields.io/badge/slack-join_chat-brightgreen.svg)](https://clojurians.slack.com/archives/C02KE09HMHV)
+[![clojars](https://img.shields.io/clojars/v/com.phronemophobic/membrane.term.svg)](https://clojars.org/com.phronemophobic/membrane.term)
+
 A simple terminal emulator in clojure.
 
 ## Rationale
@@ -12,6 +16,11 @@ Some reasons to use **membrane.term**:
 - If you'd like to embed a terminal somewhere. There's not really a guide for embedding, but if you file an issue, I can provide some tips
 - If you'd like to capture terminal screenshots for documentation
 
+## Status
+
+Pre 1.0 release.
+APIs and behavior are subject to change.
+
 ## Installation
 
 Membrane.term works on macOS and Linux operating systems.
diff --git a/doc/cljdoc.edn b/doc/cljdoc.edn
new file mode 100644
index 0000000..0138519
--- /dev/null
+++ b/doc/cljdoc.edn
@@ -0,0 +1,3 @@
+{:cljdoc.doc/tree [["Readme" {:file "README.md"}]
+                   ["Changelog" {:file "CHANGELOG.md"}]
+                   ["Developer Notes" {:file "doc/dev.md"}]]}
diff --git a/src/com/phronemophobic/membrane/term.clj b/src/com/phronemophobic/membrane/term.clj
index 13f5a9c..135ad95 100644
--- a/src/com/phronemophobic/membrane/term.clj
+++ b/src/com/phronemophobic/membrane/term.clj
@@ -7,18 +7,18 @@
   (:import [com.pty4j PtyProcess WinSize]))
 
 
-(defn start-pty []
+(defn- start-pty []
   (let [cmd (into-array String ["/bin/bash" "-l"])
         pty (PtyProcess/exec ^"[Ljava.lang.String;" cmd
                              ^java.util.Map (merge (into {} (System/getenv))
                                                    {"TERM" "xterm-256color"}))]
     pty))
 
-(def blank-cell [32 {}])
-(defn blank-cell? [cell]
+(def ^:private blank-cell [32 {}])
+(defn- blank-cell? [cell]
   (= cell blank-cell))
 
-(defn vt-color->term-color
+(defn- vt-color->term-color
   [color-scheme vt-color]
   (if (vector? vt-color)
     (let [[r g b] vt-color]
@@ -101,7 +101,7 @@
                                           :italic
                                           :upright)))))
 
-(defn term-line [color-scheme {:keys [:membrane.term/cell-width :membrane.term/cell-height] :as font} line]
+(defn- term-line [color-scheme {:keys [:membrane.term/cell-width :membrane.term/cell-height] :as font} line]
   (into []
         (comp
          (map-indexed vector)
@@ -125,10 +125,10 @@
                  foreground))))))
         line))
 
-(def term-line-memo (memoize term-line))
-(def window-padding-height 8)
+(def ^:private term-line-memo (memoize term-line))
+(def ^:private window-padding-height 8)
 
-(defn term-view [color-scheme {:keys [:membrane.term/cell-width :membrane.term/cell-height] :as font} vt]
+(defn- term-view [color-scheme {:keys [:membrane.term/cell-width :membrane.term/cell-height] :as font} vt]
   (let [screen (:screen vt)
         cursor (let [{:keys [x y visible]} (:cursor screen)]
                  (when visible
@@ -153,14 +153,14 @@
                  (-> vt :screen :lines))
            cursor))))
 
-(defn writec-bytes [out bytes]
+(defn- writec-bytes [out bytes]
   (.write ^java.io.OutputStream out (byte-array bytes)))
 
-(defn send-input [pty s]
+(defn- send-input [pty s]
   (let [out (.getOutputStream ^PtyProcess pty)]
     (writec-bytes out (.getBytes ^String s))))
 
-(def meta-shift-map
+(def ^:private meta-shift-map
   {
    \` \~
    \1 \!
@@ -187,7 +187,7 @@
    \. \>
    \/ \?})
 
-(defn term-events [pty view]
+(defn- term-events [pty view]
   (let [out (.getOutputStream ^PtyProcess pty)]
     (ui/on
      :key-event
@@ -278,7 +278,7 @@
        nil)
      view)))
 
-(defn run-pty-process [width height term-state]
+(defn- run-pty-process [width height term-state]
   (let [^PtyProcess
         pty (doto ^PtyProcess (start-pty)
               (.setWinSize (WinSize. width height)))]
@@ -313,12 +313,11 @@
                                 :cell-height (tk/font-line-height toolkit term-font)
                                 :descent-gap (- descent-offset baseline-offset)})))))
 
-(defn load-default-toolkit []
+(defn- load-default-toolkit []
   @(requiring-resolve 'membrane.java2d/toolkit))
 
 (def default-color-scheme
-  "Colors are specified a per membrane convention:
-   vectors of [red green blue] or [red green blue alpha] with values from 0 - 1 inclusive"
+  "Default color-scheme used in [[default-run-term-opts]] and [[default-screenshot-opts]]"
   {:white           [1     1     1]
    :black           [0     0     0]
    :red             [0.76  0.21  0.13]
@@ -340,67 +339,135 @@
    :background      [1     1     1]
    :foreground      [0     0     0]})
 
-(def default-common-opts {:width 90
-                          :height 30
-                          :font-family :monospace
-                          :font-size 12
-                          :toolkit nil
-                          :color-scheme default-color-scheme})
+(def ^:private default-common-opts {:width 90
+                                    :height 30
+                                    :font-family :monospace
+                                    :font-size 12
+                                    :toolkit nil
+                                    :color-scheme default-color-scheme})
+
+(def default-run-term-opts "Default options used for [[run-term]]" default-common-opts)
 
 (defn run-term
+  "Launch an interactive membrane.term terminal. Terminal exits when explicitly closed by user.
+
+  Accepts optional `opts` map:
+  - `:width`           Window width in characters (default: `90`)
+  - `:height`          Window height in characters (default: `30`)
+  - `:color-scheme`  Map for terminal colors (defaults to an internal scheme)
+     Colors are specified per membrane convention, vectors of `[red green blue]` or
+     `[red green blue alpha]` with values from `0` - `1` inclusive. Example: `[0.14  0.74  0.14 0.50]`.
+     A color value must be specified for all of:
+     - ANSI colors
+       - `:white` `:black` `:red` `:green` `:yellow` `:blue` `:magenta` `cyan`
+       - `:bright-white` `:bright-black` `:bright-red` `:bright-green` `:bright-yellow` `:bright-blue` `:bright-magenta` `:bright-cyan`
+     - `:cursor` - Background color for cursor
+     - `:cursor-text` - Foreground color for cursor text
+     - `:background` - Default background color
+     - `:foreground` - Default text color
+  - `:font-family`     OS installed font family name. Example: `\"Courier New\"`.
+     Use `:monospace` for default monospace (default: `:monospace`)
+  - `:font-size`       Font point size (default: `12`)
+  - `:toolkit`         Graphics toolkit (default: `membrane.toolkit/java2d`)
+    - An object that must satisfy the following
+      [`membrane.toolkit`](https://github.com/phronmophobic/membrane/blob/master/src/membrane/toolkit.clj) interfaces:
+      - `IToolkit`
+      - `IToolkitLogicalFontFontFamily`
+      - `IToolkitFontExists`
+      - `IToolkitFontMetrics`
+      - `IToolkitFontAdvanceX`
+      - `IToolkitFontLineHeight`
+      - `IToolkitRunSync`
+    - Usable examples from membrane library: `membrane.java2d/toolkit`, `membrane.skia/toolkit`"
   ([]
    (run-term {}))
-  ([opts]
-   (let [opts (merge default-common-opts opts)
+  ([{:keys [width height color-scheme font-family font-size toolkit] :as opts}]
+   (let [opts (merge default-run-term-opts opts)
          {:keys [width height color-scheme font-family font-size toolkit]} opts
          term-state (atom {:vt (vt/make-vt width height)})
          toolkit (if toolkit
                    toolkit
                    (load-default-toolkit))
          font (load-terminal-font toolkit font-family font-size)]
-        (swap! term-state assoc
-               :pty (run-pty-process width height term-state))
-        (tk/run-sync
-         toolkit
-         (fn []
-           (let [{:keys [pty vt]} @term-state]
-             (term-events pty
-                          (term-view color-scheme font vt))))
-         {:window-title "membrane.term"
-          :window-start-width (* width (:membrane.term/cell-width font))
-          :window-start-height (+ window-padding-height (* height (:membrane.term/cell-height font)))})
-
-        (let [^PtyProcess pty (:pty @term-state)]
-          (.close (.getInputStream pty))
-          (.close (.getOutputStream pty))))))
-
-(defn screenshot
-  ([opts]
-   (let [opts (merge default-common-opts
-                     {:line-delay 1e3
-                      :final-delay 10e3
-                      :out "terminal.png"}
-                     opts)
-         {:keys [play width height out line-delay final-delay color-scheme font-family font-size toolkit]} opts
-         term-state (atom {:vt (vt/make-vt width height)})
-         toolkit (if toolkit
-                   toolkit
-                   (load-default-toolkit))
-         font (load-terminal-font toolkit font-family font-size)]
      (swap! term-state assoc
             :pty (run-pty-process width height term-state))
-     (doseq [line (string/split-lines (slurp play))]
-       (send-input (:pty @term-state) line)
-       (send-input (:pty @term-state) "\n")
-       (Thread/sleep line-delay))
-
-     (Thread/sleep final-delay)
-     (tk/save-image toolkit
-                    out
-                    (ui/fill-bordered (:background color-scheme) 5
-                                      (term-view color-scheme font (:vt @term-state))))
-     (println (str "Wrote screenshot to " out "."))
+     (tk/run-sync
+      toolkit
+      (fn []
+        (let [{:keys [pty vt]} @term-state]
+          (term-events pty
+                       (term-view color-scheme font vt))))
+      {:window-title "membrane.term"
+       :window-start-width (* width (:membrane.term/cell-width font))
+       :window-start-height (+ window-padding-height (* height (:membrane.term/cell-height font)))})
 
      (let [^PtyProcess pty (:pty @term-state)]
        (.close (.getInputStream pty))
        (.close (.getOutputStream pty))))))
+
+(def default-screenshot-opts "Default options used for [[screenshot]]" (merge default-common-opts {:line-delay 1e3
+                                                                                                   :final-delay 10e3
+                                                                                                   :out "terminal.png"}))
+
+(defn screenshot
+  "Take a screenshot after playing a script line by line in a membrane.term terminal.
+  Terminal is not displayed and automatically exits after screenshot is written.
+
+  Requires `opts` map:
+  - `:play`          Path to script to play in terminal (**required**)
+  - `:out`           Filename for screenshot image (default: `\"terminal.png\"`)
+  - `:line-delay`    Delay in milliseconds to wait after each line in `:play` script is sent to terminal (default: `1000`)
+  - `:final-delay`   Delay in milliseconds to wait after all lines in `:play` script are sent to terminal (default: `10000`)
+  - `:width`         Window width in characters (default: `90`)
+  - `:height`        Window height in characters (default: `30`)
+  - `:color-scheme`  Map for terminal colors (defaults to an internal scheme)
+     Colors are specified per membrane convention, vectors of `[red green blue]` or
+     `[red green blue alpha]` with values from `0` - `1` inclusive. Example: `[0.14  0.74  0.14 0.50]`.
+     A color value must be specified for all of:
+     - ANSI colors
+       - `:white` `:black` `:red` `:green` `:yellow` `:blue` `:magenta` `cyan`
+       - `:bright-white` `:bright-black` `:bright-red` `:bright-green` `:bright-yellow` `:bright-blue` `:bright-magenta` `:bright-cyan`
+     - `:cursor` - Background color for cursor
+     - `:cursor-text` - Foreground color for cursor text
+     - `:background` - Default background color
+     - `:foreground` - Default text color
+  - `:font-family`   OS installed font family name. Example: `\"Courier New\"`.
+     Use `:monospace` for default monospace (default: `:monospace`)
+  - `:font-size`     Font point size (default: `12`)
+  - `:toolkit`       Graphics toolkit (default: `membrane.toolkit/java2d`)
+    - An object that must satisfy the following
+      [`membrane.toolkit`](https://github.com/phronmophobic/membrane/blob/master/src/membrane/toolkit.clj) interfaces:
+      - `IToolkit`
+      - `IToolkitLogicalFontFontFamily`
+      - `IToolkitFontExists`
+      - `IToolkitFontMetrics`
+      - `IToolkitFontAdvanceX`
+      - `IToolkitFontLineHeight`
+      - `IToolkitRunSync`
+      - `IToolkitSaveImage`
+    - Usable examples from membrane library: `membrane.java2d/toolkit`, `membrane.skia/toolkit`"
+  [{:keys [play out line-delay final-delay width height color-scheme font-family font-size toolkit] :as opts}]
+  (let [opts (merge default-screenshot-opts opts)
+        {:keys [play width height out line-delay final-delay color-scheme font-family font-size toolkit]} opts
+        term-state (atom {:vt (vt/make-vt width height)})
+        toolkit (if toolkit
+                  toolkit
+                  (load-default-toolkit))
+        font (load-terminal-font toolkit font-family font-size)]
+    (swap! term-state assoc
+           :pty (run-pty-process width height term-state))
+    (doseq [line (string/split-lines (slurp play))]
+      (send-input (:pty @term-state) line)
+      (send-input (:pty @term-state) "\n")
+      (Thread/sleep line-delay))
+
+    (Thread/sleep final-delay)
+    (tk/save-image toolkit
+                   out
+                   (ui/fill-bordered (:background color-scheme) 5
+                                     (term-view color-scheme font (:vt @term-state))))
+    (println (str "Wrote screenshot to " out "."))
+
+    (let [^PtyProcess pty (:pty @term-state)]
+      (.close (.getInputStream pty))
+      (.close (.getOutputStream pty)))))
diff --git a/src/com/phronemophobic/membrane/term/color_scheme.clj b/src/com/phronemophobic/membrane/term/color_scheme.clj
index d505e38..175980d 100644
--- a/src/com/phronemophobic/membrane/term/color_scheme.clj
+++ b/src/com/phronemophobic/membrane/term/color_scheme.clj
@@ -1,4 +1,4 @@
-(ns com.phronemophobic.membrane.term.color-scheme
+(ns ^:no-doc com.phronemophobic.membrane.term.color-scheme
   (:require [clojure.data.xml :as xml]
             [clojure.data.zip.xml :as zxml]
             [clojure.set :as cset]
diff --git a/src/com/phronemophobic/membrane/term/main.clj b/src/com/phronemophobic/membrane/term/main.clj
index 9358779..7ff4a01 100644
--- a/src/com/phronemophobic/membrane/term/main.clj
+++ b/src/com/phronemophobic/membrane/term/main.clj
@@ -1,4 +1,4 @@
-(ns com.phronemophobic.membrane.term.main
+(ns ^:no-doc com.phronemophobic.membrane.term.main
   (:require [clojure.java.io :as io]
             [clojure.string :as string]
             [com.phronemophobic.membrane.term :as term]
@@ -37,9 +37,6 @@ Replace membrane.term with your appropriate Clojure tools CLI launch sequence. F
 | clojure -M:membrane.term run-term -w 133 -h 60
 |")
 
-(defn- parse-string [v]
-  (str v))
-
 (defn parse-font-family [v]
   (if (= "monospace" v)
     :monospace