diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,3 +1,18 @@
 [![Hackage](https://img.shields.io/hackage/v/javascript-extras.svg)](https://hackage.haskell.org/package/javascript-extras)
 
 Extra javascript functions when using GHCJS
+
+# Changelog
+
+* 0.4.0.0
+  - Renamed `JSVar` to `JSRep` to avoid confusion with `JSVal`
+  - Renamed `toJS'` to `toJSR`
+  - Renamed `fromJS'` to `fromJSR`
+  - `getProperty` and `setProperty` uses `JE.ToJS a` instead of `Coercible a J.JSVal`
+  - flipped the args of `getProperty` and `setProperty`
+  - Moved `justSnds` to esoteric-extras `Data.Maybe.Esoteric.keepMaybes`
+  - Renamed `safeModularIncrement` to `safeIncrement`
+  - Renamed `safeModularDecrement` to `safeDecrement`
+
+* 0.3.3.0
+  - Added `classNames`, `justSnds`
diff --git a/javascript-extras.cabal b/javascript-extras.cabal
--- a/javascript-extras.cabal
+++ b/javascript-extras.cabal
@@ -1,5 +1,5 @@
 name:                javascript-extras
-version:             0.3.2.0
+version:             0.4.0.0
 synopsis:            Extra javascript functions when using GHCJS
 description:         Extra javascript functions when using GHCJS
 homepage:            https://github.com/louispan/javascript-extras#readme
@@ -20,21 +20,21 @@
                        JavaScript.Extras.Cast
                        JavaScript.Extras.Number
                        JavaScript.Extras.Property
-                       JavaScript.Extras.JSVar
-                       JavaScript.Extras.JSVar.Unsafe
+                       JavaScript.Extras.JSRep
+                       JavaScript.Extras.JSRep.Unsafe
   build-depends:       base >= 4.7 && < 5
-                     , deepseq >= 1.4 && < 2
-                     , parallel >= 3.2 && < 4
-                     , text >= 1.2 && < 1.3
+                     , deepseq >= 1.4
+                     , parallel >= 3.2
+                     , text >= 1.2
   default-language:    Haskell2010
   ghc-options:         -Wall
   if impl(ghcjs)
     build-depends: ghcjs-base
   if !impl(ghcjs)
-    build-depends: ghcjs-base-stub >= 0.1.0.1 && < 1
+    build-depends: ghcjs-base-stub >= 0.1.0.1
 
 executable javascript-extras-test
-  hs-source-dirs:      test/haskell
+  hs-source-dirs:      test/hs
   main-is:             Main.hs
   ghc-options:         -Wall -threaded -rtsopts -with-rtsopts=-N
   cpp-options:         -DGHCJS_BROWSER
@@ -44,9 +44,9 @@
   default-extensions:  ApplicativeDo
   if impl(ghcjs)
     build-depends: ghcjs-base
-                 , ghcjs-prim >= 0.1 && < 0.2
+                 , ghcjs-prim >= 0.1
   if !impl(ghcjs)
-    build-depends: ghcjs-base-stub >= 0.1.0.2 && < 1
+    build-depends: ghcjs-base-stub >= 0.1.0.2
 
 source-repository head
   type:     git
diff --git a/src/JavaScript/Extras.hs b/src/JavaScript/Extras.hs
--- a/src/JavaScript/Extras.hs
+++ b/src/JavaScript/Extras.hs
@@ -1,11 +1,11 @@
 module JavaScript.Extras
     ( module JavaScript.Extras.Cast
-    , module JavaScript.Extras.JSVar
+    , module JavaScript.Extras.JSRep
     , module JavaScript.Extras.Number
     , module JavaScript.Extras.Property
     ) where
 
 import JavaScript.Extras.Cast
-import JavaScript.Extras.JSVar
+import JavaScript.Extras.JSRep
 import JavaScript.Extras.Number
 import JavaScript.Extras.Property
diff --git a/src/JavaScript/Extras/JSRep.hs b/src/JavaScript/Extras/JSRep.hs
new file mode 100644
--- /dev/null
+++ b/src/JavaScript/Extras/JSRep.hs
@@ -0,0 +1,53 @@
+{-# LANGUAGE CPP #-}
+
+module JavaScript.Extras.JSRep where
+
+import Control.DeepSeq
+import Data.Coerce
+import Data.JSString as JS
+import Data.String
+import qualified GHCJS.Marshal.Pure as J
+import qualified GHCJS.Types as J
+import JavaScript.Extras.Cast as JE
+
+-- | Wrapper to have a JSVal that also have an IString instance
+-- This is helpful when using OverloadedStrings
+newtype JSRep = JSRep J.JSVal
+
+instance Show JSRep where
+    show = JS.unpack . js_stringify
+
+instance J.IsJSVal JSRep
+
+instance J.PToJSVal JSRep where
+    pToJSVal = J.jsval
+
+instance JE.ToJS JSRep
+
+instance JE.FromJS JSRep where
+    fromJS v = coerce (fromJS v :: Maybe J.JSVal)
+
+instance IsString JSRep where
+    fromString = JSRep . J.jsval . JS.pack
+
+instance NFData JSRep where
+    rnf (JSRep v) = rnf v
+
+toJSR :: JE.ToJS a => a -> JSRep
+toJSR = JSRep . toJS
+
+fromJSR :: JE.FromJS a => JSRep -> Maybe a
+fromJSR (JSRep v) = fromJS v
+
+#ifdef __GHCJS__
+
+foreign import javascript unsafe
+  "$r = hje$stringify($1);"
+  js_stringify :: JSRep -> J.JSString
+
+#else
+
+js_stringify :: JSRep -> J.JSString
+js_stringify _ = JS.empty
+
+#endif
diff --git a/src/JavaScript/Extras/JSRep/Unsafe.hs b/src/JavaScript/Extras/JSRep/Unsafe.hs
new file mode 100644
--- /dev/null
+++ b/src/JavaScript/Extras/JSRep/Unsafe.hs
@@ -0,0 +1,26 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# LANGUAGE CPP #-}
+
+module JavaScript.Extras.JSRep.Unsafe where
+
+import Data.JSString as JS
+import qualified GHCJS.Types as J
+import JavaScript.Extras.JSRep as JE
+
+-- | Injection attack! Use with care
+instance Read JE.JSRep where
+    readsPrec _ str = [(js_eval (JS.pack str), [])]
+
+#ifdef __GHCJS__
+
+-- | Injection attack! Use with care
+foreign import javascript unsafe
+  "$r = hje$unstringify($1);"
+  js_eval :: J.JSString -> JSRep
+
+#else
+
+js_eval :: J.JSString -> JSRep
+js_eval _ = JSRep J.nullRef
+
+#endif
diff --git a/src/JavaScript/Extras/JSVar.hs b/src/JavaScript/Extras/JSVar.hs
deleted file mode 100644
--- a/src/JavaScript/Extras/JSVar.hs
+++ /dev/null
@@ -1,53 +0,0 @@
-{-# LANGUAGE CPP #-}
-
-module JavaScript.Extras.JSVar where
-
-import Control.DeepSeq
-import Data.Coerce
-import Data.JSString as JS
-import Data.String
-import qualified GHCJS.Marshal.Pure as J
-import qualified GHCJS.Types as J
-import JavaScript.Extras.Cast as JE
-
--- | Wrapper to have a JSVal that also have an IString instance
--- This is helpful when using OverloadedStrings
-newtype JSVar = JSVar J.JSVal
-
-instance Show JSVar where
-    show = JS.unpack . js_stringify
-
-instance J.IsJSVal JSVar
-
-instance J.PToJSVal JSVar where
-    pToJSVal = J.jsval
-
-instance JE.ToJS JSVar
-
-instance JE.FromJS JSVar where
-    fromJS v = coerce (fromJS v :: Maybe J.JSVal)
-
-instance IsString JSVar where
-    fromString = JSVar . J.jsval . JS.pack
-
-instance NFData JSVar where
-    rnf (JSVar v) = rnf v
-
-toJS' :: JE.ToJS a => a -> JSVar
-toJS' = JSVar . toJS
-
-fromJS' :: JE.FromJS a => JSVar -> Maybe a
-fromJS' (JSVar v) = fromJS v
-
-#ifdef __GHCJS__
-
-foreign import javascript unsafe
-  "$r = hje$stringify($1);"
-  js_stringify :: JSVar -> J.JSString
-
-#else
-
-js_stringify :: JSVar -> J.JSString
-js_stringify _ = JS.empty
-
-#endif
diff --git a/src/JavaScript/Extras/JSVar/Unsafe.hs b/src/JavaScript/Extras/JSVar/Unsafe.hs
deleted file mode 100644
--- a/src/JavaScript/Extras/JSVar/Unsafe.hs
+++ /dev/null
@@ -1,26 +0,0 @@
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-{-# LANGUAGE CPP #-}
-
-module JavaScript.Extras.JSVar.Unsafe where
-
-import Data.JSString as JS
-import qualified GHCJS.Types as J
-import JavaScript.Extras.JSVar as JE
-
--- | Injection attack! Use with care
-instance Read JE.JSVar where
-    readsPrec _ str = [(js_eval (JS.pack str), [])]
-
-#ifdef __GHCJS__
-
--- | Injection attack! Use with care
-foreign import javascript unsafe
-  "$r = hje$unstringify($1);"
-  js_eval :: J.JSString -> JSVar
-
-#else
-
-js_eval :: J.JSString -> JSVar
-js_eval _ = JSVar J.nullRef
-
-#endif
diff --git a/src/JavaScript/Extras/Number.hs b/src/JavaScript/Extras/Number.hs
--- a/src/JavaScript/Extras/Number.hs
+++ b/src/JavaScript/Extras/Number.hs
@@ -2,20 +2,41 @@
 
 module JavaScript.Extras.Number
     ( maxSafeInteger
+    , minSafeInteger
+    , safeIncrement
+    , safeDecrement
     ) where
 
 maxSafeInteger :: Int
 maxSafeInteger = js_maxSafeInteger
 
+minSafeInteger :: Int
+minSafeInteger = js_minSafeInteger
+
+-- | always returns a number between [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]
+safeIncrement :: Int -> Int
+safeIncrement i = if i >= maxSafeInteger then minSafeInteger else i + 1
+
+-- | always returns a number between [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]
+safeDecrement :: Int -> Int
+safeDecrement i = if i <= minSafeInteger then maxSafeInteger else i - 1
+
 #ifdef __GHCJS__
 
 foreign import javascript unsafe
   "Number.MAX_SAFE_INTEGER"
   js_maxSafeInteger :: Int
 
+foreign import javascript unsafe
+  "Number.MIN_SAFE_INTEGER"
+  js_minSafeInteger :: Int
+
 #else
 
 js_maxSafeInteger :: Int
 js_maxSafeInteger = 0
+
+js_minSafeInteger :: Int
+js_minSafeInteger = 0
 
 #endif
diff --git a/src/JavaScript/Extras/Property.hs b/src/JavaScript/Extras/Property.hs
--- a/src/JavaScript/Extras/Property.hs
+++ b/src/JavaScript/Extras/Property.hs
@@ -1,9 +1,11 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE GHCForeignImportPrim #-}
+{-# LANGUAGE TupleSections #-}
 
 module JavaScript.Extras.Property
-    ( Property
+    ( classNames
+    , Property
     , getProperty
     , setProperty
     , fromProperties
@@ -12,71 +14,78 @@
 
 import Control.DeepSeq
 import Control.Parallel
-import Data.Coerce
+import qualified Data.JSString as JS
 import qualified GHC.Exts as Exts
 import qualified GHCJS.Marshal.Pure as J
 import qualified GHCJS.Types as J
+import qualified JavaScript.Extras.Cast as JE
+import qualified JavaScript.Extras.JSRep as JE
 import qualified JavaScript.Object as JO
 import qualified JavaScript.Object.Internal as JOI
-import qualified JavaScript.Extras.JSVar as JE
 import Unsafe.Coerce
 
-type Property = (J.JSString, JE.JSVar)
+type Property = (J.JSString, JE.JSRep)
 
+-- | Creates a JE.JSRep single string for "className" property from a list of (JSString, Bool)
+-- Idea from https://github.com/JedWatson/classnames
+classNames :: [(J.JSString, Bool)] -> JE.JSRep
+classNames = JE.toJSR . JS.unwords . fmap fst . filter snd
+
 -- | get a property of any JSVal. If a null or undefined is queried, the result will also be null
-getProperty :: Coercible a J.JSVal => J.JSString -> a -> IO JE.JSVar
-getProperty k a = let k' = J.pToJSVal k
-                      x = coerce a
+getProperty :: JE.ToJS a => a -> J.JSString -> IO JE.JSRep
+getProperty a k = let k' = J.pToJSVal k
+                      x = JE.toJS a
                   in if J.isUndefined x || J.isNull x
                          || J.isUndefined k' || J.isNull k'
-                     then pure $ JE.JSVar J.nullRef
-                     else js_unsafeGetProperty k x
+                     then pure $ JE.JSRep J.nullRef
+                     else js_unsafeGetProperty x k
 
 -- | set a property of any JSVal
-setProperty :: Coercible a J.JSVal => Property -> a -> IO ()
-setProperty (k, v) a = let k' = J.pToJSVal k
-                           x = coerce a
+setProperty :: JE.ToJS a => a -> Property -> IO ()
+setProperty a (k, v) = let k' = J.pToJSVal k
+                           x = JE.toJS a
                     in if J.isUndefined x || J.isNull x
                           || J.isUndefined k' || J.isNull k'
                        then pure ()
-                       else js_unsafeSetProperty k v x
+                       else js_unsafeSetProperty x k v
 
 fromProperties :: [Property] -> JO.Object
 fromProperties xs =
-    let (names, props) = unzip xs
-    in (rnf names `seq` rnf props) `pseq` js_toJSObjectPure (unsafeCoerce names) (unsafeCoerce props)
+    let (names, values) = unzip xs
+    in (rnf names `seq` rnf values) `pseq` js_toJSObjectPure (unsafeCoerce names) (unsafeCoerce values)
 
 
 toProperties :: JO.Object -> IO [Property]
 toProperties obj = do
    props <- JO.listProps obj
-   traverse (\k -> (\v -> (k, JE.JSVar v)) <$> JO.unsafeGetProp k obj) props
+   traverse (\k -> (\v -> (k, JE.JSRep v)) <$> JO.unsafeGetProp k obj) props
 
 #ifdef __GHCJS__
 
 -- | throws an exception if undefined or null
 foreign import javascript unsafe
-  "$2[$1]"
-  js_unsafeGetProperty :: J.JSString -> J.JSVal -> IO JE.JSVar
+  "$1[$2]"
+  js_unsafeGetProperty :: J.JSVal -> J.JSString -> IO JE.JSRep
 
 -- | throws an exception if undefined or null
 foreign import javascript unsafe
-  "$3[$1] = $2;"
-  js_unsafeSetProperty :: J.JSString -> JE.JSVar -> J.JSVal -> IO ()
+  "$1[$2] = $3;"
+  js_unsafeSetProperty :: J.JSVal -> J.JSString -> JE.JSRep -> IO ()
 
 -- | zip list of string and JSVal to object, lists must have been completely forced first
 -- Using the idea from JavaScript.Array.Internal.fromList h$fromHsListJSVal
-foreign import javascript unsafe "hje$fromHsZipListJSVal($1, $2)"
+foreign import javascript unsafe
+  "hje$fromHsZipListJSVal($1, $2)"
   js_toJSObjectPure :: Exts.Any -> Exts.Any -> JO.Object
 
 #else
 
 -- | throws an exception if undefined or null
-js_unsafeGetProperty :: J.JSString -> J.JSVal -> IO JE.JSVar
-js_unsafeGetProperty _ _ = pure $ JE.JSVar J.nullRef
+js_unsafeGetProperty :: J.JSVal -> J.JSString -> IO JE.JSRep
+js_unsafeGetProperty _ _ = pure $ JE.JSRep J.nullRef
 
 -- | throws an exception if undefined or null
-js_unsafeSetProperty :: J.JSString -> JE.JSVar -> J.JSVal -> IO ()
+js_unsafeSetProperty :: J.JSVal -> J.JSString -> JE.JSRep -> IO ()
 js_unsafeSetProperty _ _ _ = pure ()
 
 -- | zip list of string and JSVal to object, lists must have been completely forced first
diff --git a/test/haskell/Main.hs b/test/haskell/Main.hs
deleted file mode 100644
--- a/test/haskell/Main.hs
+++ /dev/null
@@ -1,47 +0,0 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE OverloadedStrings #-}
-
-module Main (main) where
-
-import qualified Data.JSString as JS
-import qualified GHCJS.Foreign.Callback as J
-import qualified GHCJS.Types as J
-import qualified JavaScript.Extras as JE
-import qualified JavaScript.Extras.JSVar.Unsafe as JE
-
-#ifdef __GHCJS__
-
-test :: JE.JSVar -> IO ()
-test x = do
-    let str = show x
-        x' = read str :: JE.JSVar
-        str' = show x'
-    js_write $ "Test: " `mappend` (JS.pack str) `mappend` " == " `mappend` (JS.pack str')
-
-main :: IO ()
-main = do
-    test js_int
-    test js_obj
-    cb <- J.syncCallback' (pure (JE.toJS js_int))
-    test (JE.JSVar (J.jsval cb))
-    J.releaseCallback cb
-    test (JE.JSVar (J.jsval cb))
-
-foreign import javascript unsafe
-  "document.write('<p>' + $1 + '</p>')"
-  js_write :: JS.JSString -> IO ()
-
-foreign import javascript unsafe
-  "5"
-  js_int :: JE.JSVar
-
-foreign import javascript unsafe
-  "{ 'hello': 'world' }"
-  js_obj :: JE.JSVar
-
-#else
-
-main :: IO ()
-main = pure ()
-
-#endif
diff --git a/test/hs/Main.hs b/test/hs/Main.hs
new file mode 100644
--- /dev/null
+++ b/test/hs/Main.hs
@@ -0,0 +1,47 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+module Main (main) where
+
+#ifdef __GHCJS__
+
+import qualified Data.JSString as JS
+import qualified GHCJS.Foreign.Callback as J
+import qualified GHCJS.Types as J
+import qualified JavaScript.Extras as JE
+import JavaScript.Extras.JSRep.Unsafe ()
+
+test :: JE.JSRep -> IO ()
+test x = do
+    let str = show x
+        x' = read str :: JE.JSRep
+        str' = show x'
+    js_write $ "Test: " `mappend` (JS.pack str) `mappend` " == " `mappend` (JS.pack str')
+
+main :: IO ()
+main = do
+    test js_int
+    test js_obj
+    cb <- J.syncCallback' (pure (JE.toJS js_int))
+    test (JE.JSRep (J.jsval cb))
+    J.releaseCallback cb
+    test (JE.JSRep (J.jsval cb))
+
+foreign import javascript unsafe
+  "document.write('<p>' + $1 + '</p>')"
+  js_write :: JS.JSString -> IO ()
+
+foreign import javascript unsafe
+  "5"
+  js_int :: JE.JSRep
+
+foreign import javascript unsafe
+  "{ 'hello': 'world' }"
+  js_obj :: JE.JSRep
+
+#else
+
+main :: IO ()
+main = pure ()
+
+#endif
