diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,7 @@
+# cli-setup
+
+## 0.2.0.5
+
+  * Use `xxd` rather than `TemplateHaskell` to provide easier cross-platform
+    builds.
+  * Support older GHCs
diff --git a/Setup.hs b/Setup.hs
deleted file mode 100644
--- a/Setup.hs
+++ /dev/null
@@ -1,2 +0,0 @@
-import Distribution.Simple
-main = defaultMain
diff --git a/cabal.project.local b/cabal.project.local
--- a/cabal.project.local
+++ b/cabal.project.local
@@ -1,6 +1,2 @@
-constraints: cli-setup +development
-tests: True
-benchmarks: True
+constraints: cli-setup -development
 documentation: True
-haddock-hoogle: True
-haddock-internal: True
diff --git a/cbits/optparse-applicative.c b/cbits/optparse-applicative.c
new file mode 100644
--- /dev/null
+++ b/cbits/optparse-applicative.c
@@ -0,0 +1,36 @@
+unsigned char py_optparse_applicative_py[] = {
+  0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x72, 0x65, 0x0a, 0x66, 0x72,
+  0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x66, 0x75, 0x63, 0x6b, 0x2e, 0x75,
+  0x74, 0x69, 0x6c, 0x73, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x20,
+  0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x75,
+  0x6d, 0x65, 0x6e, 0x74, 0x0a, 0x0a, 0x64, 0x65, 0x66, 0x20, 0x6d, 0x61,
+  0x74, 0x63, 0x68, 0x28, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x29,
+  0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
+  0x20, 0x28, 0x27, 0x44, 0x69, 0x64, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6d,
+  0x65, 0x61, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x3f, 0x27, 0x20, 0x69,
+  0x6e, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x6f, 0x75,
+  0x74, 0x70, 0x75, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x27, 0x49, 0x6e,
+  0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65,
+  0x6e, 0x74, 0x27, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x61,
+  0x6e, 0x64, 0x2e, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x29, 0x0a, 0x0a,
+  0x64, 0x65, 0x66, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x6e, 0x65, 0x77, 0x5f,
+  0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x28, 0x63, 0x6f, 0x6d, 0x6d,
+  0x61, 0x6e, 0x64, 0x29, 0x3a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x62, 0x72,
+  0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x61,
+  0x6e, 0x64, 0x2e, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x70, 0x61,
+  0x72, 0x74, 0x73, 0x5b, 0x31, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66,
+  0x69, 0x78, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x2e, 0x66, 0x69, 0x6e, 0x64,
+  0x61, 0x6c, 0x6c, 0x28, 0x72, 0x27, 0x20, 0x20, 0x20, 0x20, 0x28, 0x5b,
+  0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x7a, 0x5d, 0x2a, 0x29, 0x27, 0x2c, 0x20,
+  0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x6f, 0x75, 0x74, 0x70,
+  0x75, 0x74, 0x29, 0x5b, 0x30, 0x5d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x65, 0x70, 0x6c, 0x61,
+  0x63, 0x65, 0x5f, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x28,
+  0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x73, 0x63, 0x72, 0x69,
+  0x70, 0x74, 0x2c, 0x20, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x6e, 0x2c, 0x20,
+  0x66, 0x69, 0x78, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65,
+  0x64, 0x5f, 0x62, 0x79, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74,
+  0x20, 0x3d, 0x20, 0x54, 0x72, 0x75, 0x65, 0x0a, 0x0a, 0x70, 0x72, 0x69,
+  0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x30, 0x0a
+};
+unsigned int py_optparse_applicative_py_len = 396;
diff --git a/cli-setup.cabal b/cli-setup.cabal
--- a/cli-setup.cabal
+++ b/cli-setup.cabal
@@ -1,6 +1,6 @@
 cabal-version: 1.18
 name: cli-setup
-version: 0.2.0.4
+version: 0.2.0.5
 license: BSD3
 license-file: LICENSE
 copyright: Copyright: (c) 2018 Vanessa McHale
@@ -13,10 +13,11 @@
 category: Development, Command Line Tools
 build-type: Simple
 extra-source-files:
-    stack.yaml
     cabal.project.local
     py/optparse-applicative.py
+    cbits/*.c
 extra-doc-files: README.md
+                 CHANGELOG.md
 
 source-repository head
     type: darcs
@@ -31,15 +32,16 @@
 library
     exposed-modules:
         Distribution.CommandLine
+    c-sources:
+        cbits/optparse-applicative.c
     hs-source-dirs: src
     default-language: Haskell2010
     ghc-options: -Wall
     build-depends:
-        base >=4.9 && <5,
+        base >=4.6 && <5,
         directory -any,
         process >=1.4.0.0,
-        bytestring -any,
-        file-embed >=0.0.9
+        bytestring -any
     
     if flag(development)
         ghc-options: -Werror
diff --git a/src/Distribution/CommandLine.hs b/src/Distribution/CommandLine.hs
--- a/src/Distribution/CommandLine.hs
+++ b/src/Distribution/CommandLine.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE TemplateHaskell #-}
-
 module Distribution.CommandLine
     ( writeManpages
     , writeBashCompletions
@@ -7,16 +5,15 @@
     , writeTheFuck
     ) where
 
-import           Control.Monad      (unless, void, when)
-import           Data.Bool          (bool)
-import           Data.FileEmbed     (embedStringFile)
-import           System.Directory   (createDirectoryIfMissing,
-                                     doesDirectoryExist, doesFileExist)
-import           System.Environment (lookupEnv)
-import           System.Process     (readCreateProcessWithExitCode, shell)
+import           Control.Applicative
+import           Control.Monad       (unless, void, when)
+import           Foreign.C           (CString, peekCString)
+import           System.Directory    (createDirectoryIfMissing,
+                                      doesDirectoryExist, doesFileExist)
+import           System.Environment  (lookupEnv)
+import           System.Process      (readCreateProcessWithExitCode, shell)
 
-rules :: String
-rules = $(embedStringFile "py/optparse-applicative.py")
+foreign import ccall unsafe py_optparse_applicative_py :: CString
 
 -- | Write a set of rules based on
 -- [optparse-applicative](http://hackage.haskell.org/package/optparse-applicative)
@@ -25,11 +22,13 @@
 writeTheFuck :: IO ()
 writeTheFuck = do
     h <- lookupEnv "HOME"
+    rules <- peekCString py_optparse_applicative_py
     case h of
         Just h' -> do
             proceed <- doesDirectoryExist (h' ++ "/.config/thefuck/rules")
-            bool mempty (writeFile (h' ++ "/.config/thefuck/rules/optparse-applicative.py") rules) proceed
-        Nothing -> mempty
+            when proceed $
+                writeFile (h' ++ "/.config/thefuck/rules/optparse-applicative.py") rules
+        Nothing -> pure ()
 
 -- | Add a line exporting the modified @MANPATH@ to the user's @bashrc@, if it
 -- does not exist already.
@@ -45,7 +44,7 @@
                 unless ("#manpath updated by cli-setup" `elem` lines config && length config > 0)
                     (appendFile bashRc "\n#manpath updated by cli-setup\nexport MANPATH=~/.local/share:$MANPATH\n" >>
                     void (readCreateProcessWithExitCode (shell $ "MANPATH=" ++ x ++ "/.local/share mandb") ""))
-        Nothing -> mempty
+        Nothing -> pure ()
 
 -- | As an example, if your source tarball contains a file @man/madlang.1@ you
 -- could use
@@ -61,7 +60,7 @@
             let manPath = x ++ "/.local/share/man/man1"
             createDirectoryIfMissing True manPath
             writeFile (manPath ++ "/" ++ p') =<< readFile p
-        Nothing -> mempty
+        Nothing -> pure ()
 
 -- | Add a line to the user's @bashrc@ so that command-line completions work
 -- automatically.
@@ -75,4 +74,4 @@
             config <- readFile bashRc
             unless (("# Added for " ++ exeName) `elem` lines config)
                 (appendFile bashRc ("\n# Added for " ++ exeName ++ "\neval \"$(" ++ exeName ++ " --bash-completion-script " ++ exeName ++ ")\"\n"))
-        Nothing -> mempty
+        Nothing -> pure ()
diff --git a/stack.yaml b/stack.yaml
deleted file mode 100644
--- a/stack.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
----
-resolver: lts-10.3
-packages:
-  - '.'
-extra-deps: []
-flags:
-  cli-setup:
-    development: false
-extra-package-dbs: []
