diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+0.9.1
+-----
+
+* Fix javascript function name generation
+* Allow servant-0.10
+
 0.5
 ----
 
diff --git a/servant-js.cabal b/servant-js.cabal
--- a/servant-js.cabal
+++ b/servant-js.cabal
@@ -1,16 +1,16 @@
 name:                servant-js
-version:             0.9
+version:             0.9.1
 synopsis:            Automatically derive javascript functions to query servant webservices.
 description:
   Automatically derive javascript functions to query servant webservices.
   .
   Supports deriving functions using vanilla javascript AJAX requests, Angulari, Axios or JQuery.
   .
-  You can find an example <https://github.com/haskell-servant/servant/blob/master/servant-js/examples/counter.hs here>
+  You can find an example <https://github.com/haskell-servant/servant-js/blob/master/servant-js/examples/counter.hs here>
   which serves the generated javascript to a webpage that allows you to trigger
   webservice calls.
   .
-  <https://github.com/haskell-servant/servant/blob/master/servant-js/CHANGELOG.md CHANGELOG>
+  <https://github.com/haskell-servant/servant-js/blob/master/CHANGELOG.md CHANGELOG>
 license:             BSD3
 license-file:        LICENSE
 author:              Servant Contributors
@@ -20,14 +20,15 @@
 build-type:          Simple
 cabal-version:       >=1.10
 homepage:            http://haskell-servant.readthedocs.org/
-Bug-reports:         http://github.com/haskell-servant/servant/issues
+bug-reports:         http://github.com/haskell-servant/servant-js/issues
+tested-with:         GHC==7.8.3, GHC==7.10.3, GHC==8.0.1
 extra-source-files:
   include/*.h
   CHANGELOG.md
   README.md
 source-repository head
   type: git
-  location: http://github.com/haskell-servant/servant.git
+  location: http://github.com/haskell-servant/servant-js.git
 
 flag example
   description: Build the example too
@@ -45,8 +46,8 @@
                      , base-compat     >= 0.9
                      , charset         >= 0.3
                      , lens            >= 4
-                     , servant-foreign == 0.9.*
-                     , servant         == 0.9.*
+                     , servant-foreign >= 0.9 && <0.11
+                     , servant         >= 0.9 && <0.11
                      , text            >= 1.2  && < 1.3
 
   hs-source-dirs:      src
@@ -86,11 +87,12 @@
       Servant.JSSpec.CustomHeaders
   build-depends:     base
                    , base-compat
-                   , hspec >= 2.1.8
+                   , hspec >= 2.3.0 && <2.5
                    , hspec-expectations
                    , language-ecmascript >= 0.16
                    , lens
                    , servant
                    , servant-js
                    , text
+                   , QuickCheck
   default-language:  Haskell2010
diff --git a/src/Servant/JS/Angular.hs b/src/Servant/JS/Angular.hs
--- a/src/Servant/JS/Angular.hs
+++ b/src/Servant/JS/Angular.hs
@@ -132,7 +132,7 @@
 
         fsep = if hasService then ":" else " ="
 
-        fname = namespace <> (functionNameBuilder opts $ req ^. reqFuncName)
+        fname = namespace <> (toValidFunctionName (functionNameBuilder opts $ req ^. reqFuncName))
 
         method = req ^. reqMethod
         url = if url' == "'" then "'/'" else url'
diff --git a/src/Servant/JS/Axios.hs b/src/Servant/JS/Axios.hs
--- a/src/Servant/JS/Axios.hs
+++ b/src/Servant/JS/Axios.hs
@@ -120,7 +120,7 @@
                where
                   hasNoModule = moduleName opts == ""
 
-        fname = namespace <> (functionNameBuilder opts $ req ^. reqFuncName)
+        fname = namespace <> (toValidFunctionName (functionNameBuilder opts $ req ^. reqFuncName))
 
         method = T.toLower . decodeUtf8 $ req ^. reqMethod
         url = if url' == "'" then "'/'" else url'
diff --git a/src/Servant/JS/Internal.hs b/src/Servant/JS/Internal.hs
--- a/src/Servant/JS/Internal.hs
+++ b/src/Servant/JS/Internal.hs
@@ -1,5 +1,4 @@
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE ViewPatterns #-}
 
 module Servant.JS.Internal
   ( JavaScriptGenerator
@@ -116,25 +115,30 @@
       setFirstChar x `T.cons` T.filter remainder xs
     Nothing -> "_"
   where
-    setFirstChar c = if firstChar c then c else '_'
-    firstChar c = prefixOK c || Set.member c firstLetterOK
-    remainder c = prefixOK c || Set.member c remainderOK
-    prefixOK c = c `elem` ['$','_']
-    firstLetterOK = mconcat
-                      [ Set.lowercaseLetter
+    setFirstChar c = if Set.member c firstLetterOK then c else '_'
+    remainder c = Set.member c remainderOK
+    firstLetterOK = (filterBmpChars $ mconcat
+                      [ Set.fromDistinctAscList "$_"
+                      , Set.lowercaseLetter
                       , Set.uppercaseLetter
                       , Set.titlecaseLetter
                       , Set.modifierLetter
                       , Set.otherLetter
                       , Set.letterNumber
-                      ]
+                      ])
     remainderOK   = firstLetterOK
-               <> mconcat
+               <> (filterBmpChars $ mconcat
                     [ Set.nonSpacingMark
                     , Set.spacingCombiningMark
                     , Set.decimalNumber
                     , Set.connectorPunctuation
-                    ]
+                    ])
+
+-- Javascript identifiers can only contain codepoints in the Basic Multilingual Plane
+-- that is, codepoints that can be encoded in UTF-16 without a surrogate pair (UCS-2)
+-- that is, codepoints that can fit in 16-bits, up to 0xffff (65535)
+filterBmpChars :: Set.CharSet -> Set.CharSet
+filterBmpChars = Set.filter (< '\65536')
 
 toJSHeader :: HeaderArg f -> Text
 toJSHeader (HeaderArg n)
diff --git a/src/Servant/JS/JQuery.hs b/src/Servant/JS/JQuery.hs
--- a/src/Servant/JS/JQuery.hs
+++ b/src/Servant/JS/JQuery.hs
@@ -86,7 +86,7 @@
         namespace = if (moduleName opts) == ""
                        then "var "
                        else (moduleName opts) <> "."
-        fname = namespace <> (functionNameBuilder opts $ req ^. reqFuncName)
+        fname = namespace <> (toValidFunctionName (functionNameBuilder opts $ req ^. reqFuncName))
 
         method = req ^. reqMethod
         url = if url' == "'" then "'/'" else url'
diff --git a/src/Servant/JS/Vanilla.hs b/src/Servant/JS/Vanilla.hs
--- a/src/Servant/JS/Vanilla.hs
+++ b/src/Servant/JS/Vanilla.hs
@@ -97,7 +97,7 @@
         namespace = if moduleName opts == ""
                        then "var "
                        else (moduleName opts) <> "."
-        fname = namespace <> (functionNameBuilder opts $ req ^. reqFuncName)
+        fname = namespace <> (toValidFunctionName (functionNameBuilder opts $ req ^. reqFuncName))
 
         method = req ^. reqMethod
         url = if url' == "'" then "'/'" else url'
diff --git a/test/Servant/JSSpec.hs b/test/Servant/JSSpec.hs
--- a/test/Servant/JSSpec.hs
+++ b/test/Servant/JSSpec.hs
@@ -15,10 +15,14 @@
 import           Data.Proxy
 import           Data.Text                    (Text)
 import qualified Data.Text                    as T
+import           Language.ECMAScript3.Lexer   (identifier)
 import           Language.ECMAScript3.Parser  (program, parse)
 import           Prelude                      ()
 import           Prelude.Compat
 import           Test.Hspec  hiding (shouldContain, shouldNotContain)
+import           Test.QuickCheck              (Arbitrary (..),
+                                               choose, listOf,
+                                               property)
 
 import           Servant.API.Internal.Test.ComprehensiveAPI
 import           Servant.API.ContentTypes
@@ -97,6 +101,7 @@
     angularSpec    Angular
     axiosSpec
     --angularSpec    AngularCustom
+    internalSpec
 
 shouldContain :: Text -> Text -> Expectation
 a `shouldContain` b  = shouldSatisfy a (T.isInfixOf b)
@@ -151,6 +156,24 @@
         testName = "MyService"
         ngOpts = NG.defAngularOptions { NG.serviceName = testName }
         genJS req = NG.angularService ngOpts req
+
+newtype ASCII = ASCII {getASCII :: T.Text} deriving (Show)
+
+instance Arbitrary ASCII where
+    -- Our arbitrary instance is generating only ASCII, since the language-ecmascript's lexer
+    -- is currently (October 2016) still a bit naïve
+    arbitrary = fmap (ASCII . T.pack) $ listOf $ choose (minBound, '\127')
+    shrink xs = (ASCII . T.pack) <$> shrink (T.unpack $ getASCII xs)
+
+internalSpec :: Spec
+internalSpec = describe "Internal" $ do
+    it "should generate only valid javascript identifiers for any ASCII route" $ do
+        let parseIdentifier = fmap T.pack. parse identifier ""
+        property $ \x -> let valid = toValidFunctionName $ getASCII x in
+                         Right valid == parseIdentifier valid
+
+    it "should generate a valid javascript identifier when supplied with hyphens, unicode whitespace, non-bmp unicode" $ do
+        toValidFunctionName "a_--a\66352b\6158c\65075" `shouldBe` "a_abc\65075"
 
 generateJSSpec :: TestNames -> (AjaxReq -> Text) -> Spec
 generateJSSpec n gen = describe specLabel $ do
