diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,7 @@
+## 0.8.21
+
+* Decode empty inputs as Null [#101](https://github.com/snoyberg/yaml/pull/101)
+
 ## 0.8.20
 
 * Upgrade to libyaml 0.1.7
diff --git a/Data/Yaml/Internal.hs b/Data/Yaml/Internal.hs
--- a/Data/Yaml/Internal.hs
+++ b/Data/Yaml/Internal.hs
@@ -133,12 +133,24 @@
 
 parse :: C.Sink Event Parse Value
 parse = do
-    requireEvent EventStreamStart
-    requireEvent EventDocumentStart
-    res <- parseO
-    requireEvent EventDocumentEnd
-    requireEvent EventStreamEnd
-    return res
+    streamStart <- CL.head
+    case streamStart of
+        Nothing ->
+            -- empty string input
+            return Null
+        Just EventStreamStart -> do
+            documentStart <- CL.head
+            case documentStart of
+                Just EventStreamEnd ->
+                    -- empty file input, comment only string/file input
+                    return Null
+                Just EventDocumentStart -> do
+                    res <- parseO
+                    requireEvent EventDocumentEnd
+                    requireEvent EventStreamEnd
+                    return res
+                _ -> liftIO $ throwIO $ UnexpectedEvent documentStart Nothing
+        _ -> liftIO $ throwIO $ UnexpectedEvent streamStart Nothing
 
 parseScalar :: ByteString -> Anchor -> Style -> Tag
             -> C.Sink Event Parse Text
diff --git a/test/Data/YamlSpec.hs b/test/Data/YamlSpec.hs
--- a/test/Data/YamlSpec.hs
+++ b/test/Data/YamlSpec.hs
@@ -95,7 +95,11 @@
         it "parses when all uppercase" caseUppercaseBool
         it "parses when titlecase" caseTitlecaseBool
     describe "empty input" $ do
-        it "doesn't crash" caseEmptyInput
+        it "parses as Null" caseEmptyInput
+        it "parses as Null from file" caseEmptyInputFile
+    describe "comment only input" $ do
+        it "parses as Null" caseCommentOnlyInput
+        it "parses as Null from file" caseCommentOnlyInputFile
     describe "alias stripping" $ do
         it "works" caseStripAlias
     describe "nulls" $ do
@@ -457,7 +461,20 @@
 caseTitlecaseBool = D.decode "foo: No\nbar: Yes\nbaz: True" @?= obj
 
 caseEmptyInput :: Assertion
-caseEmptyInput = D.decode B8.empty @?= (Nothing :: Maybe D.Value)
+caseEmptyInput = D.decodeEither B8.empty @?= Right D.Null
+
+caseEmptyInputFile :: Assertion
+caseEmptyInputFile = do
+    out <- D.decodeFileEither "test/resources/empty.yaml"
+    either (Left . D.prettyPrintParseException) Right out @?= Right D.Null
+
+caseCommentOnlyInput :: Assertion
+caseCommentOnlyInput = D.decodeEither "# comment\n" @?= Right D.Null
+
+caseCommentOnlyInputFile :: Assertion
+caseCommentOnlyInputFile = do
+    out <- D.decodeFileEither "test/resources/empty2.yaml"
+    either (Left . D.prettyPrintParseException) Right out @?= Right D.Null
 
 checkNull :: T.Text -> Spec
 checkNull x =
diff --git a/yaml.cabal b/yaml.cabal
--- a/yaml.cabal
+++ b/yaml.cabal
@@ -1,5 +1,5 @@
 name:            yaml
-version:         0.8.20
+version:         0.8.21
 license:         BSD3
 license-file:    LICENSE
 author:          Michael Snoyman <michael@snoyman.com>, Anton Ageev <antage@gmail.com>,Kirill Simonov
