diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,11 @@
 Versioning is `MAJOR.MINOR`.
 Major changes are generally backwards-incompatible changes to the interface, minor changes are incremental improvements.
 
+## 1.1
+
+### [Changed]
+- Support _only_ PureScript 0.15
+
 ## 1.0
 
 ### [Added]
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -13,6 +13,16 @@
 
 On the [organization page for PureNix](https://github.com/purenix-org) you will find a number of packages intended to be used with PureNix, including ports of libraries like [purescript-prelude](https://github.com/purenix-org/purescript-prelude).
 
+## Usage
+
+The easiest way to use PureNix is through Spago.
+Simply set `backend = "purenix"`, make sure `purenix` is available in the `PATH`, and build as normal.
+
+When you run `purenix`, manually or through Spago, it will look for the Purescript output directory `./output` in the current working directory.
+It then traverses this directory structure, looks for Purescript's intermediate `corefn.json` files, transpiles the `corefn.json` files to the equivalent Nix code, and writes the output Nix code to `default.nix`.
+
+See the [Getting Started Guide](./docs/quick-start.md) for more in-depth instructions.
+
 ## Code sample
 
 PureScript source, `Main.purs`:
@@ -48,19 +58,19 @@
 
 ```nix
 let
-  module = 
+  module =
     { "Data.A" = import ../Data.A;
       "Data.B" = import ../Data.B;
     };
   foreign = import ./foreign.nix;
   add = foreign.add;
   Nothing = {__tag = "Nothing";};
-  Just = value0: 
+  Just = value0:
     { __tag = "Just";
       __field0 = value0;
     };
   greeting = "Hello, world!";
-  fromMaybe = v: v1: 
+  fromMaybe = v: v1:
     let
       __pattern0 = __fail: if v1.__tag == "Nothing" then let a = v; in a else __fail;
       __pattern1 = __fail: if v1.__tag == "Just" then let a = v1.__field0; in a else __fail;
@@ -74,17 +84,15 @@
 
 There are a couple things to notice here:
 
-- PureScript built-in types like `String`, `Int`, objects, and lists are converted to their corresponding Nix types, as in `greeting`.
+- PureScript built-in types like `String`, `Int`, records, and lists are converted to their corresponding Nix types, as in `greeting`.
 - Data constructors from sum types are available to easily work with in the output Nix file, like `Just` and `Nothing`, although you might want to define named field accessors.
 - Foreign imports are straightforward to define and use, like in `add` and `foo`. The FFI file gets copied into the module's output directory as `foreign.nix`.
 
-## Usage
-
-The easiest way to use PureNix is through Spago.
-Simply set `backend = "purenix"`, make sure `purenix` is available in the `PATH`, and build as normal.
+## Development
 
-When you run `purenix`, manually or through Spago, it will look for the Purescript output directory `./output` in the current working directory.
-It then traverses this directory structure, looks for Purescript's intermediate `corefn.json` files, transpiles the `corefn.json` files to the equivalent Nix code, and writes the output Nix code to `default.nix`.
+You can launch a development shell with the command `nix develop` (as long as you have flakes support enabled in Nix).
+This puts you in a Nix shell with `cabal-install` and GHC setup to compile PureNix, as well as other helpful tools like HLint, HLS, PureScript, Spago, etc.
+From here you should be able to run commands like `cabal build` in order to build PureNix.
 
 ## Warnings
 
diff --git a/purenix.cabal b/purenix.cabal
--- a/purenix.cabal
+++ b/purenix.cabal
@@ -1,12 +1,15 @@
 cabal-version:   2.4
 name:            purenix
-version:         1.0
+version:         1.1
 license:         BSD-3-Clause
 build-type:      Simple
 license-file:    LICENSE
+
 -- category:
 -- description:     description
-synopsis:        Nix backend for PureScript.  Transpile PureScript code to Nix.
+synopsis:
+  Nix backend for PureScript.  Transpile PureScript code to Nix.
+
 author:          Dennis Gosnell, Jonas Carpay
 maintainer:      Dennis Gosnell <cdep.illabout@gmail.com>
 copyright:       2021 Dennis Gosnell, Jonas Carpay
@@ -48,8 +51,7 @@
     , microlens-platform
     , mtl
     , pretty-simple
-    , purescript          ==0.14.4
-    , purescript-cst
+    , purescript          ^>=0.15
     , text
 
 executable purenix
diff --git a/src/PureNix/Convert.hs b/src/PureNix/Convert.hs
--- a/src/PureNix/Convert.hs
+++ b/src/PureNix/Convert.hs
@@ -111,7 +111,7 @@
 expr (Var ann (P.Qualified mqual name)) = localAnn ann $ do
   (_, thisModule, _) <- ask
   pure $ case mqual of
-    Just qual
+    P.ByModuleName qual
       | qual /= thisModule -> N.sel (N.sel (N.var "module") (N.moduleKey qual)) (N.identKey name)
     _ -> N.var (N.mkVar name)
 expr (Accessor ann sel body) = localAnn ann $ flip N.sel (N.stringKey sel) <$> expr body
diff --git a/src/PureNix/Identifiers.hs b/src/PureNix/Identifiers.hs
--- a/src/PureNix/Identifiers.hs
+++ b/src/PureNix/Identifiers.hs
@@ -60,7 +60,8 @@
 -- This was relaxed in 0.14.2:
 -- https://github.com/purescript/purescript/pull/4096
 identToText (PS.GenIdent mvar n) = fromMaybe "__instance" mvar <> T.pack (show n)
-identToText PS.UnusedIdent = error "impossible"
+identToText PS.UnusedIdent = "_"
+identToText (PS.InternalIdent _) = error "impossible"
 
 -- | Make a Nix variable binder from a CoreFn binder.
 --
diff --git a/src/PureNix/Main.hs b/src/PureNix/Main.hs
--- a/src/PureNix/Main.hs
+++ b/src/PureNix/Main.hs
@@ -22,7 +22,7 @@
 defaultMain = do
   let workdir = "."
   let moduleRoot = workdir </> "output"
-  moduleDirs <- filter (/= "cache-db.json") <$> Dir.listDirectory moduleRoot
+  moduleDirs <- filter (not . FP.isExtensionOf "json") <$> Dir.listDirectory moduleRoot
   forM_ moduleDirs $ \rel -> do
     let dir = moduleRoot </> rel
     let file = dir </> "corefn.json"
diff --git a/src/PureNix/Print.hs b/src/PureNix/Print.hs
--- a/src/PureNix/Print.hs
+++ b/src/PureNix/Print.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE DerivingStrategies #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE ScopedTypeVariables #-}
@@ -11,6 +12,7 @@
 import Data.Foldable (toList)
 import Data.List (intersperse)
 import Data.Semigroup (mtimesDefault)
+import qualified Data.Text as Text
 import Data.Text.Lazy.Builder (Builder)
 import qualified Data.Text.Lazy.Builder as TB
 import Lens.Micro.Platform
@@ -170,6 +172,14 @@
 key :: Key -> Printer
 key = text . unKey
 
+ppString :: Text -> Printer
+ppString txt = char '"' <> text escaped <> char '"'
+  where
+    escaped = flip Text.concatMap txt $ \case
+      '\'' -> "\\"
+      '"' -> "\""
+      chr -> Text.singleton chr
+
 ppExpr :: Style -> ExprF Printer -> Printer
 ppExpr _ (Var v) = binder v
 ppExpr _ (Lam arg body) = text (unVar arg) <> ": " <> body
@@ -184,7 +194,7 @@
 ppExpr sty (List l) = delimit sty '[' ']' $ sepBy newline l
 ppExpr _ (Sel a b) = a <> "." <> key b
 ppExpr _ (Path t) = text t
-ppExpr _ (String str) = char '"' <> text str <> char '"'
+ppExpr _ (String str) = ppString str
 ppExpr _ (Int n) = string (show n)
 ppExpr _ (Double x) = string (show x)
 ppExpr Single (Cond c t f) = sepBy space ["if", c, "then", t, "else", f]
