diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,22 @@
 
 See full history at: <https://github.com/faylang/fay/commits>
 
+### 0.21.1 (2014-10-21)
+
+* Lots of additions to in `fay-base` adding the following modules:
+  * Data.Var - Mutable variables, Reactive variables, and reactive signals
+  * Unsafe.Coerce
+  * Data.Text (fay-text will be updated to reuse this module)
+  * Data.Time
+  * Data.Ord, Data.Function, Data.Maybe, Data.List, Data.Either
+  * Data.Defined and Data.Nullable
+  * Data.Mutex - Simple mutexes
+  * Control.Exception
+  * Data.LocalStorage
+  * Data.MutMap - Mutable maps
+
+The introduction of `Data.Var` required some additions to fay's runtime.
+
 #### 0.21.0.2 (2014-10-19)
 
 * Fallback to ghc and ghc-pkg in PATH if not available from GHC.Paths
diff --git a/fay.cabal b/fay.cabal
--- a/fay.cabal
+++ b/fay.cabal
@@ -1,5 +1,5 @@
 name:                fay
-version:             0.21.0.2
+version:             0.21.1
 synopsis:            A compiler for Fay, a Haskell subset that compiles to JavaScript.
 description:         Fay is a proper subset of Haskell which is type-checked
                      with GHC, and compiled to JavaScript. It is lazy, pure, has a Fay monad,
diff --git a/js/runtime.js b/js/runtime.js
--- a/js/runtime.js
+++ b/js/runtime.js
@@ -746,5 +746,73 @@
 }
 
 /*******************************************************************************
+ * Data.Var
+ */
+
+function Fay$$Ref2(val){
+  this.val = val;
+}
+
+function Fay$$Sig(){
+  this.handlers = [];
+}
+
+function Fay$$Var(val){
+  this.val = val;
+  this.handlers = [];
+}
+
+// Helper used by Fay$$setValue and for merging
+function Fay$$broadcastInternal(self, val, force){
+  var handlers = self.handlers;
+  var exceptions = [];
+  for(var len = handlers.length, i = 0; i < len; i++) {
+    try {
+      force(handlers[i][1](val), true);
+    } catch (e) {
+      exceptions.push(e);
+    }
+  }
+  // Rethrow the encountered exceptions.
+  if (exceptions.length > 0) {
+    console.error("Encountered " + exceptions.length + " exception(s) while broadcasing a change to ", self);
+    for(var len = exceptions.length, i = 0; i < len; i++) {
+      (function(exception) {
+        window.setTimeout(function() { throw exception; }, 0);
+      })(exceptions[i]);
+    }
+  }
+}
+
+function Fay$$setValue(self, val, force){
+  if (self instanceof Fay$$Ref2) {
+    self.val = val;
+  } else if (self instanceof Fay$$Var) {
+    self.val = val;
+    Fay$$broadcastInternal(self, val, force);
+  } else if (self instanceof Fay$$Sig) {
+    Fay$$broadcastInternal(self, val, force);
+  } else {
+    throw "Fay$$setValue given something that's not a Ref2, Var, or Sig"
+  }
+}
+
+function Fay$$subscribe(self, f){
+  var key = {};
+  self.handlers.push([key,f]);
+  var searchStart = self.handlers.length - 1;
+  return function(_){
+    for(var i = Math.min(searchStart, self.handlers.length - 1); i >= 0; i--) {
+      if(self.handlers[i][0] == key) {
+        self.handlers = self.handlers.slice(0,i).concat(self.handlers.slice(i+1));
+        return;
+      }
+    }
+    return _; // This variable has to be used, otherwise Closure
+              // strips it out and Fay serialization breaks.
+  };
+}
+
+/*******************************************************************************
  * Application code.
  */
diff --git a/tests/AllBaseModules.hs b/tests/AllBaseModules.hs
new file mode 100644
--- /dev/null
+++ b/tests/AllBaseModules.hs
@@ -0,0 +1,28 @@
+module AllBaseModules where
+
+import Control.Exception ()
+import Data.Char ()
+import Data.Data ()
+import Data.Defined ()
+import Data.Either ()
+import Data.Function ()
+import Data.List ()
+import Data.LocalStorage ()
+import Data.Maybe ()
+import Data.MutMap ()
+import Data.MutMap.Internal ()
+import Data.Mutex ()
+import Data.Nullable ()
+import Data.Ord ()
+import Data.Ratio ()
+import Data.Text ()
+import Data.Time ()
+import Data.Var ()
+import Debug.Trace ()
+import FFI
+import Fay.Unsafe ()
+import Prelude
+import Unsafe.Coerce ()
+
+main :: Fay ()
+main = putStrLn "ok"
diff --git a/tests/AllBaseModules.res b/tests/AllBaseModules.res
new file mode 100644
--- /dev/null
+++ b/tests/AllBaseModules.res
@@ -0,0 +1,1 @@
+ok
diff --git a/tests/Var.hs b/tests/Var.hs
new file mode 100644
--- /dev/null
+++ b/tests/Var.hs
@@ -0,0 +1,24 @@
+-- | Tests for the var types.
+
+module Var where
+
+import Data.Var
+
+main =
+  do v <- newVar (0 :: Int)
+     subscribe v
+               (\v ->
+                  putStrLn ("v changed: " ++ show v))
+     set v 4
+     modify v (+ 5)
+     s <- newSig
+     subscribe s
+               (\v ->
+                  putStrLn ("s signalled: " ++ show v))
+     set s (567 :: Int)
+     r <- newRef (123 :: Int)
+     v <- get r
+     putStrLn ("ref: " ++ show v)
+     set r (666 :: Int)
+     v <- get r
+     putStrLn ("ref(2): " ++ show v)
diff --git a/tests/Var.res b/tests/Var.res
new file mode 100644
--- /dev/null
+++ b/tests/Var.res
@@ -0,0 +1,5 @@
+v changed: 4
+v changed: 9
+s signalled: 567
+ref: 123
+ref(2): 666
