diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,12 @@
+# 2.3.0.0
+
+* Windows is now rudimentarily supported. Since I couldn't find a library to
+  connect to named pipes on windows and I didn't want to extend or write one,
+  you have to use TCP sockets or Standard in and out to communicate with
+  neovim. If you start neovim with `nvim --listen localhost:`, it will set the
+  `NVIM` environment variable, so that nvim-hs can automatically connect to the
+  neovim instance without passing any arguments.
+
 # 2.2.0.0
 
 * NeovimException are now thrown from (synchronous) remote functions and are no
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -9,7 +9,6 @@
 to generate the neovim bindings and to avoid some of the boilerplate
 handy work, some exotic operating systems and architectures may not work.
 
-[![Build Status](https://travis-ci.org/neovimhaskell/nvim-hs.svg?branch=master)](https://travis-ci.org/neovimhaskell/nvim-hs)
 [![Hackage version](https://img.shields.io/hackage/v/nvim-hs.svg?style=flat)](https://hackage.haskell.org/package/nvim-hs)
 [![nvim-hs on latest Stackage LTS](http://stackage.org/package/nvim-hs/badge/lts)](http://stackage.org/lts/package/nvim-hs)
 [![nvim-hs on Stackage Nightly](http://stackage.org/package/nvim-hs/badge/nightly)](http://stackage.org/nightly/package/nvim-hs)
@@ -17,6 +16,16 @@
 # What do I have to expect if I were to use it now?
 
 Check the issue list here on github.
+
+## For Windows users
+
+Named pipes are not supported at the momend #103. You therefore have to start
+`nvim-hs` instances by connecting to STDIN and STDOUT or TCP. By default `nvim-hs`
+connects to the listen socket pointed to by the `NVIM` environment variable and 
+the functions in the module `Neovim.Debug` rely on that. If you want to be able to 
+run these functions, start Neovim with `nvim --listen localhost:` or similar
+(This example command starts neovim with a socket listening on `localhost` and 
+random a random TCP port.)
 
 # How do I start using this?
 
diff --git a/api b/api
Binary files a/api and b/api differ
diff --git a/apiblobs/0.4.3.msgpack b/apiblobs/0.4.3.msgpack
new file mode 100644
Binary files /dev/null and b/apiblobs/0.4.3.msgpack differ
diff --git a/apiblobs/0.5.0.msgpack b/apiblobs/0.5.0.msgpack
new file mode 100644
Binary files /dev/null and b/apiblobs/0.5.0.msgpack differ
diff --git a/apiblobs/0.6.1.msgpack b/apiblobs/0.6.1.msgpack
new file mode 100644
Binary files /dev/null and b/apiblobs/0.6.1.msgpack differ
diff --git a/apiblobs/0.8.0.msgpack b/apiblobs/0.8.0.msgpack
new file mode 100644
Binary files /dev/null and b/apiblobs/0.8.0.msgpack differ
diff --git a/library/Neovim/API/Parser.hs b/library/Neovim/API/Parser.hs
--- a/library/Neovim/API/Parser.hs
+++ b/library/Neovim/API/Parser.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {- |
 Module      :  Neovim.API.Parser
 Description :  P.Parser for the msgpack output stram API
@@ -22,10 +23,10 @@
 import qualified Data.ByteString.Lazy as LB
 import Data.Map (Map)
 import qualified Data.Map as Map
-import Data.MessagePack
-import Data.Serialize
+import Data.MessagePack ( Object )
+import Data.Serialize ( decode )
 import Neovim.Compat.Megaparsec as P
-import System.Process.Typed
+import System.Process.Typed ( proc, readProcessStdout_ )
 import UnliftIO.Exception (
     SomeException,
     catch,
@@ -71,8 +72,18 @@
 
 -- | Run @nvim --api-info@ and parse its output.
 parseAPI :: IO (Either (Doc AnsiStyle) NeovimAPI)
-parseAPI = either (Left . pretty) extractAPI <$> (decodeAPI `catch` readFromAPIFile)
+parseAPI = either (Left . pretty) extractAPI <$> 
+#ifndef WINDOWS
+  (decodeAPI `catch` \(_ignored :: SomeException) -> readFromAPIFile)
 
+decodeAPI :: IO (Either String Object)
+decodeAPI =
+    decode . LB.toStrict <$> readProcessStdout_ (proc "nvim" ["--api-info"])
+
+#else
+  readFromAPIFile
+#endif
+
 extractAPI :: Object -> Either (Doc AnsiStyle) NeovimAPI
 extractAPI apiObj =
     fromObject apiObj >>= \apiMap ->
@@ -81,18 +92,13 @@
             <*> extractCustomTypes apiMap
             <*> extractFunctions apiMap
 
-readFromAPIFile :: SomeException -> IO (Either String Object)
-readFromAPIFile _ = (decode <$> B.readFile "api") `catch` returnPreviousExceptionAsText
+readFromAPIFile :: IO (Either String Object)
+readFromAPIFile = (decode <$> B.readFile "api") `catch` returnNoApiForCodegeneratorErrorMessage
   where
-    returnPreviousExceptionAsText :: SomeException -> IO (Either String Object)
-    returnPreviousExceptionAsText _ =
+    returnNoApiForCodegeneratorErrorMessage :: SomeException -> IO (Either String Object)
+    returnNoApiForCodegeneratorErrorMessage _ =
         return . Left $
-            "The 'nvim' process could not be started and there is no file named\
-            \ 'api' in the working directory as a substitute."
-
-decodeAPI :: IO (Either String Object)
-decodeAPI =
-    decode . LB.toStrict <$> readProcessStdout_ (proc "nvim" ["--api-info"])
+            "The 'nvim' process could not be started and there is no file named 'api' in the working directory as a substitute."
 
 oLookup :: (NvimObject o) => String -> Map String Object -> Either (Doc AnsiStyle) o
 oLookup qry = maybe throwErrorMessage fromObject . Map.lookup qry
diff --git a/library/Neovim/Debug.hs b/library/Neovim/Debug.hs
--- a/library/Neovim/Debug.hs
+++ b/library/Neovim/Debug.hs
@@ -53,7 +53,7 @@
 -- | Run a 'Neovim' function.
 --
 -- This function connects to the socket pointed to by the environment variable
--- @$NVIM_LISTEN_ADDRESS@ and executes the command. It does not register itself
+-- @$NVIM@ and executes the command. It does not register itself
 -- as a real plugin provider, you can simply call neovim-functions from the
 -- module "Neovim.API.String" this way.
 --
diff --git a/library/Neovim/Main.hs b/library/Neovim/Main.hs
--- a/library/Neovim/Main.hs
+++ b/library/Neovim/Main.hs
@@ -86,7 +86,7 @@
     <*> switch
         ( long "environment"
         <> short 'e'
-        <> help "Read connection information from $NVIM_LISTEN_ADDRESS.")
+        <> help "Read connection information from $NVIM.")
     <*> optional ((,)
         <$> strOption
             (long "log-file"
diff --git a/library/Neovim/RPC/Common.hs b/library/Neovim/RPC/Common.hs
--- a/library/Neovim/RPC/Common.hs
+++ b/library/Neovim/RPC/Common.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE RankNTypes        #-}
+{-# LANGUAGE RankNTypes, CPP        #-}
 {- |
 Module      :  Neovim.RPC.Common
 Description :  Common functons for the RPC module
@@ -25,12 +25,17 @@
 import           Data.String
 import           Data.Time
 import           Network.Socket         as N hiding (SocketType)
-import           System.Environment     (getEnv)
 import           System.IO              (BufferMode (..), Handle, IOMode(ReadWriteMode),
                                          hClose, hSetBuffering)
 import           System.Log.Logger
+import           Neovim.Compat.Megaparsec as P
 
 import           Prelude
+import UnliftIO.Environment (lookupEnv)
+import Data.Maybe (catMaybes)
+import Data.List (intercalate)
+import qualified Data.List as List
+import qualified Text.Megaparsec.Char.Lexer as L
 
 
 -- | Things shared between the socket reader and the event handler.
@@ -58,7 +63,7 @@
                 -- suitable for an embedded neovim which is used in test cases.
                 | Environment
                 -- ^ Read the connection information from the environment
-                -- variable @NVIM_LISTEN_ADDRESS@.
+                -- variable @NVIM@.
                 | UnixSocket FilePath
                 -- ^ Use a unix socket.
                 | TCP Int String
@@ -77,7 +82,11 @@
         return h
 
     UnixSocket f ->
-        createHandle . Stdout =<< createUnixSocketHandle f
+#ifndef WINDOWS
+        liftIO $ createHandle . Stdout =<< flip socketToHandle ReadWriteMode =<< getSocketUnix f
+#else
+        error "Windows' named pipes are not supported"
+#endif
 
     TCP p h ->
         createHandle . Stdout =<< createTCPSocketHandle p h
@@ -86,27 +95,39 @@
         createHandle . Stdout =<< createSocketHandleFromEnvironment
 
   where
-    createUnixSocketHandle :: (MonadIO io) => FilePath -> io Handle
-    createUnixSocketHandle f =
-        liftIO $ getSocketUnix f >>= flip socketToHandle ReadWriteMode
-
     createTCPSocketHandle :: (MonadIO io) => Int -> String -> io Handle
     createTCPSocketHandle p h = liftIO $ getSocketTCP (fromString h) p
         >>= flip socketToHandle ReadWriteMode . fst
 
-    createSocketHandleFromEnvironment = do
-        listenAddress <- liftIO (getEnv "NVIM_LISTEN_ADDRESS")
-        case words listenAddress of
-            [unixSocket] -> createHandle (UnixSocket unixSocket)
-            [h,p] -> createHandle (TCP (read p) h)
+    createSocketHandleFromEnvironment = liftIO $ do
+        -- NVIM_LISTEN_ADDRESS is for backwards compatibility
+        envValues <- catMaybes <$> mapM lookupEnv ["NVIM", "NVIM_LISTEN_ADDRESS"]
+        listenAdresses <- mapM parseNvimEnvironmentVariable envValues
+        case listenAdresses of
+            (s:_) -> createHandle s
             _  -> do
                 let errMsg = unlines
                         [ "Unhandled socket type from environment variable: "
-                        , "\t" <> listenAddress
+                        , "\t" <> intercalate ", " envValues
                         ]
                 liftIO $ errorM "createHandle" errMsg
                 error errMsg
 
+parseNvimEnvironmentVariable :: MonadFail m => String -> m SocketType
+parseNvimEnvironmentVariable envValue =
+  either (fail . show) pure $ parse (P.try pTcpAddress <|> pUnixSocket) envValue envValue
+
+pUnixSocket :: P.Parser SocketType
+pUnixSocket = UnixSocket <$> P.some anySingle <* P.eof
+
+pTcpAddress :: P.Parser SocketType
+pTcpAddress = do
+   prefixes <- P.some (P.try (P.many (P.anySingleBut ':') <* P.single ':'))
+   port <- L.lexeme P.eof L.decimal
+   P.eof
+   pure $ TCP port (List.intercalate ":" prefixes)
+
+  -- fail $ "Unsupported format for $NVIM environment variable: " <> envValue
 
 -- | Close the handle and print a warning if the conduit chain has been
 -- interrupted prematurely.
diff --git a/library/Neovim/Test.hs b/library/Neovim/Test.hs
--- a/library/Neovim/Test.hs
+++ b/library/Neovim/Test.hs
@@ -107,7 +107,7 @@
     nvimProcess <- startProcess
         $ setStdin createPipe
         $ setStdout createPipe
-        $ proc "nvim" (["-n","-u","NONE","--embed"] ++ args)
+        $ proc "nvim" (["-n","--clean","--embed"] ++ args)
 
     cfg <- Internal.newConfig (pure Nothing) newRPCConfig
 
diff --git a/nvim-hs-devel.sh b/nvim-hs-devel.sh
deleted file mode 100644
--- a/nvim-hs-devel.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/sh
-
-# Helper script to run nvim-hs in a development environment.
-
-# You should not name this script nvim-hs and put it on your path.
-if [ x"$0" = x`which nvim-hs` ] ; then
-    echo "This script has the potential to run in an infinite loop. Exiting now..."
-    exit 1
-fi
-
-# This variable defines where the sandbox or stack files can be found. Adjust it
-# appropriately and then delete the line after it.
-sandbox_directory=$HOME/git/nvim-hs
-echo "I should have read the comments. Silly me." && exit 1
-
-old_pwd="`pwd`"
-cd "$sandbox_directory"
-
-if [ -d "$sandbox_directory/.cabal-sandbox" ] ; then
-    # We detect the sandbox by checking for the directory .cabal-sandbox
-    # This should work most of the time.
-    env CABAL_SANDBOX_CONFIG="$sandbox_directory"/cabal.sandbox.config cabal \
-        exec "$sandbox_directory/.cabal-sandbox/bin/nvim-hs" -- "$@"
-elif [ -d "$sandbox_directory/.stack-work" ] ; then
-    # Stack leaves behind a .stack-work directory, so we take its present as a
-    # sign to use this approach.
-    stack exec nvim-hs -- "$@"
-else
-    echo "No development directories found. Have you built the project?"
-    exit 2
-fi
-cd "$old_pwd"
-
-# vim: foldmethod=marker sts=2 ts=4 expandtab sw=4
diff --git a/nvim-hs.cabal b/nvim-hs.cabal
--- a/nvim-hs.cabal
+++ b/nvim-hs.cabal
@@ -1,5 +1,5 @@
 name:                nvim-hs
-version:             2.2.0.3
+version:             2.3.0.0
 synopsis:            Haskell plugin backend for neovim
 description:
   This package provides a plugin provider for neovim. It allows you to write
@@ -30,11 +30,14 @@
 category:            Editor
 build-type:          Simple
 cabal-version:       1.18
-extra-source-files:    nvim-hs-devel.sh
-                     , test-files/hello
+extra-source-files:    test-files/hello
                      , apiblobs/0.1.7.msgpack
                      , apiblobs/0.2.0.msgpack
                      , apiblobs/0.3.0.msgpack
+                     , apiblobs/0.4.3.msgpack
+                     , apiblobs/0.5.0.msgpack
+                     , apiblobs/0.6.1.msgpack
+                     , apiblobs/0.8.0.msgpack
                      , api
 
 extra-doc-files:       CHANGELOG.md
@@ -139,6 +142,8 @@
   default-language:     Haskell2010
   ghc-options:          -Wall
 
+  if os(windows)
+    cpp-options: -DWINDOWS
 
 test-suite hspec
   type:                 exitcode-stdio-1.0
@@ -194,6 +199,7 @@
                       , Neovim.EmbeddedRPCSpec
                       , Neovim.Plugin.ClassesSpec
                       , Neovim.RPC.SocketReaderSpec
+                      , Neovim.RPC.CommonSpec
 
   ghc-options:          -threaded -rtsopts -with-rtsopts=-N
 
diff --git a/test-suite/Neovim/RPC/CommonSpec.hs b/test-suite/Neovim/RPC/CommonSpec.hs
new file mode 100644
--- /dev/null
+++ b/test-suite/Neovim/RPC/CommonSpec.hs
@@ -0,0 +1,20 @@
+module Neovim.RPC.CommonSpec where
+
+import Neovim.RPC.Common
+
+import Test.Hspec
+
+spec :: Spec
+spec = do
+  describe "Parsing of $NVIM environment variable" $ do
+    it "is a UnixSocket if it doesn't contain a colon" $ do
+      UnixSocket actual <- parseNvimEnvironmentVariable "/some/file"
+      actual `shouldBe` "/some/file"
+    it "is a tcp connection if it contains a colon" $ do
+      TCP actualPort actualHostname <- parseNvimEnvironmentVariable "localhost:12345"
+      actualPort `shouldBe` 12345
+      actualHostname `shouldBe` "localhost"
+    it "the last number after many colons is the port" $ do
+      TCP actualPort actualHostname <- parseNvimEnvironmentVariable "the:cake:is:a:lie:777"
+      actualPort `shouldBe` 777
+      actualHostname `shouldBe` "the:cake:is:a:lie"
