diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Revision history for screenshot-to-clipboard
+
+## 0.1.0.0 -- YYYY-mm-dd
+
+* First version. Released on an unsuspecting world.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,47 @@
+
+# `screenshot-to-clipboard`
+
+[![CI](https://github.com/cdepillabout/screenshot-to-clipboard/actions/workflows/ci.yml/badge.svg)](https://github.com/cdepillabout/screenshot-to-clipboard/actions/workflows/ci.yml)
+[![Hackage](https://img.shields.io/hackage/v/screenshot-to-clipboard.svg)](https://hackage.haskell.org/package/screenshot-to-clipboard)
+[![Stackage LTS](http://stackage.org/package/screenshot-to-clipboard/badge/lts)](http://stackage.org/lts/package/screenshot-to-clipboard)
+[![Stackage Nightly](http://stackage.org/package/screenshot-to-clipboard/badge/nightly)](http://stackage.org/nightly/package/screenshot-to-clipboard)
+[![BSD3 license](https://img.shields.io/badge/license-BSD3-blue.svg)](./LICENSE)
+
+This program provides a simple way to take a screenshot and copy it to your
+system clipboard.
+
+When you run `screenshot-to-clipboard`, it internally runs the
+[`import`](https://imagemagick.org/script/import.php) program from
+[ImageMagick](https://imagemagick.org) to take a screenshot, and then uses
+[GTK](https://www.gtk.org/) to copy that screenshot to your system clipboard.
+
+## Installation
+
+The recommended installation procedure is to use Nix.  With Nix installed, just do:
+
+```console
+$ git clone git@github.com:cdepillabout/screenshot-to-clipboard
+$ cd screenshot-to-clipboard/
+$ nix-build
+```
+
+You can run this program with the output `result/bin/screenshot-to-clipboard` program.
+
+`screenshot-to-clipboard` is also available in Nixpkgs, starting with
+NixOS-22.11 as `haskellPackages.screenshot-to-clipboard`.
+
+It is also possible to build with `cabal` (or `stack`), but you are responsible for
+installing necessary system libraries.  You'll likely need both `imagemagick`,
+and the development packages for GTK.
+
+## Usage
+
+If you run `screenshot-to-clipboard`, it will turn your cursor into a
+cross-hair.  Click and drag to select a portion of the screen to take a
+screenshot.  This screenshot will be copied to your system clipboard.  You can
+paste it into another application.
+
+`screenshot-to-clipboard` will continue running until you've copied _something
+else_ into your system clipboard.  See the long comment in
+[`src/ScreenshotToClipboard.hs`](./src/ScreenshotToClipboard.hs) for why this
+is necessary.
diff --git a/app/Main.hs b/app/Main.hs
new file mode 100644
--- /dev/null
+++ b/app/Main.hs
@@ -0,0 +1,6 @@
+module Main where
+
+import ScreenshotToClipboard (defaultMain)
+
+main :: IO ()
+main = defaultMain
diff --git a/screenshot-to-clipboard.cabal b/screenshot-to-clipboard.cabal
new file mode 100644
--- /dev/null
+++ b/screenshot-to-clipboard.cabal
@@ -0,0 +1,50 @@
+cabal-version:      2.4
+name:               screenshot-to-clipboard
+version:            0.1.0.0
+synopsis:           Take screenshot and copy it to the system clipboard.
+description:
+  This is a small program that shells out to imagemagick to take a screenshot,
+  and then uses GTK to copy it to the system clipboard.
+homepage:           https://github.com/cdepillabout/screenshot-to-clipboard
+bug-reports:        https://github.com/cdepillabout/screenshot-to-clipboard/issues
+license:            BSD-3-Clause
+author:             Dennis Gosnell
+maintainer:         cdep.illabout@gmail.com
+copyright:          2022 Dennis Gosnell
+category:           Utils
+extra-source-files:
+    CHANGELOG.md
+    README.md
+
+library
+  hs-source-dirs:      src
+  exposed-modules:     ScreenshotToClipboard
+  other-modules:       Paths_screenshot_to_clipboard
+  autogen-modules:     Paths_screenshot_to_clipboard
+  build-depends:       base >= 4.15 && < 5
+                     , bytestring
+                     , filepath
+                     , gi-gdk
+                     , gi-gdkpixbuf
+                     , gi-gio
+                     , gi-glib
+                     , gi-gtk
+                     , haskell-gi-base
+                     , process
+                     , temporary
+                     , text
+  default-language:    Haskell2010
+  ghc-options:         -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates
+  -- default-extensions:  DataKinds
+  --                    , DefaultSignatures
+  -- other-extensions:    TemplateHaskell
+  --                    , UndecidableInstances
+  -- pkgconfig-depends:   gtk+-3.0
+  --                    , vte-2.91 >= 0.46
+
+executable screenshot-to-clipboard
+    main-is:          Main.hs
+    build-depends:    base
+                    , screenshot-to-clipboard
+    hs-source-dirs:   app
+    default-language: Haskell2010
diff --git a/src/ScreenshotToClipboard.hs b/src/ScreenshotToClipboard.hs
new file mode 100644
--- /dev/null
+++ b/src/ScreenshotToClipboard.hs
@@ -0,0 +1,77 @@
+
+module ScreenshotToClipboard where
+
+import Control.Monad (when)
+import Data.Functor (void)
+import Data.IORef (IORef, newIORef, atomicModifyIORef')
+import GI.Gdk (displayGetDefault)
+import GI.GdkPixbuf (pixbufNewFromFile)
+import GI.Gtk (clipboardGetDefault, clipboardStore, clipboardSetCanStore, clipboardSetImage, onClipboardOwnerChange)
+import qualified GI.Gtk as Gtk
+import System.Exit (ExitCode(ExitSuccess))
+import System.FilePath ((</>))
+import System.IO.Temp (withSystemTempDirectory)
+import System.Process (readProcessWithExitCode)
+
+defaultMain :: IO ()
+defaultMain =
+  withSystemTempDirectory "screenshot-to-clipboard" $ \tempdir -> do
+    void $ Gtk.init Nothing
+    let imgPath = tempdir </> "image.png"
+
+    -- Take screenshot with `import` program from imagemagick.
+    (importExitCode, _, _) <- readProcessWithExitCode "import" [imgPath] ""
+    when (importExitCode /= ExitSuccess) $
+      err "error when calling `import` to take a screenshot"
+
+    -- Load screenshot into GDK Pixbuf.
+    imgPixbuf <-
+      maybe (err "could not load screenshot image file with gdk pixbuf") pure =<< pixbufNewFromFile imgPath
+
+    -- Get the current display, since it is needed to get the clipboard.
+    display <-
+      maybe (err "could not get default display from GDK") pure =<< displayGetDefault
+
+    -- Get the clipboard and set hint that it should be able to store.
+    clipboard <- clipboardGetDefault display
+    clipboardSetCanStore clipboard Nothing
+
+    -- Add callback for when the clipboard contents change.
+    numberOfCallsIORef <- newIORef 0
+    void $
+      onClipboardOwnerChange clipboard $
+        const (clipboardOwnerChangeCallback numberOfCallsIORef)
+
+    -- Load the screenshot into the clipboard and store it.
+    clipboardSetImage clipboard imgPixbuf
+    clipboardStore clipboard
+
+    -- Start GTK main loop.
+    Gtk.main
+  where
+    err :: String -> a
+    err e = error $ "screenshot-to-clipboard: " <> e
+
+    -- This callback is called everytime the clipboard changes.  It counts the
+    -- number of times it has been called, and it will end the program after
+    -- having been called two times.
+    --
+    -- The first time this function is called will be when this program copies
+    -- the screenshot to the clipboard.  This program then hangs around,
+    -- waiting for something else to be copied to the clipboard.  It tells the
+    -- GTK mainloop to exit only after having been called a second time.
+    --
+    -- The reason for this is because with XMonad (and other non-Gnome window
+    -- managers?), it appears that there is nothing that will persist the
+    -- screenshot after copying it to the clipboard if this program exits.  So
+    -- this program needs to continue running at leaset until ANOTHER program
+    -- actually pastes the screenshot that has been copied to the clipboard.
+    --
+    -- However, this program gets no notification when another program has
+    -- pasted the screenshot.  In order to work around this lack of
+    -- information, this program will just keep running until it sees that
+    -- something else has been copied to the clipboard.
+    clipboardOwnerChangeCallback :: IORef Int -> IO ()
+    clipboardOwnerChangeCallback numberOfCallsIORef = do
+      newNum <- atomicModifyIORef' numberOfCallsIORef (\num -> (num + 1, num + 1))
+      when (newNum >= 2) $ Gtk.mainQuit
