diff --git a/example/example.cabal b/example/example.cabal
--- a/example/example.cabal
+++ b/example/example.cabal
@@ -17,7 +17,7 @@
   GHC ==8.4.4
    || ==8.6.5
    || ==8.8.4
-   || ==8.10.2
+   || ==8.10.4
 
 library
   ghc-options:      -Wall
diff --git a/servant-openapi3.cabal b/servant-openapi3.cabal
--- a/servant-openapi3.cabal
+++ b/servant-openapi3.cabal
@@ -1,5 +1,5 @@
 name:                servant-openapi3
-version:             2.0.1.1
+version:             2.0.1.2
 synopsis:            Generate a Swagger/OpenAPI/OAS 3.0 specification for your servant API.
 description:
   Swagger is a project used to describe and document RESTful APIs. The core of the 
@@ -32,7 +32,7 @@
   GHC ==8.4.4
    || ==8.6.5
    || ==8.8.4
-   || ==8.10.2
+   || ==8.10.4
 
 extra-source-files:
     README.md
@@ -80,10 +80,10 @@
                      , bytestring                >=0.10.8.1 && <0.11
                      , http-media                >=0.7.1.3  && <0.9
                      , insert-ordered-containers >=0.2.1.0  && <0.3
-                     , lens                      >=4.17     && <4.20
+                     , lens                      >=4.17     && <5.1
                      , servant                   >=0.17     && <0.19
                      , singleton-bool            >=0.1.4    && <0.2
-                     , openapi3                  >=3.0.0    && <4.0
+                     , openapi3                  >=3.0.0    && <3.2
                      , text                      >=1.2.3.0  && <1.3
                      , unordered-containers      >=0.2.9.0  && <0.3
 
@@ -120,7 +120,8 @@
                   , lens-aeson >=1.0.2    && <1.2
                   , servant
                   , servant-openapi3
-                  , openapi3
+                    -- openapi3 3.1.0 fixes some ordering-related issues, making tests stable
+                  , openapi3 >= 3.1.0
                   , text
                   , template-haskell
                   , utf8-string >=1.0.1.1 && <1.1
diff --git a/src/Servant/OpenApi.hs b/src/Servant/OpenApi.hs
--- a/src/Servant/OpenApi.hs
+++ b/src/Servant/OpenApi.hs
@@ -57,6 +57,7 @@
 -- >>> import Test.Hspec
 -- >>> import Test.QuickCheck
 -- >>> import qualified Data.ByteString.Lazy.Char8 as BSL8
+-- >>> import Servant.OpenApi.Internal.Test
 -- >>> :set -XDataKinds
 -- >>> :set -XDeriveDataTypeable
 -- >>> :set -XDeriveGeneric
@@ -98,8 +99,114 @@
 -- $generate
 -- In order to generate @'OpenApi'@ specification for a servant API, just use @'toOpenApi'@:
 --
--- >>> BSL8.putStrLn $ encode $ toOpenApi (Proxy :: Proxy UserAPI)
--- {"openapi":"3.0.0","info":{"version":"","title":""},"paths":{"/":{"get":{"responses":{"200":{"content":{"application/json;charset=utf-8":{"schema":{"items":{"$ref":"#/components/schemas/User"},"type":"array"}}},"description":""}}},"post":{"requestBody":{"content":{"application/json;charset=utf-8":{"schema":{"$ref":"#/components/schemas/User"}}}},"responses":{"400":{"description":"Invalid `body`"},"200":{"content":{"application/json;charset=utf-8":{"schema":{"$ref":"#/components/schemas/UserId"}}},"description":""}}}},"/{user_id}":{"get":{"parameters":[{"required":true,"schema":{"type":"integer"},"in":"path","name":"user_id"}],"responses":{"404":{"description":"`user_id` not found"},"200":{"content":{"application/json;charset=utf-8":{"schema":{"$ref":"#/components/schemas/User"}}},"description":""}}}}},"components":{"schemas":{"User":{"required":["name","age"],"type":"object","properties":{"age":{"maximum":9223372036854775807,"minimum":-9223372036854775808,"type":"integer"},"name":{"type":"string"}}},"UserId":{"type":"integer"}}}}
+-- >>> BSL8.putStrLn $ encodePretty $ toOpenApi (Proxy :: Proxy UserAPI)
+-- {
+--     "components": {
+--         "schemas": {
+--             "User": {
+--                 "properties": {
+--                     "age": {
+--                         "maximum": 9223372036854775807,
+--                         "minimum": -9223372036854775808,
+--                         "type": "integer"
+--                     },
+--                     "name": {
+--                         "type": "string"
+--                     }
+--                 },
+--                 "required": [
+--                     "name",
+--                     "age"
+--                 ],
+--                 "type": "object"
+--             },
+--             "UserId": {
+--                 "type": "integer"
+--             }
+--         }
+--     },
+--     "info": {
+--         "title": "",
+--         "version": ""
+--     },
+--     "openapi": "3.0.0",
+--     "paths": {
+--         "/": {
+--             "get": {
+--                 "responses": {
+--                     "200": {
+--                         "content": {
+--                             "application/json;charset=utf-8": {
+--                                 "schema": {
+--                                     "items": {
+--                                         "$ref": "#/components/schemas/User"
+--                                     },
+--                                     "type": "array"
+--                                 }
+--                             }
+--                         },
+--                         "description": ""
+--                     }
+--                 }
+--             },
+--             "post": {
+--                 "requestBody": {
+--                     "content": {
+--                         "application/json;charset=utf-8": {
+--                             "schema": {
+--                                 "$ref": "#/components/schemas/User"
+--                             }
+--                         }
+--                     }
+--                 },
+--                 "responses": {
+--                     "200": {
+--                         "content": {
+--                             "application/json;charset=utf-8": {
+--                                 "schema": {
+--                                     "$ref": "#/components/schemas/UserId"
+--                                 }
+--                             }
+--                         },
+--                         "description": ""
+--                     },
+--                     "400": {
+--                         "description": "Invalid `body`"
+--                     }
+--                 }
+--             }
+--         },
+--         "/{user_id}": {
+--             "get": {
+--                 "parameters": [
+--                     {
+--                         "in": "path",
+--                         "name": "user_id",
+--                         "required": true,
+--                         "schema": {
+--                             "type": "integer"
+--                         }
+--                     }
+--                 ],
+--                 "responses": {
+--                     "200": {
+--                         "content": {
+--                             "application/json;charset=utf-8": {
+--                                 "schema": {
+--                                     "$ref": "#/components/schemas/User"
+--                                 }
+--                             }
+--                         },
+--                         "description": ""
+--                     },
+--                     "404": {
+--                         "description": "`user_id` not found"
+--                     }
+--                 }
+--             }
+--         }
+--     }
+-- }
 --
 -- By default @'toOpenApi'@ will generate specification for all API routes, parameters, headers, responses and data schemas.
 --
@@ -113,14 +220,129 @@
 -- We can add this information using field lenses from @"Data.OpenApi"@:
 --
 -- >>> :{
--- BSL8.putStrLn $ encode $ toOpenApi (Proxy :: Proxy UserAPI)
+-- BSL8.putStrLn $ encodePretty $ toOpenApi (Proxy :: Proxy UserAPI)
 --   & info.title        .~ "User API"
 --   & info.version      .~ "1.0"
 --   & info.description  ?~ "This is an API for the Users service"
 --   & info.license      ?~ "MIT"
 --   & servers           .~ ["https://example.com"]
 -- :}
--- {"openapi":"3.0.0","info":{"version":"1.0","title":"User API","license":{"name":"MIT"},"description":"This is an API for the Users service"},"servers":[{"url":"https://example.com"}],"paths":{"/":{"get":{"responses":{"200":{"content":{"application/json;charset=utf-8":{"schema":{"items":{"$ref":"#/components/schemas/User"},"type":"array"}}},"description":""}}},"post":{"requestBody":{"content":{"application/json;charset=utf-8":{"schema":{"$ref":"#/components/schemas/User"}}}},"responses":{"400":{"description":"Invalid `body`"},"200":{"content":{"application/json;charset=utf-8":{"schema":{"$ref":"#/components/schemas/UserId"}}},"description":""}}}},"/{user_id}":{"get":{"parameters":[{"required":true,"schema":{"type":"integer"},"in":"path","name":"user_id"}],"responses":{"404":{"description":"`user_id` not found"},"200":{"content":{"application/json;charset=utf-8":{"schema":{"$ref":"#/components/schemas/User"}}},"description":""}}}}},"components":{"schemas":{"User":{"required":["name","age"],"type":"object","properties":{"age":{"maximum":9223372036854775807,"minimum":-9223372036854775808,"type":"integer"},"name":{"type":"string"}}},"UserId":{"type":"integer"}}}}
+-- {
+--     "components": {
+--         "schemas": {
+--             "User": {
+--                 "properties": {
+--                     "age": {
+--                         "maximum": 9223372036854775807,
+--                         "minimum": -9223372036854775808,
+--                         "type": "integer"
+--                     },
+--                     "name": {
+--                         "type": "string"
+--                     }
+--                 },
+--                 "required": [
+--                     "name",
+--                     "age"
+--                 ],
+--                 "type": "object"
+--             },
+--             "UserId": {
+--                 "type": "integer"
+--             }
+--         }
+--     },
+--     "info": {
+--         "description": "This is an API for the Users service",
+--         "license": {
+--             "name": "MIT"
+--         },
+--         "title": "User API",
+--         "version": "1.0"
+--     },
+--     "openapi": "3.0.0",
+--     "paths": {
+--         "/": {
+--             "get": {
+--                 "responses": {
+--                     "200": {
+--                         "content": {
+--                             "application/json;charset=utf-8": {
+--                                 "schema": {
+--                                     "items": {
+--                                         "$ref": "#/components/schemas/User"
+--                                     },
+--                                     "type": "array"
+--                                 }
+--                             }
+--                         },
+--                         "description": ""
+--                     }
+--                 }
+--             },
+--             "post": {
+--                 "requestBody": {
+--                     "content": {
+--                         "application/json;charset=utf-8": {
+--                             "schema": {
+--                                 "$ref": "#/components/schemas/User"
+--                             }
+--                         }
+--                     }
+--                 },
+--                 "responses": {
+--                     "200": {
+--                         "content": {
+--                             "application/json;charset=utf-8": {
+--                                 "schema": {
+--                                     "$ref": "#/components/schemas/UserId"
+--                                 }
+--                             }
+--                         },
+--                         "description": ""
+--                     },
+--                     "400": {
+--                         "description": "Invalid `body`"
+--                     }
+--                 }
+--             }
+--         },
+--         "/{user_id}": {
+--             "get": {
+--                 "parameters": [
+--                     {
+--                         "in": "path",
+--                         "name": "user_id",
+--                         "required": true,
+--                         "schema": {
+--                             "type": "integer"
+--                         }
+--                     }
+--                 ],
+--                 "responses": {
+--                     "200": {
+--                         "content": {
+--                             "application/json;charset=utf-8": {
+--                                 "schema": {
+--                                     "$ref": "#/components/schemas/User"
+--                                 }
+--                             }
+--                         },
+--                         "description": ""
+--                     },
+--                     "404": {
+--                         "description": "`user_id` not found"
+--                     }
+--                 }
+--             }
+--         }
+--     },
+--     "servers": [
+--         {
+--             "url": "https://example.com"
+--         }
+--     ]
+-- }
 --
 -- It is also useful to annotate or modify certain endpoints.
 -- @'subOperations'@ provides a convenient way to zoom into a part of an API.
@@ -134,11 +356,136 @@
 -- >>> let getOps  = subOperations (Proxy :: Proxy (GetUsers :<|> GetUser)) (Proxy :: Proxy UserAPI)
 -- >>> let postOps = subOperations (Proxy :: Proxy PostUser) (Proxy :: Proxy UserAPI)
 -- >>> :{
--- BSL8.putStrLn $ encode $ toOpenApi (Proxy :: Proxy UserAPI)
+-- BSL8.putStrLn $ encodePretty $ toOpenApi (Proxy :: Proxy UserAPI)
 --   & applyTagsFor getOps  ["get"  & description ?~ "GET operations"]
 --   & applyTagsFor postOps ["post" & description ?~ "POST operations"]
 -- :}
--- {"openapi":"3.0.0","info":{"version":"","title":""},"paths":{"/":{"get":{"tags":["get"],"responses":{"200":{"content":{"application/json;charset=utf-8":{"schema":{"items":{"$ref":"#/components/schemas/User"},"type":"array"}}},"description":""}}},"post":{"tags":["post"],"requestBody":{"content":{"application/json;charset=utf-8":{"schema":{"$ref":"#/components/schemas/User"}}}},"responses":{"400":{"description":"Invalid `body`"},"200":{"content":{"application/json;charset=utf-8":{"schema":{"$ref":"#/components/schemas/UserId"}}},"description":""}}}},"/{user_id}":{"get":{"tags":["get"],"parameters":[{"required":true,"schema":{"type":"integer"},"in":"path","name":"user_id"}],"responses":{"404":{"description":"`user_id` not found"},"200":{"content":{"application/json;charset=utf-8":{"schema":{"$ref":"#/components/schemas/User"}}},"description":""}}}}},"components":{"schemas":{"User":{"required":["name","age"],"type":"object","properties":{"age":{"maximum":9223372036854775807,"minimum":-9223372036854775808,"type":"integer"},"name":{"type":"string"}}},"UserId":{"type":"integer"}}},"tags":[{"name":"get","description":"GET operations"},{"name":"post","description":"POST operations"}]}
+-- {
+--     "components": {
+--         "schemas": {
+--             "User": {
+--                 "properties": {
+--                     "age": {
+--                         "maximum": 9223372036854775807,
+--                         "minimum": -9223372036854775808,
+--                         "type": "integer"
+--                     },
+--                     "name": {
+--                         "type": "string"
+--                     }
+--                 },
+--                 "required": [
+--                     "name",
+--                     "age"
+--                 ],
+--                 "type": "object"
+--             },
+--             "UserId": {
+--                 "type": "integer"
+--             }
+--         }
+--     },
+--     "info": {
+--         "title": "",
+--         "version": ""
+--     },
+--     "openapi": "3.0.0",
+--     "paths": {
+--         "/": {
+--             "get": {
+--                 "responses": {
+--                     "200": {
+--                         "content": {
+--                             "application/json;charset=utf-8": {
+--                                 "schema": {
+--                                     "items": {
+--                                         "$ref": "#/components/schemas/User"
+--                                     },
+--                                     "type": "array"
+--                                 }
+--                             }
+--                         },
+--                         "description": ""
+--                     }
+--                 },
+--                 "tags": [
+--                     "get"
+--                 ]
+--             },
+--             "post": {
+--                 "requestBody": {
+--                     "content": {
+--                         "application/json;charset=utf-8": {
+--                             "schema": {
+--                                 "$ref": "#/components/schemas/User"
+--                             }
+--                         }
+--                     }
+--                 },
+--                 "responses": {
+--                     "200": {
+--                         "content": {
+--                             "application/json;charset=utf-8": {
+--                                 "schema": {
+--                                     "$ref": "#/components/schemas/UserId"
+--                                 }
+--                             }
+--                         },
+--                         "description": ""
+--                     },
+--                     "400": {
+--                         "description": "Invalid `body`"
+--                     }
+--                 },
+--                 "tags": [
+--                     "post"
+--                 ]
+--             }
+--         },
+--         "/{user_id}": {
+--             "get": {
+--                 "parameters": [
+--                     {
+--                         "in": "path",
+--                         "name": "user_id",
+--                         "required": true,
+--                         "schema": {
+--                             "type": "integer"
+--                         }
+--                     }
+--                 ],
+--                 "responses": {
+--                     "200": {
+--                         "content": {
+--                             "application/json;charset=utf-8": {
+--                                 "schema": {
+--                                     "$ref": "#/components/schemas/User"
+--                                 }
+--                             }
+--                         },
+--                         "description": ""
+--                     },
+--                     "404": {
+--                         "description": "`user_id` not found"
+--                     }
+--                 },
+--                 "tags": [
+--                     "get"
+--                 ]
+--             }
+--         }
+--     },
+--     "tags": [
+--         {
+--             "description": "GET operations",
+--             "name": "get"
+--         },
+--         {
+--             "description": "POST operations",
+--             "name": "post"
+--         }
+--     ]
+-- }
 --
 -- This applies @\"get\"@ tag to the @GET@ endpoints and @\"post\"@ tag to the @POST@ endpoint of the User API.
 
diff --git a/src/Servant/OpenApi/Internal.hs b/src/Servant/OpenApi/Internal.hs
--- a/src/Servant/OpenApi/Internal.hs
+++ b/src/Servant/OpenApi/Internal.hs
@@ -32,6 +32,7 @@
 import           Data.Singletons.Bool
 import           Data.Text                  (Text)
 import qualified Data.Text                  as Text
+import           Data.Typeable              (Typeable)
 import           GHC.TypeLits
 import           Network.HTTP.Media         (MediaType)
 import           Servant.API
@@ -234,7 +235,7 @@
         , _openApiExternalDocs = _openApiExternalDocs s <|> _openApiExternalDocs t
         }
 
-instance ToSchema a => ToSchema (WithStatus s a) where
+instance (Typeable (WithStatus s a), ToSchema a) => ToSchema (WithStatus s a) where
   declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy a)
 #endif
 
diff --git a/src/Servant/OpenApi/Internal/Orphans.hs b/src/Servant/OpenApi/Internal/Orphans.hs
--- a/src/Servant/OpenApi/Internal/Orphans.hs
+++ b/src/Servant/OpenApi/Internal/Orphans.hs
@@ -1,14 +1,17 @@
 {-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 module Servant.OpenApi.Internal.Orphans where
 
 import Data.OpenApi
 import Data.Proxy            (Proxy (..))
+import Data.Typeable         (Typeable)
 import Servant.Types.SourceT (SourceT)
 
 -- | Pretend that 'SourceT m a' is '[a]'.
 --
 -- @since 1.1.7
 --
-instance ToSchema a => ToSchema (SourceT m a) where
+instance (Typeable (SourceT m a), ToSchema a) => ToSchema (SourceT m a) where
     declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy [a])
diff --git a/src/Servant/OpenApi/Internal/Test.hs b/src/Servant/OpenApi/Internal/Test.hs
--- a/src/Servant/OpenApi/Internal/Test.hs
+++ b/src/Servant/OpenApi/Internal/Test.hs
@@ -7,7 +7,8 @@
 module Servant.OpenApi.Internal.Test where
 
 import           Data.Aeson                     (ToJSON (..))
-import           Data.Aeson.Encode.Pretty       (encodePretty)
+import qualified Data.Aeson.Encode.Pretty       as P
+import qualified Data.ByteString.Lazy           as BSL
 import           Data.OpenApi                   (Pattern, ToSchema, toSchema)
 import           Data.OpenApi.Schema.Validation
 import           Data.Text                      (Text)
@@ -156,19 +157,19 @@
 -- <BLANKLINE>
 -- OpenApi Schema:
 -- {
---     "required": [
---         "name",
---         "phone"
---     ],
---     "type": "object",
 --     "properties": {
---         "phone": {
---             "type": "integer"
---         },
 --         "name": {
 --             "type": "string"
+--         },
+--         "phone": {
+--             "type": "integer"
 --         }
---     }
+--     },
+--     "required": [
+--         "name",
+--         "phone"
+--     ],
+--     "type": "object"
 -- }
 -- <BLANKLINE>
 --
@@ -198,3 +199,6 @@
 maybeCounterExample :: Maybe String -> Property
 maybeCounterExample Nothing  = property True
 maybeCounterExample (Just s) = counterexample s (property False)
+
+encodePretty :: ToJSON a => a -> BSL.ByteString
+encodePretty = P.encodePretty' $ P.defConfig { P.confCompare = P.compare }
