diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
deleted file mode 100644
--- a/CHANGELOG.markdown
+++ /dev/null
@@ -1,7 +0,0 @@
-# Change log
-
-GitHub Release uses [Semantic Versioning][].
-The change log is available through the [releases on GitHub][].
-
-[Semantic Versioning]: http://semver.org/spec/v2.0.0.html
-[releases on GitHub]: https://github.com/tfausak/github-release/releases
diff --git a/LICENSE.markdown b/LICENSE.markdown
--- a/LICENSE.markdown
+++ b/LICENSE.markdown
@@ -1,6 +1,6 @@
 # [The MIT License (MIT)][]
 
-Copyright (c) 2016 Taylor Fausak
+Copyright (c) 2017 Taylor Fausak
 
 Permission is hereby granted, free of charge, to any person obtaining a copy of
 this software and associated documentation files (the "Software"), to deal in
diff --git a/README.markdown b/README.markdown
deleted file mode 100644
--- a/README.markdown
+++ /dev/null
@@ -1,64 +0,0 @@
-# [GitHub Release][]
-
-[![Version badge][]][version]
-[![Build badge][]][build]
-[![Windows build badge][]][windows build]
-
-GitHub Release is a command-line utility for uploading files to GitHub
-releases.
-
-The recommended way to get GitHub Release is to download [the latest release][]
-for your operating system. These releases are, of course, added with GitHub
-Release itself.
-
-Once you've got it, run it like so:
-
-``` sh
-github-release upload \
-  --token '...' \
-  --owner 'someone' \
-  --repo 'something' \
-  --tag '1.2.3' \
-  --file 'path/to/example.tgz' \
-  --name 'example-1.2.3.tgz'
-```
-
-You can generate a token on the [personal access tokens][] page of your
-personal settings. The `file` option is the path to the local file you want to
-upload. The `name` option is what the file should be called on the GitHub
-release.
-
-GitHub Release is written in Haskell. If you want to build it yourself or use
-it in your project, you'll want to get [Stack][]. Once you've done that, you
-can install and use it from the command line.
-
-``` sh
-stack --resolver nightly install github-release
-stack exec -- github release upload # as above ...
-```
-
-Or you can use it from Haskell.
-
-``` hs
-import qualified GitHubRelease
-GitHubRelease.upload
-    "..."                 -- token
-    "someone"             -- owner
-    "something"           -- repo
-    "1.2.3"               -- tag
-    "path/to/example.tgz" -- file
-    "example-1.2.3.tgz"   -- name
-```
-
-Inspired by <https://github.com/aktau/github-release>.
-
-[GitHub Release]: https://github.com/tfausak/github-release
-[Version badge]: https://www.stackage.org/package/github-release/badge/nightly?label=version
-[version]: https://www.stackage.org/package/github-release
-[Build badge]: https://travis-ci.org/tfausak/github-release.svg
-[build]: https://travis-ci.org/tfausak/github-release
-[Windows build badge]: https://ci.appveyor.com/api/projects/status/github/tfausak/github-release?svg=true
-[windows build]: https://ci.appveyor.com/project/TaylorFausak/github-release
-[the latest release]: https://github.com/tfausak/github-release/releases/latest
-[personal access tokens]: https://github.com/settings/tokens
-[Stack]: http://docs.haskellstack.org/en/stable/README/
diff --git a/executables/github-release.hs b/executables/github-release.hs
new file mode 100644
--- /dev/null
+++ b/executables/github-release.hs
@@ -0,0 +1,5 @@
+module Main
+  ( module GitHubRelease
+  ) where
+
+import GitHubRelease (main)
diff --git a/github-release.cabal b/github-release.cabal
--- a/github-release.cabal
+++ b/github-release.cabal
@@ -3,9 +3,9 @@
 -- see: https://github.com/sol/hpack
 
 name:           github-release
-version:        1.0.4
+version:        1.0.5
 synopsis:       Upload files to GitHub releases.
-description:    GitHub Release is a command-line utility for uploading files to GitHub releases.
+description:    GitHub Release uploads files to GitHub releases.
 category:       Utility
 homepage:       https://github.com/tfausak/github-release#readme
 bug-reports:    https://github.com/tfausak/github-release/issues
@@ -15,32 +15,26 @@
 build-type:     Simple
 cabal-version:  >= 1.10
 
-extra-source-files:
-    CHANGELOG.markdown
-    package.yaml
-    README.markdown
-    stack.yaml
-
 source-repository head
   type: git
   location: https://github.com/tfausak/github-release
 
 library
   hs-source-dirs:
-      source/library
+      library
   ghc-options: -Wall
   build-depends:
-      aeson >=0.9 && <1.3
-    , base >=4.8.2 && <4.11
-    , bytestring >=0.10.6 && <0.11
-    , http-client >=0.4.30 && <0.6
-    , http-client-tls >=0.2.4 && <0.4
-    , http-types >=0.9 && <0.10
-    , mime-types >=0.1 && <0.2
-    , optparse-generic >=1.1 && <1.3
-    , text >=1.2.2 && <1.3
-    , unordered-containers >=0.2.5 && <0.3
-    , uri-templater >=0.2 && <0.3
+      base >= 4.8.2 && < 4.11
+    , aeson >= 0.9 && < 1.3
+    , bytestring >= 0.10.6 && < 0.11
+    , http-client >= 0.4.30 && < 0.6
+    , http-client-tls >= 0.2.4 && < 0.4
+    , http-types >= 0.9 && < 0.10
+    , mime-types >= 0.1 && < 0.2
+    , optparse-generic >= 1.1 && < 1.3
+    , text >= 1.2.2 && < 1.3
+    , unordered-containers >= 0.2.5 && < 0.3
+    , uri-templater >= 0.2 && < 0.3
   exposed-modules:
       GitHubRelease
   other-modules:
@@ -48,11 +42,11 @@
   default-language: Haskell2010
 
 executable github-release
-  main-is: Main.hs
+  main-is: github-release.hs
   hs-source-dirs:
-      source/executable
-  ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N
+      executables
+  ghc-options: -Wall -rtsopts -threaded -with-rtsopts=-N
   build-depends:
-      base
+      base >= 4.8.2 && < 4.11
     , github-release
   default-language: Haskell2010
diff --git a/library/GitHubRelease.hs b/library/GitHubRelease.hs
new file mode 100644
--- /dev/null
+++ b/library/GitHubRelease.hs
@@ -0,0 +1,151 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeOperators #-}
+
+module GitHubRelease where
+
+import Options.Generic (type (<?>))
+
+import qualified Data.Aeson as Aeson
+import qualified Data.ByteString.Char8 as BS8
+import qualified Data.ByteString.Lazy as BSL
+import qualified Data.HashMap.Strict as HashMap
+import qualified Data.Text as Text
+import qualified Data.Version as Version
+import qualified GHC.Generics as Generics
+import qualified Network.HTTP.Client as Client
+import qualified Network.HTTP.Client.TLS as TLS
+import qualified Network.HTTP.Types as HTTP
+import qualified Network.Mime as MIME
+import qualified Network.URI.Template as Template
+import qualified Network.URI.Template.Types as Template
+import qualified Options.Generic as Options
+import qualified Paths_github_release as This
+import qualified System.IO as IO
+import qualified Text.Printf as Printf
+
+data Command
+  = Upload { file :: FilePath <?> "The path to the local file to upload."
+          ,  name :: String <?> "The name to give the file on the release."
+          ,  owner :: String <?> "The GitHub owner, either a user or organization."
+          ,  repo :: String <?> "The GitHub repository name."
+          ,  tag :: String <?> "The tag name."
+          ,  token :: String <?> "Your OAuth2 token."}
+  | Version
+  deriving (Generics.Generic, Show)
+
+instance Options.ParseRecord Command
+
+main :: IO ()
+main = do
+  command <- Options.getRecord (Text.pack "Upload a file to a GitHub release.")
+  runCommand command
+
+runCommand :: Command -> IO ()
+runCommand command =
+  case command of
+    Upload aFile aName anOwner aRepo aTag aToken ->
+      upload
+        (Options.unHelpful aToken)
+        (Options.unHelpful anOwner)
+        (Options.unHelpful aRepo)
+        (Options.unHelpful aTag)
+        (Options.unHelpful aFile)
+        (Options.unHelpful aName)
+    Version -> putStrLn versionString
+
+upload :: String -> String -> String -> String -> FilePath -> String -> IO ()
+upload aToken anOwner aRepo aTag aFile aName = do
+  manager <- Client.newManager TLS.tlsManagerSettings
+  uploadUrl <- getUploadUrl manager aToken anOwner aRepo aTag
+  response <- uploadFile manager uploadUrl aToken aFile aName
+  case HTTP.statusCode (Client.responseStatus response) of
+    201 -> pure ()
+    _ -> do
+      IO.hPrint IO.stderr response
+      BSL.hPutStr IO.stderr (Client.responseBody response)
+      fail "Failed to upload file to release!"
+
+getUploadUrl
+  :: Client.Manager
+  -> String
+  -> String
+  -> String
+  -> String
+  -> IO Template.UriTemplate
+getUploadUrl manager aToken anOwner aRepo aTag = do
+  (Right json) <- getTag manager aToken anOwner aRepo aTag
+  let (Just (Aeson.String text)) = HashMap.lookup (Text.pack "upload_url") json
+  let uploadUrl = Text.unpack text
+  let (Right template) = Template.parseTemplate uploadUrl
+  pure template
+
+getTag
+  :: Client.Manager
+  -> String
+  -> String
+  -> String
+  -> String
+  -> IO (Either String Aeson.Object)
+getTag manager aToken anOwner aRepo aTag = do
+  let format = "https://api.github.com/repos/%s/%s/releases/tags/%s"
+  let url = Printf.printf format anOwner aRepo aTag
+  initialRequest <- Client.parseUrlThrow url
+  let request =
+        initialRequest
+        {Client.requestHeaders = [authorizationHeader aToken, userAgentHeader]}
+  response <- Client.httpLbs request manager
+  let body = Client.responseBody response
+  let json = Aeson.eitherDecode body
+  return json
+
+authorizationHeader :: String -> HTTP.Header
+authorizationHeader aToken =
+  (HTTP.hAuthorization, BS8.pack (Printf.printf "token %s" aToken))
+
+userAgentHeader :: HTTP.Header
+userAgentHeader = (HTTP.hUserAgent, BS8.pack userAgent)
+
+userAgent :: String
+userAgent = Printf.printf "%s/%s-%s" "tfausak" "github-release" versionString
+
+versionString :: String
+versionString = Version.showVersion This.version
+
+uploadFile
+  :: Client.Manager
+  -> Template.UriTemplate
+  -> String
+  -> FilePath
+  -> String
+  -> IO (Client.Response BSL.ByteString)
+uploadFile manager template aToken aFile aName = do
+  contents <- BSL.readFile aFile
+  let body = Client.RequestBodyLBS contents
+  uploadBody manager template aToken body aName
+
+uploadBody
+  :: Client.Manager
+  -> Template.UriTemplate
+  -> String
+  -> Client.RequestBody
+  -> String
+  -> IO (Client.Response BSL.ByteString)
+uploadBody manager template aToken body aName = do
+  let url =
+        Template.render
+          template
+          [("name", Template.WrappedValue (Template.Single aName))]
+  initialRequest <- Client.parseUrlThrow url
+  let request =
+        initialRequest
+        { Client.method = BS8.pack "POST"
+        , Client.requestBody = body
+        , Client.requestHeaders =
+            [ authorizationHeader aToken
+            , (HTTP.hContentType, MIME.defaultMimeLookup (Text.pack aName))
+            , userAgentHeader
+            ]
+        }
+  Client.httpLbs request manager
diff --git a/package.yaml b/package.yaml
deleted file mode 100644
--- a/package.yaml
+++ /dev/null
@@ -1,42 +0,0 @@
-category: Utility
-description: GitHub Release is a command-line utility for uploading files to GitHub
-  releases.
-executables:
-  github-release:
-    dependencies:
-    - base
-    - github-release
-    ghc-options:
-    - -threaded
-    - -rtsopts
-    - -with-rtsopts=-N
-    main: Main.hs
-    source-dirs: source/executable
-extra-source-files:
-- CHANGELOG.markdown
-- package.yaml
-- README.markdown
-- stack.yaml
-ghc-options: -Wall
-github: tfausak/github-release
-library:
-  dependencies:
-  - aeson >=0.9 && <1.3
-  - base >=4.8.2 && <4.11
-  - bytestring >=0.10.6 && <0.11
-  - http-client >=0.4.30 && <0.6
-  - http-client-tls >=0.2.4 && <0.4
-  - http-types >=0.9 && <0.10
-  - mime-types >=0.1 && <0.2
-  - optparse-generic >=1.1 && <1.3
-  - text >=1.2.2 && <1.3
-  - unordered-containers >=0.2.5 && <0.3
-  - uri-templater >=0.2 && <0.3
-  other-modules: Paths_github_release
-  source-dirs: source/library
-license: MIT
-license-file: LICENSE.markdown
-maintainer: Taylor Fausak
-name: github-release
-synopsis: Upload files to GitHub releases.
-version: '1.0.4'
diff --git a/source/executable/Main.hs b/source/executable/Main.hs
deleted file mode 100644
--- a/source/executable/Main.hs
+++ /dev/null
@@ -1,5 +0,0 @@
-module Main
-  ( module GitHubRelease
-  ) where
-
-import GitHubRelease (main)
diff --git a/source/library/GitHubRelease.hs b/source/library/GitHubRelease.hs
deleted file mode 100644
--- a/source/library/GitHubRelease.hs
+++ /dev/null
@@ -1,151 +0,0 @@
-{-# LANGUAGE DataKinds #-}
-{-# LANGUAGE DeriveGeneric #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeOperators #-}
-
-module GitHubRelease where
-
-import Options.Generic (type (<?>))
-
-import qualified Data.Aeson as Aeson
-import qualified Data.ByteString.Char8 as BS8
-import qualified Data.ByteString.Lazy as BSL
-import qualified Data.HashMap.Strict as HashMap
-import qualified Data.Text as Text
-import qualified Data.Version as Version
-import qualified GHC.Generics as Generics
-import qualified Network.HTTP.Client as Client
-import qualified Network.HTTP.Client.TLS as TLS
-import qualified Network.HTTP.Types as HTTP
-import qualified Network.Mime as MIME
-import qualified Network.URI.Template as Template
-import qualified Network.URI.Template.Types as Template
-import qualified Options.Generic as Options
-import qualified Paths_github_release as This
-import qualified System.IO as IO
-import qualified Text.Printf as Printf
-
-data Command
-  = Upload { file :: FilePath <?> "The path to the local file to upload."
-          ,  name :: String <?> "The name to give the file on the release."
-          ,  owner :: String <?> "The GitHub owner, either a user or organization."
-          ,  repo :: String <?> "The GitHub repository name."
-          ,  tag :: String <?> "The tag name."
-          ,  token :: String <?> "Your OAuth2 token."}
-  | Version
-  deriving (Generics.Generic, Show)
-
-instance Options.ParseRecord Command
-
-main :: IO ()
-main = do
-  command <- Options.getRecord (Text.pack "Upload a file to a GitHub release.")
-  runCommand command
-
-runCommand :: Command -> IO ()
-runCommand command =
-  case command of
-    Upload aFile aName anOwner aRepo aTag aToken ->
-      upload
-        (Options.unHelpful aToken)
-        (Options.unHelpful anOwner)
-        (Options.unHelpful aRepo)
-        (Options.unHelpful aTag)
-        (Options.unHelpful aFile)
-        (Options.unHelpful aName)
-    Version -> putStrLn versionString
-
-upload :: String -> String -> String -> String -> FilePath -> String -> IO ()
-upload aToken anOwner aRepo aTag aFile aName = do
-  manager <- Client.newManager TLS.tlsManagerSettings
-  uploadUrl <- getUploadUrl manager aToken anOwner aRepo aTag
-  response <- uploadFile manager uploadUrl aToken aFile aName
-  case HTTP.statusCode (Client.responseStatus response) of
-    201 -> pure ()
-    _ -> do
-      IO.hPrint IO.stderr response
-      BSL.hPutStr IO.stderr (Client.responseBody response)
-      fail "Failed to upload file to release!"
-
-getUploadUrl
-  :: Client.Manager
-  -> String
-  -> String
-  -> String
-  -> String
-  -> IO Template.UriTemplate
-getUploadUrl manager aToken anOwner aRepo aTag = do
-  (Right json) <- getTag manager aToken anOwner aRepo aTag
-  let (Just (Aeson.String text)) = HashMap.lookup (Text.pack "upload_url") json
-  let uploadUrl = Text.unpack text
-  let (Right template) = Template.parseTemplate uploadUrl
-  pure template
-
-getTag
-  :: Client.Manager
-  -> String
-  -> String
-  -> String
-  -> String
-  -> IO (Either String Aeson.Object)
-getTag manager aToken anOwner aRepo aTag = do
-  let format = "https://api.github.com/repos/%s/%s/releases/tags/%s"
-  let url = Printf.printf format anOwner aRepo aTag
-  initialRequest <- Client.parseUrlThrow url
-  let request =
-        initialRequest
-        {Client.requestHeaders = [authorizationHeader aToken, userAgentHeader]}
-  response <- Client.httpLbs request manager
-  let body = Client.responseBody response
-  let json = Aeson.eitherDecode body
-  return json
-
-authorizationHeader :: String -> HTTP.Header
-authorizationHeader aToken =
-  (HTTP.hAuthorization, BS8.pack (Printf.printf "token %s" aToken))
-
-userAgentHeader :: HTTP.Header
-userAgentHeader = (HTTP.hUserAgent, BS8.pack userAgent)
-
-userAgent :: String
-userAgent = Printf.printf "%s/%s-%s" "tfausak" "github-release" versionString
-
-versionString :: String
-versionString = Version.showVersion This.version
-
-uploadFile
-  :: Client.Manager
-  -> Template.UriTemplate
-  -> String
-  -> FilePath
-  -> String
-  -> IO (Client.Response BSL.ByteString)
-uploadFile manager template aToken aFile aName = do
-  contents <- BSL.readFile aFile
-  let body = Client.RequestBodyLBS contents
-  uploadBody manager template aToken body aName
-
-uploadBody
-  :: Client.Manager
-  -> Template.UriTemplate
-  -> String
-  -> Client.RequestBody
-  -> String
-  -> IO (Client.Response BSL.ByteString)
-uploadBody manager template aToken body aName = do
-  let url =
-        Template.render
-          template
-          [("name", Template.WrappedValue (Template.Single aName))]
-  initialRequest <- Client.parseUrlThrow url
-  let request =
-        initialRequest
-        { Client.method = BS8.pack "POST"
-        , Client.requestBody = body
-        , Client.requestHeaders =
-            [ authorizationHeader aToken
-            , (HTTP.hContentType, MIME.defaultMimeLookup (Text.pack aName))
-            , userAgentHeader
-            ]
-        }
-  Client.httpLbs request manager
diff --git a/stack.yaml b/stack.yaml
deleted file mode 100644
--- a/stack.yaml
+++ /dev/null
@@ -1,1 +0,0 @@
-resolver: lts-8.0
