diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,15 @@
 # Changelog
 
+## [0.10.0.0] - 2025-09-17
+
+This is technically a breaking change, but if you don't use any `opt-env-conf`
+internals, nothing should break for you.
+
+### Added
+
+* `unprefixedEnv`
+* `unprefixedConf`
+
 ## [0.9.0.0] - 2025-03-12
 
 ### Added
diff --git a/opt-env-conf.cabal b/opt-env-conf.cabal
--- a/opt-env-conf.cabal
+++ b/opt-env-conf.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           opt-env-conf
-version:        0.9.0.0
+version:        0.10.0.0
 synopsis:       Settings parsing for Haskell: command-line arguments, environment variables, and configuration values.
 homepage:       https://github.com/NorfairKing/opt-env-conf#readme
 bug-reports:    https://github.com/NorfairKing/opt-env-conf/issues
diff --git a/src/OptEnvConf.hs b/src/OptEnvConf.hs
--- a/src/OptEnvConf.hs
+++ b/src/OptEnvConf.hs
@@ -25,9 +25,13 @@
     long,
     short,
     env,
+    unprefixedEnv,
     conf,
     confWith,
     confWith',
+    unprefixedConf,
+    unprefixedConfWith,
+    unprefixedConfWith',
     name,
     value,
     hidden,
diff --git a/src/OptEnvConf/Doc.hs b/src/OptEnvConf/Doc.hs
--- a/src/OptEnvConf/Doc.hs
+++ b/src/OptEnvConf/Doc.hs
@@ -195,7 +195,7 @@
   let setDocTryArgument = settingTryArgument
   let setDocTrySwitch = isJust settingSwitchValue
   let setDocTryOption = settingTryOption
-  let setDocEnvVars = settingEnvVars
+  let setDocEnvVars = NE.map envVarSettingVar <$> settingEnvVars
   let setDocConfKeys =
         NE.map
           ( \ConfigValSetting {..} ->
diff --git a/src/OptEnvConf/Parser.hs b/src/OptEnvConf/Parser.hs
--- a/src/OptEnvConf/Parser.hs
+++ b/src/OptEnvConf/Parser.hs
@@ -1014,7 +1014,10 @@
       BuildTryOption -> Nothing
       BuildAddShort _ -> Nothing
       BuildAddLong _ -> Nothing
-      BuildAddEnv e -> Just $ BuildAddEnv $ e ++ "_FILE"
+      BuildAddEnv e ->
+        Just $
+          BuildAddEnv $
+            suffixEnvVarSetting "_FILE" e
       BuildAddConf _ -> Nothing
       BuildSetDefault _ _ -> Nothing
       i -> Just i
@@ -1053,7 +1056,7 @@
 {-# ANN subEnv ("NOCOVER" :: String) #-}
 subEnv :: String -> Parser a -> Parser a
 subEnv prefix = parserMapSetting $ \s ->
-  s {settingEnvVars = NE.map (prefix <>) <$> settingEnvVars s}
+  s {settingEnvVars = NE.map (prefixEnvVarSetting prefix) <$> settingEnvVars s}
 
 -- | Helper function for calling 'subEnv' with 'toEnvCase' and a @'_'@ appended.
 --
diff --git a/src/OptEnvConf/Run.hs b/src/OptEnvConf/Run.hs
--- a/src/OptEnvConf/Run.hs
+++ b/src/OptEnvConf/Run.hs
@@ -574,7 +574,7 @@
                           -- always fails if it's missing a reader.
                           rs <- requireReaders settingReaders
                           es <- asks ppEnvEnv
-                          let founds = mapMaybe (`EnvMap.lookup` es) (NE.toList ne)
+                          let founds = mapMaybe ((`EnvMap.lookup` es) . envVarSettingVar) (NE.toList ne)
                           -- Run the parser on all specified env vars before
                           -- returning the first because we want to fail if any
                           -- of them fail, even if they wouldn't be the parse
diff --git a/src/OptEnvConf/Setting.hs b/src/OptEnvConf/Setting.hs
--- a/src/OptEnvConf/Setting.hs
+++ b/src/OptEnvConf/Setting.hs
@@ -6,6 +6,7 @@
 
 module OptEnvConf.Setting
   ( Setting (..),
+    EnvVarSetting (..),
     ConfigValSetting (..),
 
     -- * Builders
@@ -20,9 +21,13 @@
     long,
     short,
     env,
+    unprefixedEnv,
     conf,
     confWith,
     confWith',
+    unprefixedConf,
+    unprefixedConfWith,
+    unprefixedConfWith',
     name,
     value,
     valueWithShown,
@@ -42,6 +47,8 @@
     emptySetting,
     Metavar,
     Help,
+    prefixEnvVarSetting,
+    suffixEnvVarSetting,
     prefixConfigValSetting,
     suffixConfigValSettingKey,
   )
@@ -80,7 +87,7 @@
     -- options.
     settingTryOption :: !Bool,
     -- | Which env vars can be read.
-    settingEnvVars :: !(Maybe (NonEmpty String)),
+    settingEnvVars :: !(Maybe (NonEmpty EnvVarSetting)),
     -- | Which and how to parse config values
     settingConfigVals :: !(Maybe (NonEmpty (ConfigValSetting a))),
     -- | Default value, if none of the above find the setting.
@@ -115,14 +122,39 @@
         `hashWithSalt` (snd <$> settingDefaultValue)
     )
 
+data EnvVarSetting = EnvVarSetting
+  { envVarSettingVar :: !String,
+    envVarSettingAllowPrefix :: !Bool
+  }
+  deriving (Show, Eq)
+
+instance Hashable EnvVarSetting where
+  hashWithSalt salt EnvVarSetting {..} =
+    salt
+      `hashWithSalt` envVarSettingVar
+      `hashWithSalt` envVarSettingAllowPrefix
+
+prefixEnvVarSetting :: String -> EnvVarSetting -> EnvVarSetting
+prefixEnvVarSetting prefix e =
+  if envVarSettingAllowPrefix e
+    then e {envVarSettingVar = prefix <> envVarSettingVar e}
+    else e
+
+suffixEnvVarSetting :: String -> EnvVarSetting -> EnvVarSetting
+suffixEnvVarSetting suffix e = e {envVarSettingVar = envVarSettingVar e <> suffix}
+
 data ConfigValSetting a = forall void.
   ConfigValSetting
   { configValSettingPath :: !(NonEmpty String),
+    configValSettingAllowPrefix :: !Bool,
     configValSettingCodec :: !(ValueCodec void (Maybe a))
   }
 
 prefixConfigValSetting :: String -> ConfigValSetting a -> ConfigValSetting a
-prefixConfigValSetting prefix c = c {configValSettingPath = prefix NE.<| configValSettingPath c}
+prefixConfigValSetting prefix c =
+  if configValSettingAllowPrefix c
+    then c {configValSettingPath = prefix NE.<| configValSettingPath c}
+    else c
 
 suffixConfigValSettingKey :: String -> ConfigValSetting a -> ConfigValSetting a
 suffixConfigValSettingKey suffix c = c {configValSettingPath = suffixPath $ configValSettingPath c}
@@ -206,7 +238,7 @@
   | BuildAddReader !(Reader a)
   | BuildAddLong !(NonEmpty Char)
   | BuildAddShort !Char
-  | BuildAddEnv !String
+  | BuildAddEnv !EnvVarSetting
   | BuildAddConf !(ConfigValSetting a)
   | BuildSetDefault !a !String
   | BuildAddExample !String
@@ -318,8 +350,12 @@
 --
 -- Multiple 'env's will be tried in order.
 env :: String -> Builder a
-env v = Builder [BuildAddEnv v]
+env v = Builder [BuildAddEnv (EnvVarSetting v True)]
 
+-- | Like 'env' but ignores any 'subEnv', 'subEnv_', or 'subAll'.
+unprefixedEnv :: String -> Builder a
+unprefixedEnv v = Builder [BuildAddEnv (EnvVarSetting v False)]
+
 -- | Try to parse a configuration value at the given key.
 --
 -- Multiple 'conf's will be tried in order.
@@ -333,7 +369,31 @@
 -- | Like 'confWith' but allows interpreting 'Null' as a value other than "Not found".
 confWith' :: String -> ValueCodec void (Maybe a) -> Builder a
 confWith' k c =
-  let t = ConfigValSetting {configValSettingPath = k :| [], configValSettingCodec = c}
+  let t =
+        ConfigValSetting
+          { configValSettingPath = k :| [],
+            configValSettingAllowPrefix = True,
+            configValSettingCodec = c
+          }
+   in Builder [BuildAddConf t]
+
+-- | Like 'conf' but ignores any 'subConf', 'subConf_', or 'subAll'.
+unprefixedConf :: (HasCodec a) => String -> Builder a
+unprefixedConf k = unprefixedConfWith k codec
+
+-- | Like 'confWith' but ignores any 'subConf', 'subConf_', or 'subAll'.
+unprefixedConfWith :: String -> ValueCodec void a -> Builder a
+unprefixedConfWith k c = unprefixedConfWith' k (maybeCodec c)
+
+-- | Like 'confWith'' but ignores any 'subConf', 'subConf_', or 'subAll'.
+unprefixedConfWith' :: String -> ValueCodec void (Maybe a) -> Builder a
+unprefixedConfWith' k c =
+  let t =
+        ConfigValSetting
+          { configValSettingPath = k :| [],
+            configValSettingAllowPrefix = False,
+            configValSettingCodec = c
+          }
    in Builder [BuildAddConf t]
 
 -- | Short-hand function for 'option', 'long', 'env', and 'conf' at the same time.
