diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,11 @@
-## [_Unreleased_](https://github.com/freckle/hspec-junit-formatter/compare/v1.0.2.2...main)
+## [_Unreleased_](https://github.com/freckle/hspec-junit-formatter/compare/v1.0.3.0...main)
 
 None
+
+## [v1.0.3.0](https://github.com/freckle/hspec-junit-formatter/compare/v1.0.2.2...v1.0.3.0)
+
+- Add `hspecJUnit` and environment-variable configuration
+- Fix `file` attribute not respecting source-path-prefix
 
 ## [v1.0.2.2](https://github.com/freckle/hspec-junit-formatter/compare/v1.0.2.1...v1.0.2.2)
 
diff --git a/README.lhs b/README.lhs
--- a/README.lhs
+++ b/README.lhs
@@ -14,16 +14,17 @@
 
 ```haskell
 import Test.Hspec
-import Test.Hspec.Core.Runner (defaultConfig, hspecWith)
 import Test.Hspec.JUnit
+import System.Environment (setEnv)
 
 main :: IO ()
 main = do
-  let
-    junitConfig = setJUnitConfigOutputDirectory "/tmp" $ defaultJUnitConfig "my-tests"
-    hspecConfig = configWithJUnit junitConfig defaultConfig
+  -- Most likely done in your CI setup
+  setEnv "JUNIT_ENABLED" "1"
+  setEnv "JUNIT_OUTPUT_DIRECTORY" "/tmp"
+  setEnv "JUNIT_SUITE_NAME" "my-tests"
 
-  hspecWith hspecConfig spec
+  hspecJUnit spec
 
 spec :: Spec
 spec = describe "Addition" $ do
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -14,16 +14,17 @@
 
 ```haskell
 import Test.Hspec
-import Test.Hspec.Core.Runner (defaultConfig, hspecWith)
 import Test.Hspec.JUnit
+import System.Environment (setEnv)
 
 main :: IO ()
 main = do
-  let
-    junitConfig = setJUnitConfigOutputDirectory "/tmp" $ defaultJUnitConfig "my-tests"
-    hspecConfig = configWithJUnit junitConfig defaultConfig
+  -- Most likely done in your CI setup
+  setEnv "JUNIT_ENABLED" "1"
+  setEnv "JUNIT_OUTPUT_DIRECTORY" "/tmp"
+  setEnv "JUNIT_SUITE_NAME" "my-tests"
 
-  hspecWith hspecConfig spec
+  hspecJUnit spec
 
 spec :: Spec
 spec = describe "Addition" $ do
diff --git a/hspec-junit-formatter.cabal b/hspec-junit-formatter.cabal
--- a/hspec-junit-formatter.cabal
+++ b/hspec-junit-formatter.cabal
@@ -1,6 +1,6 @@
 cabal-version:      1.12
 name:               hspec-junit-formatter
-version:            1.0.2.2
+version:            1.0.3.0
 license:            MIT
 license-file:       LICENSE
 copyright:          2021 Renaissance Learning Inc
@@ -18,6 +18,7 @@
     README.md
     CHANGELOG.md
     tests/golden.xml
+    tests/golden-prefixed.xml
 
 source-repository head
     type:     git
@@ -25,9 +26,11 @@
 
 library
     exposed-modules:
+        Test.Hspec.Core.Runner.Ext
         Test.HSpec.JUnit
         Test.Hspec.JUnit
         Test.Hspec.JUnit.Config
+        Test.Hspec.JUnit.Config.Env
         Test.HSpec.JUnit.Render
         Test.Hspec.JUnit.Render
         Test.HSpec.JUnit.Schema
diff --git a/library/Test/Hspec/Core/Runner/Ext.hs b/library/Test/Hspec/Core/Runner/Ext.hs
new file mode 100644
--- /dev/null
+++ b/library/Test/Hspec/Core/Runner/Ext.hs
@@ -0,0 +1,27 @@
+{-# LANGUAGE CPP #-}
+
+-- | Compatibility module for 'configAvailableFormatters'
+--
+-- This feature is only available in hspec >= 2.9. Note that this module doesn't
+-- do anything to backport the feature; it just supplies a function that will
+-- use it when possible and safely no-op when not.
+--
+module Test.Hspec.Core.Runner.Ext
+  ( configAddAvailableFormatter
+  ) where
+
+import Prelude
+
+import Test.Hspec.Core.Format (Format, FormatConfig)
+import Test.Hspec.Core.Runner (Config(..))
+
+configAddAvailableFormatter
+  :: String -> (FormatConfig -> IO Format) -> Config -> Config
+#if MIN_VERSION_hspec_core(2,9,0)
+configAddAvailableFormatter name format config = config
+  { configAvailableFormatters =
+    configAvailableFormatters config <> [(name, format)]
+  }
+#else
+configAddAvailableFormatter _ _ = id
+#endif
diff --git a/library/Test/Hspec/JUnit.hs b/library/Test/Hspec/JUnit.hs
--- a/library/Test/Hspec/JUnit.hs
+++ b/library/Test/Hspec/JUnit.hs
@@ -1,5 +1,14 @@
 module Test.Hspec.JUnit
-  ( configWithJUnit
+  (
+  -- * Runners
+    hspecJUnit
+  , hspecJUnitWith
+
+  -- * Directly modifying 'Config'
+  , configWithJUnit
+  , configWithJUnitAvailable
+
+  -- * Actual format function
   , junitFormat
 
   -- * Configuration
@@ -22,16 +31,55 @@
 import System.FilePath (splitFileName)
 import Test.Hspec.Core.Format
 import Test.Hspec.Core.Runner
+import Test.Hspec.Core.Runner.Ext
+import Test.Hspec.Core.Spec (Spec)
 import Test.Hspec.JUnit.Config
+import Test.Hspec.JUnit.Config.Env
 import Test.Hspec.JUnit.Render (renderJUnit)
 import qualified Test.Hspec.JUnit.Schema as Schema
 import Text.XML.Stream.Render (def, renderBytes)
 
+-- | Like 'hspec' but adds JUNit functionality
+--
+-- To actually /use/ the JUnit format, you must set @JUNIT_ENABLED=1@ in the
+-- environment; by default, this function just behaves like 'hspec'.
+--
+-- (If using hspec >= 2.9, running tests with @--test-arguments="-f junit"@ also
+-- works.)
+--
+-- All configuration of the JUnit report occurs through environment variables.
+--
+-- See "Test.Hspec.JUnit.Config" and "Test.Hspec.JUnit.Config.Env".
+--
+hspecJUnit :: Spec -> IO ()
+hspecJUnit = hspecJUnitWith defaultConfig
+
+-- | 'hspecJUnit' but built on a non-default 'Config'
+hspecJUnitWith :: Config -> Spec -> IO ()
+hspecJUnitWith config spec = do
+  junitEnabled <- envJUnitEnabled
+  junitConfig <- envJUnitConfig
+
+  let
+    modify = if junitEnabled then configWithJUnit junitConfig else id
+    base = configWithJUnitAvailable junitConfig config
+
+  hspecWith (modify base) spec
+
 -- | Modify an Hspec 'Config' to use 'junitFormat'
 configWithJUnit :: JUnitConfig -> Config -> Config
 configWithJUnit junitConfig config =
   config { configFormat = Just $ junitFormat junitConfig }
 
+-- | Modify an Hspec 'Config' to have the 'junitFormat' /available/
+--
+-- Adds @junit@ to the list of available options for @-f, --format@.
+--
+-- __NOTE__: This only works with hspec >= 2.9, otherwise it is a no-op.
+--
+configWithJUnitAvailable :: JUnitConfig -> Config -> Config
+configWithJUnitAvailable = configAddAvailableFormatter "junit" . junitFormat
+
 -- | Hspec 'configFormat' that generates a JUnit report
 junitFormat :: JUnitConfig -> FormatConfig -> IO Format
 junitFormat junitConfig _config = pure $ \case
@@ -81,7 +129,8 @@
   :: (FilePath -> FilePath) -> Text -> Text -> Item -> Schema.TestCase
 itemToTestCase applyPrefix group name item = Schema.TestCase
   { testCaseLocation =
-    toSchemaLocation <$> (itemResultLocation item <|> itemLocation item)
+    toSchemaLocation applyPrefix
+      <$> (itemResultLocation item <|> itemLocation item)
   , testCaseClassName = group
   , testCaseName = name
   , testCaseDuration = unSeconds $ itemDuration item
@@ -133,9 +182,9 @@
   Pending mLocation _ -> mLocation
   Failure mLocation _ -> mLocation
 
-toSchemaLocation :: Location -> Schema.Location
-toSchemaLocation Location {..} = Schema.Location
-  { Schema.locationFile = locationFile
+toSchemaLocation :: (FilePath -> FilePath) -> Location -> Schema.Location
+toSchemaLocation applyPrefix Location {..} = Schema.Location
+  { Schema.locationFile = applyPrefix locationFile
   , Schema.locationLine = fromIntegral $ max 0 locationLine
   }
 
diff --git a/library/Test/Hspec/JUnit/Config.hs b/library/Test/Hspec/JUnit/Config.hs
--- a/library/Test/Hspec/JUnit/Config.hs
+++ b/library/Test/Hspec/JUnit/Config.hs
@@ -6,6 +6,7 @@
   , setJUnitConfigOutputDirectory
   , setJUnitConfigOutputName
   , setJUnitConfigOutputFile
+  , setJUnitConfigSuiteName
   , setJUnitConfigSourcePathPrefix
 
   -- * Use
@@ -62,6 +63,9 @@
 --
 setJUnitConfigOutputFile :: FilePath -> JUnitConfig -> JUnitConfig
 setJUnitConfigOutputFile x config = config { junitConfigOutputFile = Just x }
+
+setJUnitConfigSuiteName :: Text -> JUnitConfig -> JUnitConfig
+setJUnitConfigSuiteName x config = config { junitConfigSuiteName = x }
 
 -- | Set a prefix to apply to source paths in the report
 --
diff --git a/library/Test/Hspec/JUnit/Config/Env.hs b/library/Test/Hspec/JUnit/Config/Env.hs
new file mode 100644
--- /dev/null
+++ b/library/Test/Hspec/JUnit/Config/Env.hs
@@ -0,0 +1,48 @@
+-- | Load a 'JUnitConfig' using environment variables
+module Test.Hspec.JUnit.Config.Env
+    ( envJUnitEnabled
+    , envJUnitConfig
+    ) where
+
+import Prelude
+
+import Data.Semigroup (Endo(..))
+import Data.Text (pack)
+import System.Directory (getCurrentDirectory)
+import System.Environment (lookupEnv)
+import System.FilePath (takeBaseName)
+import Test.Hspec.JUnit.Config
+
+-- | Is @JUNIT_ENABLED=1@ set in the environment?
+envJUnitEnabled :: IO Bool
+envJUnitEnabled = (== Just "1") <$> lookupEnv (envPrefix <> "ENABLED")
+
+-- | Produce a 'JUnitConfig' by reading environment variables
+--
+-- Variable names align with setter functions from "Test.Hspec.JUnit.Config":
+--
+-- * @JUNIT_OUTPUT_DIRECTORY@ 'setJUnitConfigOutputDirectory'
+-- * @JUNIT_OUTPUT_NAME@ 'setJUnitConfigOutputName
+-- * and so on
+--
+envJUnitConfig :: IO JUnitConfig
+envJUnitConfig = do
+  modify <- appEndo . foldMap Endo <$> sequence
+    [ lookupEnvOverride "OUTPUT_DIRECTORY" setJUnitConfigOutputDirectory
+    , lookupEnvOverride "OUTPUT_NAME" setJUnitConfigOutputName
+    , lookupEnvOverride "OUTPUT_FILE" setJUnitConfigOutputFile
+    , lookupEnvOverride "SUITE_NAME" $ setJUnitConfigSuiteName . pack
+    , lookupEnvOverride "SOURCE_PATH_PREFIX" setJUnitConfigSourcePathPrefix
+    ]
+
+  modify . defaultJUnitConfig . pack . takeBaseName <$> getCurrentDirectory
+
+lookupEnvOverride
+  :: String
+  -> (String -> JUnitConfig -> JUnitConfig)
+  -> IO (JUnitConfig -> JUnitConfig)
+lookupEnvOverride name setter =
+  maybe id setter <$> lookupEnv (envPrefix <> name)
+
+envPrefix :: String
+envPrefix = "JUNIT_"
diff --git a/tests/Main.hs b/tests/Main.hs
--- a/tests/Main.hs
+++ b/tests/Main.hs
@@ -8,7 +8,6 @@
 import Control.Monad (void)
 import Data.Char (isSpace)
 import qualified Data.Map.Strict as Map
-import Data.Text (Text)
 import qualified Data.Text as T
 import qualified ExampleSpec
 import System.FilePath ((</>))
@@ -26,15 +25,12 @@
         golden <- XML.readFile XML.def "tests/golden.xml"
         normalizeDoc doc `shouldBe` normalizeDoc golden
 
-    it "can prefix source paths" $ do
+    it "matches golden file with prefixing" $ do
       let modify = setJUnitConfigSourcePathPrefix "lol/monorepo"
 
       withJUnitReportConfig modify ExampleSpec.spec $ \doc -> do
-        let
-          root = XML.documentRoot doc
-          hasPrefix = ("lol/monorepo/tests/ExampleSpec.hs" `T.isPrefixOf`)
-
-        elementInnerTexts root `shouldSatisfy` all hasPrefix
+        golden <- XML.readFile XML.def "tests/golden-prefixed.xml"
+        normalizeDoc doc `shouldBe` normalizeDoc golden
 
 withJUnitReport :: Spec -> (XML.Document -> IO ()) -> IO ()
 withJUnitReport = withJUnitReportConfig id
@@ -89,12 +85,3 @@
   onNodeElement f = \case
     XML.NodeElement el -> XML.NodeElement $ f el
     n -> n
-
-elementInnerTexts :: XML.Element -> [Text]
-elementInnerTexts = concatMap go . XML.elementNodes
- where
-  go :: XML.Node -> [Text]
-  go = \case
-    XML.NodeElement el -> elementInnerTexts el
-    XML.NodeContent x -> [x]
-    _ -> []
diff --git a/tests/golden-prefixed.xml b/tests/golden-prefixed.xml
new file mode 100644
--- /dev/null
+++ b/tests/golden-prefixed.xml
@@ -0,0 +1,61 @@
+<testsuites name="hspec-junit-format">
+  <testsuite
+    name="Some section"
+    package="Some section"
+    id="0"
+    hostname="localhost"
+    time="0.000032355"
+    timestamp="2021-05-17T15:36:10.205608409Z"
+    tests="2" failures="1" errors="0" skipped="0">
+    <properties/>
+    <testcase
+      file="lol/monorepo/tests/ExampleSpec.hs"
+      line="18"
+      name="has a failure"
+      classname="Some section"
+      time="0.000015537">
+      <failure type="error">lol/monorepo/tests/ExampleSpec.hs:18:7
+
+expected: &#34;False&#34;
+ but got: &#34;True&#34;
+</failure>
+    </testcase>
+    <testcase
+      file="lol/monorepo/tests/ExampleSpec.hs"
+      line="15"
+      name="has an expectation"
+      classname="Some section"
+      time="0.000016818"/>
+  </testsuite>
+  <testsuite
+    name="Some section/A grouped context"
+    package="Some section/A grouped context"
+    id="1"
+    time="0.000021009"
+    timestamp="2021-05-17T15:36:10.205608409Z"
+    hostname="localhost"
+    tests="3" failures="0" errors="0" skipped="1">
+    <properties/>
+    <testcase
+      file="lol/monorepo/tests/ExampleSpec.hs"
+      line="26"
+      name="gets skipped"
+      classname="Some section/A grouped context"
+      time="0.000006765">
+      <skipped>lol/monorepo/tests/ExampleSpec.hs:26:9
+some reason</skipped>
+    </testcase>
+    <testcase
+      file="lol/monorepo/tests/ExampleSpec.hs"
+      line="23"
+      name="also happens in a group"
+      classname="Some section/A grouped context"
+      time="0.000007421"/>
+    <testcase
+      file="lol/monorepo/tests/ExampleSpec.hs"
+      line="21"
+      name="happens in a group"
+      classname="Some section/A grouped context"
+      time="0.000006823"/>
+  </testsuite>
+</testsuites>
