diff --git a/src/Data/Geometry/YX.hs b/src/Data/Geometry/YX.hs
--- a/src/Data/Geometry/YX.hs
+++ b/src/Data/Geometry/YX.hs
@@ -5,7 +5,7 @@
 -- YX rather than XY since layout is row major (first row sorts before the
 -- second, etc.).
 module Data.Geometry.YX ( YX(..)
-                        , rows
+                        , box, rowRange
                         , up, left, right, down
                         , steps4, steps8
                         , byteStringToArray, arrayToByteString ) where
@@ -14,6 +14,7 @@
 import qualified Data.Array.IArray as Array
 import Data.ByteString (ByteString)
 import qualified Data.ByteString.Char8 as BS
+import Data.Foldable (foldl')
 import Data.Ix (Ix)
 import qualified Data.Ix as Ix
 import Data.List (groupBy)
@@ -46,9 +47,15 @@
   inRange (YX yl xl, YX yu xu) (YX y x) =
     Ix.inRange (yl, yu) y && Ix.inRange (xl, xu) x
 
+-- | The smallest rectangle containing the input coordinates.
+box :: Foldable f => f YX -> Maybe (YX, YX)
+box = foldl' go Nothing where
+  go Nothing yx = Just (yx, yx)
+  go (Just (tl, br)) yx = Just (lift2 min tl yx, lift2 max br yx)
+
 -- | All coordinates, grouped by row.
-rows :: (YX, YX) -> [[YX]]
-rows = groupBy (\(YX y1 _) (YX y2 _) -> y1 == y2) . Ix.range
+rowRange :: (YX, YX) -> [[YX]]
+rowRange = groupBy (\(YX y1 _) (YX y2 _) -> y1 == y2) . Ix.range
 
 -- | Basic steps.
 up, left, right, down :: YX
@@ -84,4 +91,4 @@
 -- | Reverse of `byteStringToArray`
 arrayToByteString :: (IArray a e) => (e -> Char) -> a YX e -> ByteString
 arrayToByteString f arr = BS.intercalate "\n" lines where
-  lines = fmap (BS.pack . fmap (f . (arr Array.!))) . rows . Array.bounds $ arr
+  lines = fmap (BS.pack . fmap (f . (arr Array.!))) . rowRange . Array.bounds $ arr
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -3,13 +3,18 @@
 import qualified Data.Array.IArray as Array
 import Data.Char (digitToInt)
 import Data.Either (isLeft)
-import Data.Geometry.YX (YX)
+import Data.Geometry.YX (YX(..))
 import qualified Data.Geometry.YX as YX
 import Test.Hspec
 import Test.Hspec.QuickCheck
 
 main :: IO ()
 main = hspec $ do
+  describe "box" $ do
+    it "should support empty input" $ do
+      YX.box [] `shouldBe` Nothing
+    it "should support simple input" $ do
+      YX.box [YX 2 1, YX 2 2, YX 1 0] `shouldBe` Just (YX 1 0, YX 2 2)
   describe "bytestring conversions" $ do
     it "should parse a simple square case" $ do
       let
diff --git a/yx.cabal b/yx.cabal
--- a/yx.cabal
+++ b/yx.cabal
@@ -1,5 +1,5 @@
 name:                yx
-version:             0.0.1.1
+version:             0.0.2.0
 synopsis:            Row-major coordinates
 description:         https://github.com/mtth/yx
 homepage:            https://github.com/mtth/yx
