[go: nahoru, domu]

Rename {absl => std}::optional in minor top-level dirs

Automated patch, intended to be effectively a no-op.

This patch gather the changes for every top-level directories with less
than 150 files modified:
 #  directory
--- ---------------
150 remoting
98  gpu
87  chromecast
79  mojo
70  storage
65  fuchsia_web
46  sandbox
44  android_webview
38  google_apis
27  pdf
25  printing
20  headless
13  ipc
11  crypto
10  sql
3   dbus
2   testing
2   skia
2   gin
2   apps
1   rlz
1   codelabs

Context:
https://groups.google.com/a/chromium.org/g/cxx/c/nBD_1LaanTc/m/ghh-ZZhWAwAJ?utm_medium=email&utm_source=footer

As of https://crrev.com/1204351, absl::optional is now a type alias for
std::optional. We should migrate toward it.

Script:
```

function replace {
  echo "Replacing $1 by $2"
  git grep -l "$1" \
		| cut -f1 -d: \
		| grep \
			-e "^codelabs" \
			-e "^rlz" \
			-e "^apps" \
			-e "^gin" \
			-e "^skia" \
			-e "^testing" \
			-e "^dbus" \
			-e "^sql" \
			-e "^crypto" \
			-e "^ipc" \
			-e "^headless" \
			-e "^printing" \
			-e "^pdf" \
			-e "^google_apis" \
			-e "^android_webview" \
			-e "^sandbox" \
			-e "^fuchsia_web" \
			-e "^storage" \
			-e "^mojo" \
			-e "^chromecast" \
			-e "^gpu" \
			-e "^remoting" \
		| sort \
		| uniq \
		| grep \
			-e "\.h" \
			-e "\.cc" \
			-e "\.mm" \
			-e "\.py" \
	  | xargs sed -i "s/$1/$2/g"
}

replace "absl::make_optional" "std::make_optional"
replace "absl::optional" "std::optional"
replace "absl::nullopt" "std::nullopt"
replace "absl::in_place" "std::in_place"
replace "absl::in_place_t" "std::in_place_t"
replace "\"third_party\/abseil-cpp\/absl\/types\/optional.h\"" "<optional>"
git cl format
```

CQ_INCLUDE_TRYBOTS=luci.chrome.try:chromeos-betty-pi-arc-chrome

Bug: chromium:1500249
Change-Id: I0eca8ff96f5712ba746ac8d8da93d03a86d8292c
AX-Relnotes: n/a.
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5009410
Reviewed-by: danakj <danakj@chromium.org>
Owners-Override: danakj <danakj@chromium.org>
Commit-Queue: Arthur Sonzogni <arthursonzogni@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1222826}
diff --git a/android_webview/browser/aw_client_hints_controller_delegate.cc b/android_webview/browser/aw_client_hints_controller_delegate.cc
index a3cba10a..a3b196f 100644
--- a/android_webview/browser/aw_client_hints_controller_delegate.cc
+++ b/android_webview/browser/aw_client_hints_controller_delegate.cc
@@ -58,14 +58,14 @@
   // Regenerate the brand version lists with Android WebView product name.
   metadata.brand_version_list = embedder_support::GenerateBrandVersionList(
       major_version_number, kAndroidWebViewProductName, major_version,
-      absl::nullopt, absl::nullopt, enable_updated_grease_by_policy,
+      std::nullopt, std::nullopt, enable_updated_grease_by_policy,
       blink::UserAgentBrandVersionType::kMajorVersion);
 
   if (!only_low_entropy_ch) {
     metadata.brand_full_version_list =
         embedder_support::GenerateBrandVersionList(
             major_version_number, kAndroidWebViewProductName,
-            metadata.full_version, absl::nullopt, absl::nullopt,
+            metadata.full_version, std::nullopt, std::nullopt,
             enable_updated_grease_by_policy,
             blink::UserAgentBrandVersionType::kFullVersion);
   }
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc
index 013ac5e6..3e0360f 100644
--- a/android_webview/browser/aw_content_browser_client.cc
+++ b/android_webview/browser/aw_content_browser_client.cc
@@ -499,12 +499,12 @@
   return std::string();
 }
 
-absl::optional<base::FilePath>
+std::optional<base::FilePath>
 AwContentBrowserClient::GetLocalTracesDirectory() {
   base::FilePath user_data_dir;
   if (!base::PathService::Get(android_webview::DIR_LOCAL_TRACES,
                               &user_data_dir)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   DCHECK(!user_data_dir.empty());
   return user_data_dir;
@@ -843,7 +843,7 @@
     network::mojom::WebSandboxFlags /*sandbox_flags*/,
     ui::PageTransition page_transition,
     bool has_user_gesture,
-    const absl::optional<url::Origin>& initiating_origin,
+    const std::optional<url::Origin>& initiating_origin,
     content::RenderFrameHost* initiator_document,
     mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory) {
   // Sandbox flags
@@ -871,7 +871,7 @@
     // Manages its own lifetime.
     new android_webview::AwProxyingURLLoaderFactory(
         frame_tree_node_id, std::move(receiver), mojo::NullRemote(),
-        true /* intercept_only */, absl::nullopt /* security_options */,
+        true /* intercept_only */, std::nullopt /* security_options */,
         nullptr /* xrw_allowlist_matcher */, std::move(browser_context_handle));
   } else {
     content::GetIOThreadTaskRunner({})->PostTask(
@@ -885,7 +885,7 @@
               new android_webview::AwProxyingURLLoaderFactory(
                   frame_tree_node_id, std::move(receiver), mojo::NullRemote(),
                   true /* intercept_only */,
-                  absl::nullopt /* security_options */,
+                  std::nullopt /* security_options */,
                   nullptr /* xrw_allowlist_matcher */,
                   std::move(browser_context_handle));
             },
@@ -898,7 +898,7 @@
 void AwContentBrowserClient::RegisterNonNetworkSubresourceURLLoaderFactories(
     int render_process_id,
     int render_frame_id,
-    const absl::optional<url::Origin>& request_initiator_origin,
+    const std::optional<url::Origin>& request_initiator_origin,
     NonNetworkURLLoaderFactoryMap* factories) {
   WebContents* web_contents = content::WebContents::FromRenderFrameHost(
       content::RenderFrameHost::FromID(render_process_id, render_frame_id));
@@ -975,7 +975,7 @@
     int render_process_id,
     URLLoaderFactoryType type,
     const url::Origin& request_initiator,
-    absl::optional<int64_t> navigation_id,
+    std::optional<int64_t> navigation_id,
     ukm::SourceIdObj ukm_source_id,
     mojo::PendingReceiver<network::mojom::URLLoaderFactory>* factory_receiver,
     mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>*
@@ -1013,7 +1013,7 @@
           static_cast<AwBrowserContext*>(browser_context));
   if (frame) {
     auto security_options =
-        absl::make_optional<AwProxyingURLLoaderFactory::SecurityOptions>();
+        std::make_optional<AwProxyingURLLoaderFactory::SecurityOptions>();
     security_options->disable_web_security =
         base::CommandLine::ForCurrentProcess()->HasSwitch(
             switches::kDisableWebSecurity);
@@ -1057,7 +1057,7 @@
             &AwProxyingURLLoaderFactory::CreateProxy,
             content::RenderFrameHost::kNoFrameTreeNodeId,
             std::move(proxied_receiver), std::move(target_factory_remote),
-            absl::nullopt /* security_options */,
+            std::nullopt /* security_options */,
             aw_browser_context->service_worker_xrw_allowlist_matcher(),
             std::move(browser_context_handle)));
   }
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h
index 6e26be2..e093590 100644
--- a/android_webview/browser/aw_content_browser_client.h
+++ b/android_webview/browser/aw_content_browser_client.h
@@ -120,7 +120,7 @@
                        bool* no_javascript_access) override;
   base::FilePath GetDefaultDownloadDirectory() override;
   std::string GetDefaultDownloadName() override;
-  absl::optional<base::FilePath> GetLocalTracesDirectory() override;
+  std::optional<base::FilePath> GetLocalTracesDirectory() override;
   void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override;
   bool AllowPepperSocketAPI(
       content::BrowserContext* browser_context,
@@ -196,14 +196,14 @@
       network::mojom::WebSandboxFlags sandbox_flags,
       ui::PageTransition page_transition,
       bool has_user_gesture,
-      const absl::optional<url::Origin>& initiating_origin,
+      const std::optional<url::Origin>& initiating_origin,
       content::RenderFrameHost* initiator_document,
       mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory)
       override;
   void RegisterNonNetworkSubresourceURLLoaderFactories(
       int render_process_id,
       int render_frame_id,
-      const absl::optional<url::Origin>& request_initiator_origin,
+      const std::optional<url::Origin>& request_initiator_origin,
       NonNetworkURLLoaderFactoryMap* factories) override;
   bool ShouldAllowNoLongerUsedProcessToExit() override;
   bool ShouldIsolateErrorPage(bool in_main_frame) override;
@@ -219,7 +219,7 @@
       int render_process_id,
       URLLoaderFactoryType type,
       const url::Origin& request_initiator,
-      absl::optional<int64_t> navigation_id,
+      std::optional<int64_t> navigation_id,
       ukm::SourceIdObj ukm_source_id,
       mojo::PendingReceiver<network::mojom::URLLoaderFactory>* factory_receiver,
       mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>*
diff --git a/android_webview/browser/aw_contents_io_thread_client.cc b/android_webview/browser/aw_contents_io_thread_client.cc
index d2613cfc..cb45f04 100644
--- a/android_webview/browser/aw_contents_io_thread_client.cc
+++ b/android_webview/browser/aw_contents_io_thread_client.cc
@@ -8,6 +8,7 @@
 #include <memory>
 #include <utility>
 
+#include <optional>
 #include "android_webview/browser/aw_settings.h"
 #include "android_webview/browser/network_service/aw_web_resource_intercept_response.h"
 #include "android_webview/browser/network_service/aw_web_resource_request.h"
@@ -35,7 +36,6 @@
 #include "content/public/browser/web_contents_observer.h"
 #include "net/base/data_url.h"
 #include "services/network/public/cpp/resource_request.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using base::LazyInstance;
 using base::android::AttachCurrentThread;
@@ -74,10 +74,10 @@
   static RfhToIoThreadClientMap* GetInstance();
   void Set(const content::GlobalRenderFrameHostToken& rfh_token,
            const JavaObjectWeakGlobalRef& client);
-  absl::optional<JavaObjectWeakGlobalRef> Get(
+  std::optional<JavaObjectWeakGlobalRef> Get(
       const content::GlobalRenderFrameHostToken& rfh_token);
 
-  absl::optional<JavaObjectWeakGlobalRef> Get(int frame_tree_node_id);
+  std::optional<JavaObjectWeakGlobalRef> Get(int frame_tree_node_id);
 
   // Prefer to call these when RenderFrameHost* is available, because they
   // update both maps at the same time.
@@ -109,25 +109,25 @@
   rfh_to_weak_global_ref_[rfh_token] = client;
 }
 
-absl::optional<JavaObjectWeakGlobalRef> RfhToIoThreadClientMap::Get(
+std::optional<JavaObjectWeakGlobalRef> RfhToIoThreadClientMap::Get(
     const content::GlobalRenderFrameHostToken& rfh_token) {
   base::AutoLock lock(map_lock_);
   RenderFrameHostToWeakGlobalRefType::iterator iterator =
       rfh_to_weak_global_ref_.find(rfh_token);
   if (iterator == rfh_to_weak_global_ref_.end()) {
-    return absl::nullopt;
+    return std::nullopt;
   } else {
     return iterator->second;
   }
 }
 
-absl::optional<JavaObjectWeakGlobalRef> RfhToIoThreadClientMap::Get(
+std::optional<JavaObjectWeakGlobalRef> RfhToIoThreadClientMap::Get(
     int frame_tree_node_id) {
   base::AutoLock lock(map_lock_);
   FrameTreeNodeToWeakGlobalRefType::iterator iterator =
       frame_tree_node_to_weak_global_ref_.find(frame_tree_node_id);
   if (iterator == frame_tree_node_to_weak_global_ref_.end()) {
-    return absl::nullopt;
+    return std::nullopt;
   } else {
     return iterator->second.second;
   }
@@ -222,7 +222,7 @@
 // a scoped local reference. This will return |nullptr| if either the optional
 // is empty or the weak reference has already expired.
 std::unique_ptr<AwContentsIoThreadClient> WrapOptionalWeakRef(
-    absl::optional<JavaObjectWeakGlobalRef> opt_delegate_weak_ref) {
+    std::optional<JavaObjectWeakGlobalRef> opt_delegate_weak_ref) {
   if (opt_delegate_weak_ref) {
     JNIEnv* env = AttachCurrentThread();
     ScopedJavaLocalRef<jobject> java_delegate = opt_delegate_weak_ref->get(env);
@@ -252,7 +252,7 @@
     const blink::LocalFrameToken& parent_frame_token,
     const blink::LocalFrameToken& child_frame_token) {
   RfhToIoThreadClientMap* map = RfhToIoThreadClientMap::GetInstance();
-  absl::optional<JavaObjectWeakGlobalRef> opt_delegate_weak_ref = map->Get(
+  std::optional<JavaObjectWeakGlobalRef> opt_delegate_weak_ref = map->Get(
       content::GlobalRenderFrameHostToken(child_id, parent_frame_token));
   if (opt_delegate_weak_ref) {
     map->Set(content::GlobalRenderFrameHostToken(child_id, child_frame_token),
diff --git a/android_webview/browser/aw_dark_mode.cc b/android_webview/browser/aw_dark_mode.cc
index 09d8c0ff..01ccbf8 100644
--- a/android_webview/browser/aw_dark_mode.cc
+++ b/android_webview/browser/aw_dark_mode.cc
@@ -175,7 +175,7 @@
 }
 
 void AwDarkMode::InferredColorSchemeUpdated(
-    absl::optional<blink::mojom::PreferredColorScheme> color_scheme) {
+    std::optional<blink::mojom::PreferredColorScheme> color_scheme) {
   if (prefers_dark_from_theme_ && color_scheme.has_value()) {
     UMA_HISTOGRAM_BOOLEAN(
         "Android.WebView.DarkMode.PageDarkenedAccordingToAppTheme",
diff --git a/android_webview/browser/aw_dark_mode.h b/android_webview/browser/aw_dark_mode.h
index 071c9ecd..d6036e2 100644
--- a/android_webview/browser/aw_dark_mode.h
+++ b/android_webview/browser/aw_dark_mode.h
@@ -38,7 +38,7 @@
   void NavigationEntryCommitted(
       const content::LoadCommittedDetails& load_details) override;
   void InferredColorSchemeUpdated(
-      absl::optional<blink::mojom::PreferredColorScheme> color_scheme) override;
+      std::optional<blink::mojom::PreferredColorScheme> color_scheme) override;
 
   void PopulateWebPreferencesForPreT(blink::web_pref::WebPreferences* web_prefs,
                                      int force_dark_mode,
diff --git a/android_webview/browser/aw_http_auth_handler.cc b/android_webview/browser/aw_http_auth_handler.cc
index 00e237c6..663bcc90 100644
--- a/android_webview/browser/aw_http_auth_handler.cc
+++ b/android_webview/browser/aw_http_auth_handler.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include <optional>
 #include "android_webview/browser/aw_contents.h"
 #include "android_webview/browser_jni_headers/AwHttpAuthHandler_jni.h"
 #include "base/android/jni_android.h"
@@ -15,7 +16,6 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
 #include "net/base/auth.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using base::android::ConvertJavaStringToUTF16;
 using base::android::JavaParamRef;
@@ -62,7 +62,7 @@
 void AwHttpAuthHandler::Cancel(JNIEnv* env, const JavaParamRef<jobject>& obj) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (callback_) {
-    std::move(callback_).Run(absl::nullopt);
+    std::move(callback_).Run(std::nullopt);
   }
 }
 
@@ -71,14 +71,14 @@
 
   // The WebContents may have been destroyed during the PostTask.
   if (!web_contents_) {
-    std::move(callback_).Run(absl::nullopt);
+    std::move(callback_).Run(std::nullopt);
     return;
   }
 
   AwContents* aw_contents = AwContents::FromWebContents(web_contents_.get());
   if (!aw_contents->OnReceivedHttpAuthRequest(http_auth_handler_, host_,
                                               realm_)) {
-    std::move(callback_).Run(absl::nullopt);
+    std::move(callback_).Run(std::nullopt);
   }
 }
 
diff --git a/android_webview/browser/aw_user_agent_metadata_unittest.cc b/android_webview/browser/aw_user_agent_metadata_unittest.cc
index 5c08aab..6512ba4 100644
--- a/android_webview/browser/aw_user_agent_metadata_unittest.cc
+++ b/android_webview/browser/aw_user_agent_metadata_unittest.cc
@@ -24,9 +24,9 @@
 
   void verifyUaMetadata(blink::UserAgentMetadata expect,
                         blink::UserAgentMetadata actual) {
-    absl::optional<std::string> expect_str =
+    std::optional<std::string> expect_str =
         blink::UserAgentMetadata::Marshal(expect);
-    absl::optional<std::string> actual_str =
+    std::optional<std::string> actual_str =
         blink::UserAgentMetadata::Marshal(actual);
     EXPECT_TRUE(expect_str.has_value() == actual_str.has_value());
     if (expect_str.has_value()) {
diff --git a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.cc b/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.cc
index de62978..45ba404 100644
--- a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.cc
+++ b/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.cc
@@ -13,6 +13,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "android_webview/browser/metrics/aw_metrics_service_client.h"
 #include "android_webview/common/aw_features.h"
 #include "android_webview/common/aw_switches.h"
@@ -34,7 +35,6 @@
 #include "base/version.h"
 #include "components/component_updater/android/component_loader_policy.h"
 #include "components/optimization_guide/core/bloom_filter.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace android_webview {
 
@@ -54,7 +54,7 @@
 
 struct AllowListLookupResult {
   AllowlistPraseStatus parse_status;
-  absl::optional<AppPackageNameLoggingRule> record_rule;
+  std::optional<AppPackageNameLoggingRule> record_rule;
 };
 
 void RecordAndReportResult(AllowListLookupCallback lookup_callback,
@@ -118,7 +118,7 @@
 }
 
 void SetAppPackageNameLoggingRule(
-    absl::optional<AppPackageNameLoggingRule> record) {
+    std::optional<AppPackageNameLoggingRule> record) {
   auto* metrics_service_client = AwMetricsServiceClient::GetInstance();
   DCHECK(metrics_service_client);
   metrics_service_client->SetAppPackageNameLoggingRule(record);
@@ -142,7 +142,7 @@
 
 bool ShouldThrottleAppPackageNamesAllowlistComponent(
     base::Time last_update,
-    absl::optional<AppPackageNameLoggingRule> cached_record) {
+    std::optional<AppPackageNameLoggingRule> cached_record) {
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kWebViewDisablePackageAllowlistThrottling) ||
       last_update.is_null()) {
@@ -166,7 +166,7 @@
 AwAppsPackageNamesAllowlistComponentLoaderPolicy::
     AwAppsPackageNamesAllowlistComponentLoaderPolicy(
         std::string app_package_name,
-        absl::optional<AppPackageNameLoggingRule> cached_record,
+        std::optional<AppPackageNameLoggingRule> cached_record,
         AllowListLookupCallback lookup_callback)
     : app_package_name_(std::move(app_package_name)),
       cached_record_(cached_record),
@@ -204,11 +204,11 @@
 
   // Have to use double because base::DictionaryValue doesn't support int64
   // values.
-  absl::optional<double> expiry_date_ms =
+  std::optional<double> expiry_date_ms =
       manifest.FindDoubleByDottedPath(kExpiryDateKey);
-  absl::optional<int> num_hash =
+  std::optional<int> num_hash =
       manifest.FindIntByDottedPath(kBloomFilterNumHashKey);
-  absl::optional<int> num_bits =
+  std::optional<int> num_bits =
       manifest.FindIntByDottedPath(kBloomFilterNumBitsKey);
   // Being conservative and consider the allowlist expired when a valid expiry
   // date is absent.
@@ -255,7 +255,7 @@
   DCHECK(lookup_callback_);
   // TODO(crbug.com/1216200): Record the error in a histogram in the
   // ComponentLoader for each component.
-  std::move(lookup_callback_).Run(absl::optional<AppPackageNameLoggingRule>());
+  std::move(lookup_callback_).Run(std::optional<AppPackageNameLoggingRule>());
 }
 
 void AwAppsPackageNamesAllowlistComponentLoaderPolicy::GetHash(
@@ -279,7 +279,7 @@
               kWebViewAppsPackageNamesServerSideAllowlist)) {
     return;
   }
-  absl::optional<AppPackageNameLoggingRule> cached_record =
+  std::optional<AppPackageNameLoggingRule> cached_record =
       metrics_service_client->GetCachedAppPackageNameLoggingRule();
   base::Time last_update =
       metrics_service_client->GetAppPackageNameLoggingRuleLastUpdateTime();
diff --git a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.h b/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.h
index 8458065..72e6769 100644
--- a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.h
+++ b/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy.h
@@ -9,13 +9,13 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "android_webview/common/metrics/app_package_name_logging_rule.h"
 #include "base/containers/flat_map.h"
 #include "base/files/scoped_file.h"
 #include "base/functional/callback.h"
 #include "base/values.h"
 #include "components/component_updater/android/component_loader_policy.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class Time;
@@ -45,7 +45,7 @@
 // A callback for the result of loading and looking up the allowlist. If the
 // allowlist loading fails, it will be called with a null record.
 using AllowListLookupCallback =
-    base::OnceCallback<void(absl::optional<AppPackageNameLoggingRule>)>;
+    base::OnceCallback<void(std::optional<AppPackageNameLoggingRule>)>;
 
 // Defines a loader responsible for receiving the allowlist for apps package
 // names that can be included in UMA records and lookup the embedding app's name
@@ -73,7 +73,7 @@
   //                    `app_package_name` in the packages names allowlist.
   AwAppsPackageNamesAllowlistComponentLoaderPolicy(
       std::string app_package_name,
-      absl::optional<AppPackageNameLoggingRule> cached_record,
+      std::optional<AppPackageNameLoggingRule> cached_record,
       AllowListLookupCallback lookup_callback);
   ~AwAppsPackageNamesAllowlistComponentLoaderPolicy() override;
 
@@ -93,7 +93,7 @@
 
  private:
   std::string app_package_name_;
-  absl::optional<AppPackageNameLoggingRule> cached_record_;
+  std::optional<AppPackageNameLoggingRule> cached_record_;
 
   AllowListLookupCallback lookup_callback_;
 };
diff --git a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy_unittest.cc b/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy_unittest.cc
index f84c180..1895967c 100644
--- a/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy_unittest.cc
+++ b/android_webview/browser/component_updater/loader_policies/aw_apps_package_names_allowlist_component_loader_policy_unittest.cc
@@ -93,7 +93,7 @@
   }
 
   void LookupConfirmationCallback(
-      absl::optional<AppPackageNameLoggingRule> record) {
+      std::optional<AppPackageNameLoggingRule> record) {
     EXPECT_TRUE(checker_.CalledOnValidSequence());
     allowlist_lookup_result_ = record;
     lookup_run_loop_.Quit();
@@ -106,7 +106,7 @@
   base::RunLoop lookup_run_loop_;
   base::HistogramTester histogram_tester_;
 
-  absl::optional<AppPackageNameLoggingRule> allowlist_lookup_result_;
+  std::optional<AppPackageNameLoggingRule> allowlist_lookup_result_;
 
  private:
   base::FilePath allowlist_path_;
@@ -179,7 +179,7 @@
 
   auto policy =
       std::make_unique<AwAppsPackageNamesAllowlistComponentLoaderPolicy>(
-          "non.existent.app", absl::optional<AppPackageNameLoggingRule>(),
+          "non.existent.app", std::optional<AppPackageNameLoggingRule>(),
           base::BindOnce(&AwAppsPackageNamesAllowlistComponentLoaderPolicyTest::
                              LookupConfirmationCallback,
                          base::Unretained(this)));
@@ -203,7 +203,7 @@
 
   auto policy =
       std::make_unique<AwAppsPackageNamesAllowlistComponentLoaderPolicy>(
-          kTestAllowlist[1], absl::optional<AppPackageNameLoggingRule>(),
+          kTestAllowlist[1], std::optional<AppPackageNameLoggingRule>(),
           base::BindOnce(&AwAppsPackageNamesAllowlistComponentLoaderPolicyTest::
                              LookupConfirmationCallback,
                          base::Unretained(this)));
@@ -228,7 +228,7 @@
 
   auto policy =
       std::make_unique<AwAppsPackageNamesAllowlistComponentLoaderPolicy>(
-          kTestAllowlist[1], absl::optional<AppPackageNameLoggingRule>(),
+          kTestAllowlist[1], std::optional<AppPackageNameLoggingRule>(),
           base::BindOnce(&AwAppsPackageNamesAllowlistComponentLoaderPolicyTest::
                              LookupConfirmationCallback,
                          base::Unretained(this)));
@@ -252,7 +252,7 @@
 
   auto policy =
       std::make_unique<AwAppsPackageNamesAllowlistComponentLoaderPolicy>(
-          kTestAllowlist[1], absl::optional<AppPackageNameLoggingRule>(),
+          kTestAllowlist[1], std::optional<AppPackageNameLoggingRule>(),
           base::BindOnce(&AwAppsPackageNamesAllowlistComponentLoaderPolicyTest::
                              LookupConfirmationCallback,
                          base::Unretained(this)));
@@ -277,7 +277,7 @@
 
   auto policy =
       std::make_unique<AwAppsPackageNamesAllowlistComponentLoaderPolicy>(
-          kTestAllowlist[1], absl::optional<AppPackageNameLoggingRule>(),
+          kTestAllowlist[1], std::optional<AppPackageNameLoggingRule>(),
           base::BindOnce(&AwAppsPackageNamesAllowlistComponentLoaderPolicyTest::
                              LookupConfirmationCallback,
                          base::Unretained(this)));
@@ -306,7 +306,7 @@
 
   auto policy =
       std::make_unique<AwAppsPackageNamesAllowlistComponentLoaderPolicy>(
-          kTestAllowlist[1], absl::optional<AppPackageNameLoggingRule>(),
+          kTestAllowlist[1], std::optional<AppPackageNameLoggingRule>(),
           base::BindOnce(&AwAppsPackageNamesAllowlistComponentLoaderPolicyTest::
                              LookupConfirmationCallback,
                          base::Unretained(this)));
@@ -346,7 +346,7 @@
   EXPECT_EQ(policies.size(), expect_throttling ? 0 : 1u);
 }
 
-void TestThrottlingAllowlist(absl::optional<AppPackageNameLoggingRule> rule,
+void TestThrottlingAllowlist(std::optional<AppPackageNameLoggingRule> rule,
                              bool expect_throttling) {
   TestingPrefServiceSimple prefs;
   AwMetricsServiceClient::RegisterMetricsPrefs(prefs.registry());
@@ -390,7 +390,7 @@
       android_webview::features::kWebViewAppsPackageNamesServerSideAllowlist);
   base::SetRecordActionTaskRunner(env_.GetMainThreadTaskRunner());
 
-  TestThrottlingAllowlist(absl::optional<AppPackageNameLoggingRule>(),
+  TestThrottlingAllowlist(std::optional<AppPackageNameLoggingRule>(),
                           /*expect_throttling=*/false);
 }
 
diff --git a/android_webview/browser/cookie_manager.cc b/android_webview/browser/cookie_manager.cc
index 1a771d4..825fb40 100644
--- a/android_webview/browser/cookie_manager.cc
+++ b/android_webview/browser/cookie_manager.cc
@@ -10,6 +10,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "android_webview/browser/aw_browser_context.h"
 #include "android_webview/browser/aw_browser_context_store.h"
 #include "android_webview/browser/aw_client_hints_controller_delegate.h"
@@ -54,7 +55,6 @@
 #include "services/network/cookie_access_delegate_impl.h"
 #include "services/network/network_service.h"
 #include "services/network/public/mojom/cookie_manager.mojom.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/url_constants.h"
 
 using base::WaitableEvent;
@@ -488,7 +488,7 @@
       host, value, workaround_http_secure_cookies_, &should_allow_cookie);
 
   std::unique_ptr<net::CanonicalCookie> cc(net::CanonicalCookie::Create(
-      new_host, value, base::Time::Now(), absl::nullopt /* server_time */,
+      new_host, value, base::Time::Now(), std::nullopt /* server_time */,
       net::CookiePartitionKey::FromWire(net::SchemefulSite(new_host))));
 
   if (!cc || !should_allow_cookie) {
diff --git a/android_webview/browser/enterprise_authentication_app_link_policy_handler_unittest.cc b/android_webview/browser/enterprise_authentication_app_link_policy_handler_unittest.cc
index fee7f6c..22dbbac 100644
--- a/android_webview/browser/enterprise_authentication_app_link_policy_handler_unittest.cc
+++ b/android_webview/browser/enterprise_authentication_app_link_policy_handler_unittest.cc
@@ -40,7 +40,7 @@
              nullptr);
   this->UpdateProviderPolicy(policy);
   const base::Value* pref_value = nullptr;
-  absl::optional<base::Value> expected = base::JSONReader::Read(R"(
+  std::optional<base::Value> expected = base::JSONReader::Read(R"(
     [
      "https://www.testserver1.com/login",
      "https://www.testserver2.com/login"
diff --git a/android_webview/browser/gfx/aw_draw_fn_impl.h b/android_webview/browser/gfx/aw_draw_fn_impl.h
index 75498cec..41df418 100644
--- a/android_webview/browser/gfx/aw_draw_fn_impl.h
+++ b/android_webview/browser/gfx/aw_draw_fn_impl.h
@@ -5,6 +5,7 @@
 #ifndef ANDROID_WEBVIEW_BROWSER_GFX_AW_DRAW_FN_IMPL_H_
 #define ANDROID_WEBVIEW_BROWSER_GFX_AW_DRAW_FN_IMPL_H_
 
+#include <optional>
 #include "android_webview/browser/gfx/aw_vulkan_context_provider.h"
 #include "android_webview/browser/gfx/compositor_frame_consumer.h"
 #include "android_webview/browser/gfx/render_thread_manager.h"
@@ -12,7 +13,6 @@
 #include "android_webview/public/browser/draw_fn.h"
 #include "base/android/scoped_java_ref.h"
 #include "base/threading/platform_thread.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkRefCnt.h"
 
 namespace android_webview {
@@ -68,13 +68,13 @@
   // Vulkan context provider for Vk rendering.
   scoped_refptr<AwVulkanContextProvider> vulkan_context_provider_;
 
-  absl::optional<AwVulkanContextProvider::ScopedSecondaryCBDraw>
+  std::optional<AwVulkanContextProvider::ScopedSecondaryCBDraw>
       scoped_secondary_cb_draw_;
 
-  absl::optional<VulkanGLInterop> interop_;
+  std::optional<VulkanGLInterop> interop_;
 
   // Latched on first DrawGL / InitVk call.
-  absl::optional<base::PlatformThreadId> render_thread_id_;
+  std::optional<base::PlatformThreadId> render_thread_id_;
 
   bool skip_next_post_draw_vk_ = false;
 };
diff --git a/android_webview/browser/gfx/aw_vulkan_context_provider.cc b/android_webview/browser/gfx/aw_vulkan_context_provider.cc
index 17e8dd93..7fd74c6 100644
--- a/android_webview/browser/gfx/aw_vulkan_context_provider.cc
+++ b/android_webview/browser/gfx/aw_vulkan_context_provider.cc
@@ -212,9 +212,8 @@
   post_submit_tasks_.push_back(std::move(closure));
 }
 
-absl::optional<uint32_t> AwVulkanContextProvider::GetSyncCpuMemoryLimit()
-    const {
-  return absl::optional<uint32_t>();
+std::optional<uint32_t> AwVulkanContextProvider::GetSyncCpuMemoryLimit() const {
+  return std::optional<uint32_t>();
 }
 
 bool AwVulkanContextProvider::Initialize(AwDrawFn_InitVkParams* params) {
diff --git a/android_webview/browser/gfx/aw_vulkan_context_provider.h b/android_webview/browser/gfx/aw_vulkan_context_provider.h
index 26aec03..14c9db5 100644
--- a/android_webview/browser/gfx/aw_vulkan_context_provider.h
+++ b/android_webview/browser/gfx/aw_vulkan_context_provider.h
@@ -7,10 +7,10 @@
 
 #include <memory>
 
+#include <optional>
 #include "base/memory/raw_ptr_exclusion.h"
 #include "components/viz/common/gpu/vulkan_context_provider.h"
 #include "gpu/vulkan/vulkan_device_queue.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkRefCnt.h"
 #include "third_party/skia/include/gpu/GrBackendSemaphore.h"
 #include "third_party/skia/include/private/chromium/GrVkSecondaryCBDrawContext.h"
@@ -63,7 +63,7 @@
   void EnqueueSecondaryCBSemaphores(
       std::vector<VkSemaphore> semaphores) override;
   void EnqueueSecondaryCBPostSubmitTask(base::OnceClosure closure) override;
-  absl::optional<uint32_t> GetSyncCpuMemoryLimit() const override;
+  std::optional<uint32_t> GetSyncCpuMemoryLimit() const override;
 
   VkDevice device() { return globals_->device_queue->GetVulkanDevice(); }
   VkQueue queue() { return globals_->device_queue->GetVulkanQueue(); }
diff --git a/android_webview/browser/gfx/browser_view_renderer.h b/android_webview/browser/gfx/browser_view_renderer.h
index 3f5116d6..7e7a4aa 100644
--- a/android_webview/browser/gfx/browser_view_renderer.h
+++ b/android_webview/browser/gfx/browser_view_renderer.h
@@ -10,6 +10,7 @@
 #include <map>
 #include <set>
 
+#include <optional>
 #include "android_webview/browser/gfx/begin_frame_source_webview.h"
 #include "android_webview/browser/gfx/child_frame.h"
 #include "android_webview/browser/gfx/compositor_frame_producer.h"
@@ -24,7 +25,6 @@
 #include "components/viz/common/surfaces/frame_sink_id.h"
 #include "content/public/browser/android/synchronous_compositor.h"
 #include "content/public/browser/android/synchronous_compositor_client.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkRefCnt.h"
 #include "ui/gfx/geometry/point_f.h"
 #include "ui/gfx/geometry/rect.h"
@@ -282,7 +282,7 @@
   gfx::Vector2dF overscroll_rounding_error_;
 
   // The scroll to apply after the next scroll state update.
-  absl::optional<gfx::Point> scroll_on_scroll_state_update_;
+  std::optional<gfx::Point> scroll_on_scroll_state_update_;
 
   ParentCompositorDrawConstraints external_draw_constraints_;
 
diff --git a/android_webview/browser/gfx/child_frame.h b/android_webview/browser/gfx/child_frame.h
index f71be02..4177b76 100644
--- a/android_webview/browser/gfx/child_frame.h
+++ b/android_webview/browser/gfx/child_frame.h
@@ -8,12 +8,12 @@
 #include <memory>
 #include <vector>
 
+#include <optional>
 #include "base/containers/circular_deque.h"
 #include "components/viz/common/frame_sinks/begin_frame_args.h"
 #include "components/viz/common/surfaces/frame_sink_id.h"
 #include "components/viz/common/surfaces/surface_id.h"
 #include "content/public/browser/android/synchronous_compositor.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/geometry/transform.h"
 
@@ -55,7 +55,7 @@
   scoped_refptr<content::SynchronousCompositor::FrameFuture> frame_future;
   uint32_t layer_tree_frame_sink_id = 0u;
   std::unique_ptr<viz::CompositorFrame> frame;
-  absl::optional<viz::HitTestRegionList> hit_test_region_list;
+  std::optional<viz::HitTestRegionList> hit_test_region_list;
   // The id of the compositor this |frame| comes from.
   const viz::FrameSinkId frame_sink_id;
   // Local surface id of the frame. Invalid if |frame| is null.
diff --git a/android_webview/browser/gfx/hardware_renderer.cc b/android_webview/browser/gfx/hardware_renderer.cc
index 99fd14d0..d2987ba 100644
--- a/android_webview/browser/gfx/hardware_renderer.cc
+++ b/android_webview/browser/gfx/hardware_renderer.cc
@@ -338,7 +338,7 @@
       render_pass->CreateAndAppendDrawQuad<viz::SurfaceDrawQuad>();
   surface_quad->SetNew(quad_state, gfx::Rect(quad_state->quad_layer_rect),
                        gfx::Rect(quad_state->quad_layer_rect),
-                       viz::SurfaceRange(absl::nullopt, child_id),
+                       viz::SurfaceRange(std::nullopt, child_id),
                        SkColors::kWhite,
                        /*stretch_content_to_fill_bounds=*/false);
 
@@ -697,7 +697,7 @@
         ->PessimisticallyResetGrContext();
   }
 
-  absl::optional<OverlayProcessorWebView::ScopedSurfaceControlAvailable>
+  std::optional<OverlayProcessorWebView::ScopedSurfaceControlAvailable>
       allow_surface_control;
 
   auto* overlay_processor = on_viz_->overlay_processor();
diff --git a/android_webview/browser/gfx/overlay_processor_webview.cc b/android_webview/browser/gfx/overlay_processor_webview.cc
index b7301a7..b5c8b8e 100644
--- a/android_webview/browser/gfx/overlay_processor_webview.cc
+++ b/android_webview/browser/gfx/overlay_processor_webview.cc
@@ -393,10 +393,10 @@
     }
   }
 
-  absl::optional<gfx::SurfaceControl::Transaction> TakeHWUITransaction() {
+  std::optional<gfx::SurfaceControl::Transaction> TakeHWUITransaction() {
     DCHECK_CALLED_ON_VALID_THREAD(render_thread_checker_);
 
-    absl::optional<gfx::SurfaceControl::Transaction> result;
+    std::optional<gfx::SurfaceControl::Transaction> result;
     if (hwui_transaction_) {
       DCHECK(gpu_task_runner_);
       if (!pending_resource_update_.empty() || !pending_removals_.empty()) {
@@ -657,7 +657,7 @@
   base::flat_set<uint64_t> pending_removals_;
 
   scoped_refptr<gfx::SurfaceControl::Surface> parent_surface_;
-  absl::optional<gfx::SurfaceControl::Transaction> hwui_transaction_;
+  std::optional<gfx::SurfaceControl::Transaction> hwui_transaction_;
 
   GetSurfaceControlFn get_surface_control_ = nullptr;
 
@@ -721,7 +721,7 @@
   overlays_.clear();
 }
 
-absl::optional<gfx::SurfaceControl::Transaction>
+std::optional<gfx::SurfaceControl::Transaction>
 OverlayProcessorWebView::TakeSurfaceTransactionOnRT() {
   DCHECK(manager_);
   return manager_->TakeHWUITransaction();
diff --git a/android_webview/browser/gfx/overlay_processor_webview.h b/android_webview/browser/gfx/overlay_processor_webview.h
index 5c8b2fa..e27ec41 100644
--- a/android_webview/browser/gfx/overlay_processor_webview.h
+++ b/android_webview/browser/gfx/overlay_processor_webview.h
@@ -54,7 +54,7 @@
                              const viz::ResolvedFrameData* frame_data);
   void SetOverlaysEnabledByHWUI(bool enabled);
   void RemoveOverlays();
-  absl::optional<gfx::SurfaceControl::Transaction> TakeSurfaceTransactionOnRT();
+  std::optional<gfx::SurfaceControl::Transaction> TakeSurfaceTransactionOnRT();
   viz::SurfaceId GetOverlaySurfaceId(const viz::FrameSinkId& frame_sink_id);
 
   // viz::OverlayProcessorSurfaceControl overrides:
@@ -62,8 +62,9 @@
       viz::OverlayCandidateList* candidate_list) override;
   void ScheduleOverlays(
       viz::DisplayResourceProvider* resource_provider) override;
-  void AdjustOutputSurfaceOverlay(absl::optional<OutputSurfaceOverlayPlane>*
-                                      output_surface_plane) override {}
+  void AdjustOutputSurfaceOverlay(
+      std::optional<OutputSurfaceOverlayPlane>* output_surface_plane) override {
+  }
   void CheckOverlaySupportImpl(
       const viz::OverlayProcessorInterface::OutputSurfaceOverlayPlane*
           primary_plane,
diff --git a/android_webview/browser/gfx/render_thread_manager.cc b/android_webview/browser/gfx/render_thread_manager.cc
index 930298b..3680341 100644
--- a/android_webview/browser/gfx/render_thread_manager.cc
+++ b/android_webview/browser/gfx/render_thread_manager.cc
@@ -7,6 +7,7 @@
 #include <memory>
 #include <utility>
 
+#include <optional>
 #include "android_webview/browser/gfx/compositor_frame_producer.h"
 #include "android_webview/browser/gfx/gpu_service_webview.h"
 #include "android_webview/browser/gfx/hardware_renderer.h"
@@ -23,7 +24,6 @@
 #include "base/trace_event/traced_value.h"
 #include "components/viz/common/features.h"
 #include "components/viz/common/quads/compositor_frame.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace android_webview {
 
@@ -194,7 +194,7 @@
   // Force GL binding init if it's not yet initialized.
   GpuServiceWebView::GetInstance();
 
-  absl::optional<ScopedAppGLStateRestore> state_restore;
+  std::optional<ScopedAppGLStateRestore> state_restore;
   if (!vulkan_context_provider_) {
     state_restore.emplace(ScopedAppGLStateRestore::MODE_DRAW, save_restore);
     if (state_restore->skip_draw()) {
@@ -229,7 +229,7 @@
                                                       bool abandon_context) {
   GpuServiceWebView::GetInstance();
 
-  absl::optional<ScopedAppGLStateRestore> state_restore;
+  std::optional<ScopedAppGLStateRestore> state_restore;
   if (!vulkan_context_provider_ && !abandon_context) {
     state_restore.emplace(ScopedAppGLStateRestore::MODE_RESOURCE_MANAGEMENT,
                           save_restore);
diff --git a/android_webview/browser/gfx/root_frame_sink.cc b/android_webview/browser/gfx/root_frame_sink.cc
index acb376cc..6532848 100644
--- a/android_webview/browser/gfx/root_frame_sink.cc
+++ b/android_webview/browser/gfx/root_frame_sink.cc
@@ -77,7 +77,7 @@
   void SubmitCompositorFrame(
       const viz::LocalSurfaceId& local_surface_id,
       viz::CompositorFrame frame,
-      absl::optional<viz::HitTestRegionList> hit_test_region_list) {
+      std::optional<viz::HitTestRegionList> hit_test_region_list) {
     size_ = frame.size_in_pixels();
     support()->SubmitCompositorFrame(local_surface_id, std::move(frame),
                                      std::move(hit_test_region_list));
diff --git a/android_webview/browser/gfx/test/invalidate_test.cc b/android_webview/browser/gfx/test/invalidate_test.cc
index f0f5b49..849a5447 100644
--- a/android_webview/browser/gfx/test/invalidate_test.cc
+++ b/android_webview/browser/gfx/test/invalidate_test.cc
@@ -49,7 +49,7 @@
       render_pass.CreateAndAppendDrawQuad<viz::SurfaceDrawQuad>();
   surface_quad->SetNew(quad_state, gfx::Rect(quad_state->quad_layer_rect),
                        gfx::Rect(quad_state->quad_layer_rect),
-                       viz::SurfaceRange(absl::nullopt, child_id),
+                       viz::SurfaceRange(std::nullopt, child_id),
                        SkColors::kWhite,
                        /*stretch_content_to_fill_bounds=*/false);
 }
@@ -233,7 +233,7 @@
     frame.metadata.frame_token = frames_submitted_;
     support_->SubmitCompositorFrame(
         local_surface_id_allocator_.GetCurrentLocalSurfaceId(),
-        std::move(frame), absl::nullopt);
+        std::move(frame), std::nullopt);
   }
 
   void DidNotProduceFrame(const viz::BeginFrameAck& ack) {
diff --git a/android_webview/browser/metrics/aw_component_metrics_provider_delegate.cc b/android_webview/browser/metrics/aw_component_metrics_provider_delegate.cc
index 3c59dca..8629bc86 100644
--- a/android_webview/browser/metrics/aw_component_metrics_provider_delegate.cc
+++ b/android_webview/browser/metrics/aw_component_metrics_provider_delegate.cc
@@ -43,7 +43,7 @@
                               kWebViewAppsPackageNamesAllowlistComponentId;
                      }),
       components.end());
-  absl::optional<AppPackageNameLoggingRule> record =
+  std::optional<AppPackageNameLoggingRule> record =
       client_->GetCachedAppPackageNameLoggingRule();
   if (record.has_value()) {
     components.emplace_back(kWebViewAppsPackageNamesAllowlistComponentId, "",
diff --git a/android_webview/browser/metrics/aw_metrics_service_client.cc b/android_webview/browser/metrics/aw_metrics_service_client.cc
index 8eab70e..d7d6378 100644
--- a/android_webview/browser/metrics/aw_metrics_service_client.cc
+++ b/android_webview/browser/metrics/aw_metrics_service_client.cc
@@ -170,8 +170,8 @@
 }
 
 void AwMetricsServiceClient::SetAppPackageNameLoggingRule(
-    absl::optional<AppPackageNameLoggingRule> record) {
-  absl::optional<AppPackageNameLoggingRule> cached_record =
+    std::optional<AppPackageNameLoggingRule> record) {
+  std::optional<AppPackageNameLoggingRule> cached_record =
       GetCachedAppPackageNameLoggingRule();
   if (!record.has_value()) {
     package_name_record_status_ =
@@ -201,7 +201,7 @@
       base::Time::Now() - time_created_);
 }
 
-absl::optional<AppPackageNameLoggingRule>
+std::optional<AppPackageNameLoggingRule>
 AwMetricsServiceClient::GetCachedAppPackageNameLoggingRule() {
   if (cached_package_name_record_.has_value()) {
     return cached_package_name_record_;
diff --git a/android_webview/browser/metrics/aw_metrics_service_client.h b/android_webview/browser/metrics/aw_metrics_service_client.h
index 787b650..74a14f2 100644
--- a/android_webview/browser/metrics/aw_metrics_service_client.h
+++ b/android_webview/browser/metrics/aw_metrics_service_client.h
@@ -195,12 +195,11 @@
   // `record` If it has a null value, then it will be ignored and the cached
   //          record will be used if any.
   void SetAppPackageNameLoggingRule(
-      absl::optional<AppPackageNameLoggingRule> record);
+      std::optional<AppPackageNameLoggingRule> record);
 
   // Get the cached record of the app package names allowlist set by
   // `SetAppPackageNameLoggingRule` if any.
-  absl::optional<AppPackageNameLoggingRule>
-  GetCachedAppPackageNameLoggingRule();
+  std::optional<AppPackageNameLoggingRule> GetCachedAppPackageNameLoggingRule();
 
   // The last time the apps package name allowlist was queried from the
   // component update service, regardless if it was successful or not.
@@ -225,7 +224,7 @@
   base::Time time_created_;
   std::unique_ptr<Delegate> delegate_;
 
-  absl::optional<AppPackageNameLoggingRule> cached_package_name_record_;
+  std::optional<AppPackageNameLoggingRule> cached_package_name_record_;
   AppPackageNameLoggingRuleStatus package_name_record_status_ =
       AppPackageNameLoggingRuleStatus::kNotLoadedNoCache;
 };
diff --git a/android_webview/browser/metrics/aw_metrics_service_client_unittest.cc b/android_webview/browser/metrics/aw_metrics_service_client_unittest.cc
index 97cbe8d..82e26c5 100644
--- a/android_webview/browser/metrics/aw_metrics_service_client_unittest.cc
+++ b/android_webview/browser/metrics/aw_metrics_service_client_unittest.cc
@@ -141,7 +141,7 @@
   prefs->SetDict(prefs::kMetricsAppPackageNameLoggingRule,
                  expected_record.ToDictionary());
 
-  absl::optional<AppPackageNameLoggingRule> cached_record =
+  std::optional<AppPackageNameLoggingRule> cached_record =
       client->GetCachedAppPackageNameLoggingRule();
   EXPECT_TRUE(client->ShouldRecordPackageName());
   ASSERT_TRUE(cached_record.has_value());
@@ -173,7 +173,7 @@
   AppPackageNameLoggingRule expected_record(
       base::Version(kTestAllowlistVersion), base::Time::Min());
   client->SetAppPackageNameLoggingRule(expected_record);
-  absl::optional<AppPackageNameLoggingRule> cached_record =
+  std::optional<AppPackageNameLoggingRule> cached_record =
       client->GetCachedAppPackageNameLoggingRule();
 
   EXPECT_FALSE(client->ShouldRecordPackageName());
@@ -204,7 +204,7 @@
   AppPackageNameLoggingRule expected_record(
       base::Version(kTestAllowlistVersion), base::Time::Now() + expiry_time);
   client->SetAppPackageNameLoggingRule(expected_record);
-  absl::optional<AppPackageNameLoggingRule> cached_record =
+  std::optional<AppPackageNameLoggingRule> cached_record =
       client->GetCachedAppPackageNameLoggingRule();
 
   EXPECT_TRUE(client->ShouldRecordPackageName());
@@ -247,8 +247,8 @@
       base::Version(kTestAllowlistVersion), base::Time::Now() + expiry_time);
   client->SetAppPackageNameLoggingRule(expected_record);
   client->SetAppPackageNameLoggingRule(
-      absl::optional<AppPackageNameLoggingRule>());
-  absl::optional<AppPackageNameLoggingRule> cached_record =
+      std::optional<AppPackageNameLoggingRule>());
+  std::optional<AppPackageNameLoggingRule> cached_record =
       client->GetCachedAppPackageNameLoggingRule();
 
   EXPECT_TRUE(client->ShouldRecordPackageName());
@@ -277,7 +277,7 @@
 
   AwMetricsServiceClient* client = GetClient();
   client->SetAppPackageNameLoggingRule(
-      absl::optional<AppPackageNameLoggingRule>());
+      std::optional<AppPackageNameLoggingRule>());
 
   EXPECT_FALSE(client->ShouldRecordPackageName());
 
diff --git a/android_webview/browser/network_service/aw_proxying_url_loader_factory.cc b/android_webview/browser/network_service/aw_proxying_url_loader_factory.cc
index d724f1f..331b949 100644
--- a/android_webview/browser/network_service/aw_proxying_url_loader_factory.cc
+++ b/android_webview/browser/network_service/aw_proxying_url_loader_factory.cc
@@ -9,6 +9,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "android_webview/browser/android_protocol_handler.h"
 #include "android_webview/browser/aw_browser_context.h"
 #include "android_webview/browser/aw_contents_client_bridge.h"
@@ -46,7 +47,6 @@
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/mojom/early_hints.mojom.h"
 #include "services/network/public/mojom/fetch_api.mojom.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"
 #include "third_party/blink/public/mojom/origin_trial_feature/origin_trial_feature.mojom-shared.h"
 #include "url/gurl.h"
@@ -84,7 +84,7 @@
       mojo::PendingRemote<network::mojom::URLLoaderClient> client,
       mojo::PendingRemote<network::mojom::URLLoaderFactory> target_factory,
       bool intercept_only,
-      absl::optional<AwProxyingURLLoaderFactory::SecurityOptions>
+      std::optional<AwProxyingURLLoaderFactory::SecurityOptions>
           security_options,
       scoped_refptr<AwContentsOriginMatcher> xrw_allowlist_matcher,
       scoped_refptr<AwBrowserContextIoThreadHandle> browser_context_handle);
@@ -101,7 +101,7 @@
   void OnReceiveResponse(
       network::mojom::URLResponseHeadPtr head,
       mojo::ScopedDataPipeConsumerHandle body,
-      absl::optional<mojo_base::BigBuffer> cached_metadata) override;
+      std::optional<mojo_base::BigBuffer> cached_metadata) override;
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                          network::mojom::URLResponseHeadPtr head) override;
   void OnUploadProgress(int64_t current_position,
@@ -115,7 +115,7 @@
       const std::vector<std::string>& removed_headers,
       const net::HttpRequestHeaders& modified_headers,
       const net::HttpRequestHeaders& modified_cors_exempt_headers,
-      const absl::optional<GURL>& new_url) override;
+      const std::optional<GURL>& new_url) override;
   void SetPriority(net::RequestPriority priority,
                    int32_t intra_priority_value) override;
   void PauseReadingBodyFromNet() override;
@@ -180,7 +180,7 @@
 
   AwSettings::RequestedWithHeaderMode requested_with_header_mode;
 
-  absl::optional<AwProxyingURLLoaderFactory::SecurityOptions> security_options_;
+  std::optional<AwProxyingURLLoaderFactory::SecurityOptions> security_options_;
 
   // If the |target_loader_| called OnComplete with an error this stores it.
   // That way the destructor can send it to OnReceivedError if safe browsing
@@ -293,8 +293,7 @@
     mojo::PendingRemote<network::mojom::URLLoaderClient> client,
     mojo::PendingRemote<network::mojom::URLLoaderFactory> target_factory,
     bool intercept_only,
-    absl::optional<AwProxyingURLLoaderFactory::SecurityOptions>
-        security_options,
+    std::optional<AwProxyingURLLoaderFactory::SecurityOptions> security_options,
     scoped_refptr<AwContentsOriginMatcher> xrw_allowlist_matcher,
     scoped_refptr<AwBrowserContextIoThreadHandle> browser_context_handle)
     : frame_tree_node_id_(frame_tree_node_id),
@@ -624,7 +623,7 @@
           traffic_annotation_,
           std::make_unique<InterceptResponseDelegate>(
               std::move(response), weak_factory_.GetWeakPtr()),
-          absl::nullopt);
+          std::nullopt);
   loader->Start();
 }
 
@@ -687,7 +686,7 @@
 void InterceptedRequest::OnReceiveResponse(
     network::mojom::URLResponseHeadPtr head,
     mojo::ScopedDataPipeConsumerHandle body,
-    absl::optional<mojo_base::BigBuffer> cached_metadata) {
+    std::optional<mojo_base::BigBuffer> cached_metadata) {
   // intercept response headers here
   // pause/resume |proxied_client_receiver_| if necessary
 
@@ -765,7 +764,7 @@
     const std::vector<std::string>& removed_headers,
     const net::HttpRequestHeaders& modified_headers,
     const net::HttpRequestHeaders& modified_cors_exempt_headers,
-    const absl::optional<GURL>& new_url) {
+    const std::optional<GURL>& new_url) {
   if (target_loader_) {
     target_loader_->FollowRedirect(removed_headers, modified_headers,
                                    modified_cors_exempt_headers, new_url);
@@ -906,7 +905,7 @@
     mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver,
     mojo::PendingRemote<network::mojom::URLLoaderFactory> target_factory_remote,
     bool intercept_only,
-    absl::optional<SecurityOptions> security_options,
+    std::optional<SecurityOptions> security_options,
     scoped_refptr<AwContentsOriginMatcher> xrw_allowlist_matcher,
     scoped_refptr<AwBrowserContextIoThreadHandle> browser_context_handle)
     : frame_tree_node_id_(frame_tree_node_id),
@@ -935,7 +934,7 @@
     int frame_tree_node_id,
     mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver,
     mojo::PendingRemote<network::mojom::URLLoaderFactory> target_factory_remote,
-    absl::optional<SecurityOptions> security_options,
+    std::optional<SecurityOptions> security_options,
     scoped_refptr<AwContentsOriginMatcher> xrw_allowlist_matcher,
     scoped_refptr<AwBrowserContextIoThreadHandle> browser_context_handle) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
diff --git a/android_webview/browser/network_service/aw_proxying_url_loader_factory.h b/android_webview/browser/network_service/aw_proxying_url_loader_factory.h
index 5bea2cd..33708dd0 100644
--- a/android_webview/browser/network_service/aw_proxying_url_loader_factory.h
+++ b/android_webview/browser/network_service/aw_proxying_url_loader_factory.h
@@ -5,6 +5,7 @@
 #ifndef ANDROID_WEBVIEW_BROWSER_NETWORK_SERVICE_AW_PROXYING_URL_LOADER_FACTORY_H_
 #define ANDROID_WEBVIEW_BROWSER_NETWORK_SERVICE_AW_PROXYING_URL_LOADER_FACTORY_H_
 
+#include <optional>
 #include "android_webview/browser/network_service/aw_browser_context_io_thread_handle.h"
 #include "base/memory/weak_ptr.h"
 #include "components/embedder_support/android/util/android_stream_reader_url_loader.h"
@@ -15,7 +16,6 @@
 #include "services/network/public/mojom/url_loader.mojom.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 #include "services/network/public/mojom/url_response_head.mojom.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/origin.h"
 
 namespace net {
@@ -72,7 +72,7 @@
       mojo::PendingRemote<network::mojom::URLLoaderFactory>
           target_factory_remote,
       bool intercept_only,
-      absl::optional<SecurityOptions> security_options,
+      std::optional<SecurityOptions> security_options,
       scoped_refptr<AwContentsOriginMatcher> xrw_allowlist_matcher,
       scoped_refptr<AwBrowserContextIoThreadHandle> browser_context_handle);
 
@@ -88,7 +88,7 @@
       mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader,
       mojo::PendingRemote<network::mojom::URLLoaderFactory>
           target_factory_remote,
-      absl::optional<SecurityOptions> security_options,
+      std::optional<SecurityOptions> security_options,
       scoped_refptr<AwContentsOriginMatcher> xrw_allowlist_matcher,
       scoped_refptr<AwBrowserContextIoThreadHandle> browser_context_handle);
 
@@ -117,7 +117,7 @@
   // a response, the loader will abort loading.
   bool intercept_only_;
 
-  absl::optional<SecurityOptions> security_options_;
+  std::optional<SecurityOptions> security_options_;
 
   scoped_refptr<AwContentsOriginMatcher> xrw_allowlist_matcher_;
 
diff --git a/android_webview/browser/network_service/aw_web_resource_request.h b/android_webview/browser/network_service/aw_web_resource_request.h
index f336ffc..69f4a51 100644
--- a/android_webview/browser/network_service/aw_web_resource_request.h
+++ b/android_webview/browser/network_service/aw_web_resource_request.h
@@ -8,8 +8,8 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/android/scoped_java_ref.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 class HttpRequestHeaders;
@@ -62,7 +62,7 @@
   bool has_user_gesture;
   std::vector<std::string> header_names;
   std::vector<std::string> header_values;
-  absl::optional<bool> is_renderer_initiated;
+  std::optional<bool> is_renderer_initiated;
 };
 
 }  // namespace android_webview
diff --git a/android_webview/browser/tracing/aw_background_tracing_metrics_provider.h b/android_webview/browser/tracing/aw_background_tracing_metrics_provider.h
index 935860a..7052fd8 100644
--- a/android_webview/browser/tracing/aw_background_tracing_metrics_provider.h
+++ b/android_webview/browser/tracing/aw_background_tracing_metrics_provider.h
@@ -7,8 +7,8 @@
 
 #include "components/tracing/common/background_tracing_metrics_provider.h"
 
+#include <optional>
 #include "base/memory/weak_ptr.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace tracing {
 
diff --git a/android_webview/browser/tracing/aw_tracing_delegate.cc b/android_webview/browser/tracing/aw_tracing_delegate.cc
index f071f474..60792a6b 100644
--- a/android_webview/browser/tracing/aw_tracing_delegate.cc
+++ b/android_webview/browser/tracing/aw_tracing_delegate.cc
@@ -88,7 +88,7 @@
   return true;
 }
 
-absl::optional<base::Value::Dict> AwTracingDelegate::GenerateMetadataDict() {
+std::optional<base::Value::Dict> AwTracingDelegate::GenerateMetadataDict() {
   base::Value::Dict metadata_dict;
   metadata_dict.Set("revision", version_info::GetLastChange());
   return metadata_dict;
diff --git a/android_webview/browser/tracing/aw_tracing_delegate.h b/android_webview/browser/tracing/aw_tracing_delegate.h
index 8b37ebb..aa63baf 100644
--- a/android_webview/browser/tracing/aw_tracing_delegate.h
+++ b/android_webview/browser/tracing/aw_tracing_delegate.h
@@ -5,8 +5,8 @@
 #ifndef ANDROID_WEBVIEW_BROWSER_TRACING_AW_TRACING_DELEGATE_H_
 #define ANDROID_WEBVIEW_BROWSER_TRACING_AW_TRACING_DELEGATE_H_
 
+#include <optional>
 #include "content/public/browser/tracing_delegate.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class PrefRegistrySimple;
 
@@ -26,7 +26,7 @@
   // content::TracingDelegate implementation:
   bool OnBackgroundTracingActive(bool requires_anonymized_data) override;
   bool OnBackgroundTracingIdle(bool requires_anonymized_data) override;
-  absl::optional<base::Value::Dict> GenerateMetadataDict() override;
+  std::optional<base::Value::Dict> GenerateMetadataDict() override;
 
  private:
   bool IsAllowedToStartScenario() const;
diff --git a/android_webview/common/metrics/app_package_name_logging_rule.cc b/android_webview/common/metrics/app_package_name_logging_rule.cc
index c4f2c1b..db4ae5b 100644
--- a/android_webview/common/metrics/app_package_name_logging_rule.cc
+++ b/android_webview/common/metrics/app_package_name_logging_rule.cc
@@ -4,11 +4,11 @@
 
 #include "android_webview/common/metrics/app_package_name_logging_rule.h"
 
+#include <optional>
 #include "base/json/values_util.h"
 #include "base/time/time.h"
 #include "base/values.h"
 #include "base/version.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace android_webview {
 
@@ -47,23 +47,22 @@
 }
 
 // static
-absl::optional<AppPackageNameLoggingRule>
+std::optional<AppPackageNameLoggingRule>
 AppPackageNameLoggingRule::FromDictionary(const base::Value::Dict& dict) {
   const std::string* version_string = dict.FindString(kVersionKey);
   if (!version_string) {
-    return absl::optional<AppPackageNameLoggingRule>();
+    return std::optional<AppPackageNameLoggingRule>();
   }
   base::Version version(*version_string);
   if (!version.IsValid()) {
-    return absl::optional<AppPackageNameLoggingRule>();
+    return std::optional<AppPackageNameLoggingRule>();
   }
 
   const base::Value* expiry_date_value = dict.Find(kExpiryDateKey);
   if (!expiry_date_value) {
     return AppPackageNameLoggingRule(version, base::Time::Min());
   }
-  absl::optional<base::Time> expiry_date =
-      base::ValueToTime(*expiry_date_value);
+  std::optional<base::Time> expiry_date = base::ValueToTime(*expiry_date_value);
   if (!expiry_date.has_value()) {
     return AppPackageNameLoggingRule(version, base::Time::Min());
   }
diff --git a/android_webview/common/metrics/app_package_name_logging_rule.h b/android_webview/common/metrics/app_package_name_logging_rule.h
index 900e7fe..8a2875e 100644
--- a/android_webview/common/metrics/app_package_name_logging_rule.h
+++ b/android_webview/common/metrics/app_package_name_logging_rule.h
@@ -5,10 +5,10 @@
 #ifndef ANDROID_WEBVIEW_COMMON_METRICS_APP_PACKAGE_NAME_LOGGING_RULE_H_
 #define ANDROID_WEBVIEW_COMMON_METRICS_APP_PACKAGE_NAME_LOGGING_RULE_H_
 
+#include <optional>
 #include "base/time/time.h"
 #include "base/values.h"
 #include "base/version.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace android_webview {
 
@@ -41,7 +41,7 @@
 
   // Creates a valid AppPackageNameLoggingRule from a dictionary, or null if
   // the dictionary have invalid values.
-  static absl::optional<AppPackageNameLoggingRule> FromDictionary(
+  static std::optional<AppPackageNameLoggingRule> FromDictionary(
       const base::Value::Dict& dict);
 
  private:
diff --git a/android_webview/common/metrics/app_package_name_logging_rule_unittests.cc b/android_webview/common/metrics/app_package_name_logging_rule_unittests.cc
index 7886dbf..72207c0 100644
--- a/android_webview/common/metrics/app_package_name_logging_rule_unittests.cc
+++ b/android_webview/common/metrics/app_package_name_logging_rule_unittests.cc
@@ -4,10 +4,10 @@
 
 #include "android_webview/common/metrics/app_package_name_logging_rule.h"
 
+#include <optional>
 #include "base/time/time.h"
 #include "base/version.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace android_webview {
 
@@ -32,7 +32,7 @@
   base::Time one_day_from_now = base::Time::Now() + base::Days(1);
   {
     AppPackageNameLoggingRule expected_record(version, one_day_from_now);
-    absl::optional<AppPackageNameLoggingRule> record =
+    std::optional<AppPackageNameLoggingRule> record =
         AppPackageNameLoggingRule::FromDictionary(
             expected_record.ToDictionary());
     ASSERT_TRUE(record.has_value());
@@ -41,7 +41,7 @@
 
   {
     AppPackageNameLoggingRule expected_record(version, base::Time::Min());
-    absl::optional<AppPackageNameLoggingRule> record =
+    std::optional<AppPackageNameLoggingRule> record =
         AppPackageNameLoggingRule::FromDictionary(
             expected_record.ToDictionary());
     ASSERT_TRUE(record.has_value());
@@ -49,7 +49,7 @@
   }
 
   {
-    absl::optional<AppPackageNameLoggingRule> record =
+    std::optional<AppPackageNameLoggingRule> record =
         AppPackageNameLoggingRule::FromDictionary(base::Value::Dict());
     EXPECT_FALSE(record.has_value());
   }
diff --git a/android_webview/lib/aw_main_delegate.cc b/android_webview/lib/aw_main_delegate.cc
index 2bad87c..5d1e8bf 100644
--- a/android_webview/lib/aw_main_delegate.cc
+++ b/android_webview/lib/aw_main_delegate.cc
@@ -88,7 +88,7 @@
 
 AwMainDelegate::~AwMainDelegate() = default;
 
-absl::optional<int> AwMainDelegate::BasicStartupComplete() {
+std::optional<int> AwMainDelegate::BasicStartupComplete() {
   TRACE_EVENT0("startup", "AwMainDelegate::BasicStartupComplete");
   base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
 
@@ -313,7 +313,7 @@
   // renderer processes. See also: switches::kInProcessGPU above.
   content::ForceInProcessNetworkService();
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void AwMainDelegate::PreSandboxStartup() {
@@ -394,7 +394,7 @@
       variations::VariationsIdsProvider::Mode::kDontSendSignedInVariations);
 }
 
-absl::optional<int> AwMainDelegate::PostEarlyInitialization(
+std::optional<int> AwMainDelegate::PostEarlyInitialization(
     InvokedIn invoked_in) {
   const bool is_browser_process =
       absl::holds_alternative<InvokedInBrowserProcess>(invoked_in);
@@ -406,7 +406,7 @@
 
   InitializeMemorySystem(is_browser_process);
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 content::ContentClient* AwMainDelegate::CreateContentClient() {
diff --git a/android_webview/lib/aw_main_delegate.h b/android_webview/lib/aw_main_delegate.h
index b2a41d7..693558cb 100644
--- a/android_webview/lib/aw_main_delegate.h
+++ b/android_webview/lib/aw_main_delegate.h
@@ -39,7 +39,7 @@
 
  private:
   // content::ContentMainDelegate implementation:
-  absl::optional<int> BasicStartupComplete() override;
+  std::optional<int> BasicStartupComplete() override;
   void PreSandboxStartup() override;
   absl::variant<int, content::MainFunctionParams> RunProcess(
       const std::string& process_type,
@@ -48,7 +48,7 @@
   bool ShouldCreateFeatureList(InvokedIn invoked_in) override;
   bool ShouldInitializeMojo(InvokedIn invoked_in) override;
   variations::VariationsIdsProvider* CreateVariationsIdsProvider() override;
-  absl::optional<int> PostEarlyInitialization(InvokedIn invoked_in) override;
+  std::optional<int> PostEarlyInitialization(InvokedIn invoked_in) override;
   content::ContentClient* CreateContentClient() override;
   content::ContentBrowserClient* CreateContentBrowserClient() override;
   content::ContentGpuClient* CreateContentGpuClient() override;
diff --git a/android_webview/nonembedded/component_updater/aw_component_update_service.cc b/android_webview/nonembedded/component_updater/aw_component_update_service.cc
index 3a764c5b..76889e9 100644
--- a/android_webview/nonembedded/component_updater/aw_component_update_service.cc
+++ b/android_webview/nonembedded/component_updater/aw_component_update_service.cc
@@ -191,7 +191,7 @@
   return crx;
 }
 
-absl::optional<component_updater::ComponentRegistration>
+std::optional<component_updater::ComponentRegistration>
 AwComponentUpdateService::GetComponent(const std::string& id) const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   return component_updater::GetComponent(components_, id);
@@ -200,16 +200,15 @@
 void AwComponentUpdateService::GetCrxComponents(
     const std::vector<std::string>& ids,
     base::OnceCallback<
-        void(const std::vector<absl::optional<update_client::CrxComponent>>&)>
+        void(const std::vector<std::optional<update_client::CrxComponent>>&)>
         callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  std::vector<absl::optional<update_client::CrxComponent>> crxs;
-  for (absl::optional<component_updater::ComponentRegistration> item :
+  std::vector<std::optional<update_client::CrxComponent>> crxs;
+  for (std::optional<component_updater::ComponentRegistration> item :
        component_updater::GetCrxComponents(components_, ids)) {
     crxs.push_back(
-        item
-            ? absl::optional<update_client::CrxComponent>{ToCrxComponent(*item)}
-            : absl::nullopt);
+        item ? std::optional<update_client::CrxComponent>{ToCrxComponent(*item)}
+             : std::nullopt);
   }
   std::move(callback).Run(crxs);
 }
diff --git a/android_webview/nonembedded/component_updater/aw_component_update_service.h b/android_webview/nonembedded/component_updater/aw_component_update_service.h
index babef45e..93aa24e 100644
--- a/android_webview/nonembedded/component_updater/aw_component_update_service.h
+++ b/android_webview/nonembedded/component_updater/aw_component_update_service.h
@@ -9,6 +9,7 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/android/scoped_java_ref.h"
 #include "base/containers/flat_map.h"
 #include "base/functional/callback_forward.h"
@@ -19,7 +20,6 @@
 #include "base/sequence_checker.h"
 #include "components/update_client/update_client.h"
 #include "components/update_client/update_client_errors.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class TimeTicks;
@@ -75,12 +75,12 @@
                         update_client::Error error);
   update_client::CrxComponent ToCrxComponent(
       const component_updater::ComponentRegistration& component) const;
-  absl::optional<component_updater::ComponentRegistration> GetComponent(
+  std::optional<component_updater::ComponentRegistration> GetComponent(
       const std::string& id) const;
   void GetCrxComponents(
       const std::vector<std::string>& ids,
       base::OnceCallback<
-          void(const std::vector<absl::optional<update_client::CrxComponent>>&)>
+          void(const std::vector<std::optional<update_client::CrxComponent>>&)>
           callback);
   void ScheduleUpdatesOfRegisteredComponents(UpdateCallback on_finished_updates,
                                              bool on_demand_update);
diff --git a/android_webview/nonembedded/component_updater/aw_component_update_service_test.cc b/android_webview/nonembedded/component_updater/aw_component_update_service_test.cc
index bcfdca91..e3fa53c 100644
--- a/android_webview/nonembedded/component_updater/aw_component_update_service_test.cc
+++ b/android_webview/nonembedded/component_updater/aw_component_update_service_test.cc
@@ -10,6 +10,7 @@
 #include <memory>
 #include <utility>
 
+#include <optional>
 #include "android_webview/common/aw_paths.h"
 #include "android_webview/nonembedded/component_updater/aw_component_updater_configurator.h"
 #include "base/android/path_utils.h"
@@ -32,7 +33,6 @@
 #include "components/update_client/network.h"
 #include "components/update_client/update_client.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace android_webview {
@@ -313,7 +313,7 @@
   base::Version GetVersion() const { return version_; }
 
  private:
-  absl::optional<base::Value::Dict> manifest_;
+  std::optional<base::Value::Dict> manifest_;
   base::FilePath install_dir_;
   base::Version version_;
 };
diff --git a/android_webview/nonembedded/component_updater/aw_component_updater_configurator.cc b/android_webview/nonembedded/component_updater/aw_component_updater_configurator.cc
index 9131e43f..48d54e5 100644
--- a/android_webview/nonembedded/component_updater/aw_component_updater_configurator.cc
+++ b/android_webview/nonembedded/component_updater/aw_component_updater_configurator.cc
@@ -8,6 +8,7 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "android_webview/nonembedded/net/network_impl.h"
 #include "base/android/path_utils.h"
 #include "base/files/file_path.h"
@@ -29,7 +30,6 @@
 #include "components/version_info/android/channel_getter.h"
 #include "components/version_info/version_info.h"
 #include "components/version_info/version_info_values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace android_webview {
 
@@ -184,9 +184,9 @@
   return configurator_impl_.GetProtocolHandlerFactory();
 }
 
-absl::optional<bool>
-AwComponentUpdaterConfigurator::IsMachineExternallyManaged() const {
-  return absl::nullopt;
+std::optional<bool> AwComponentUpdaterConfigurator::IsMachineExternallyManaged()
+    const {
+  return std::nullopt;
 }
 
 update_client::UpdaterStateProvider
@@ -201,13 +201,13 @@
                                                               pref_service);
 }
 
-absl::optional<base::FilePath> AwComponentUpdaterConfigurator::GetCrxCachePath()
+std::optional<base::FilePath> AwComponentUpdaterConfigurator::GetCrxCachePath()
     const {
   base::FilePath path;
   return base::android::GetCacheDirectory(&path)
-             ? absl::optional<base::FilePath>(
+             ? std::optional<base::FilePath>(
                    path.AppendASCII(("webview_crx_cache")))
-             : absl::nullopt;
+             : std::nullopt;
 }
 
 }  // namespace android_webview
diff --git a/android_webview/nonembedded/component_updater/aw_component_updater_configurator.h b/android_webview/nonembedded/component_updater/aw_component_updater_configurator.h
index 6b96c89..8a7e3d8 100644
--- a/android_webview/nonembedded/component_updater/aw_component_updater_configurator.h
+++ b/android_webview/nonembedded/component_updater/aw_component_updater_configurator.h
@@ -5,6 +5,7 @@
 #ifndef ANDROID_WEBVIEW_NONEMBEDDED_COMPONENT_UPDATER_AW_COMPONENT_UPDATER_CONFIGURATOR_H_
 #define ANDROID_WEBVIEW_NONEMBEDDED_COMPONENT_UPDATER_AW_COMPONENT_UPDATER_CONFIGURATOR_H_
 
+#include <optional>
 #include "base/files/file_path.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
@@ -19,7 +20,6 @@
 #include "components/update_client/patcher.h"
 #include "components/update_client/protocol_handler.h"
 #include "components/update_client/unzipper.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class PrefService;
 
@@ -62,9 +62,9 @@
   bool IsPerUserInstall() const override;
   std::unique_ptr<update_client::ProtocolHandlerFactory>
   GetProtocolHandlerFactory() const override;
-  absl::optional<bool> IsMachineExternallyManaged() const override;
+  std::optional<bool> IsMachineExternallyManaged() const override;
   update_client::UpdaterStateProvider GetUpdaterStateProvider() const override;
-  absl::optional<base::FilePath> GetCrxCachePath() const override;
+  std::optional<base::FilePath> GetCrxCachePath() const override;
 
  protected:
   friend class base::RefCountedThreadSafe<AwComponentUpdaterConfigurator>;
diff --git a/apps/launcher.cc b/apps/launcher.cc
index d8b18e5..2701ae3 100644
--- a/apps/launcher.cc
+++ b/apps/launcher.cc
@@ -127,7 +127,7 @@
   PlatformAppPathLauncher(const PlatformAppPathLauncher&) = delete;
   PlatformAppPathLauncher& operator=(const PlatformAppPathLauncher&) = delete;
 
-  void set_action_data(absl::optional<app_runtime::ActionData> action_data) {
+  void set_action_data(std::optional<app_runtime::ActionData> action_data) {
     action_data_ = std::move(action_data);
   }
 
@@ -217,7 +217,7 @@
 
     // TODO(crbug.com/1354063): This conditional block is being added here
     // temporarily, and should be removed once the underlying type of
-    // |launch_data.action_data| is wrapped with absl::optional<T>.
+    // |launch_data.action_data| is wrapped with std::optional<T>.
     if (action_data_) {
       launch_data.action_data = std::move(*action_data_);
       action_data_.reset();
@@ -352,7 +352,7 @@
   const std::string extension_id;
   extensions::AppLaunchSource launch_source_ =
       extensions::AppLaunchSource::kSourceFileHandler;
-  absl::optional<app_runtime::ActionData> action_data_;
+  std::optional<app_runtime::ActionData> action_data_;
   // A list of files and directories to be passed through to the app.
   std::vector<base::FilePath> entry_paths_;
   // A corresponding list with EntryInfo for every base::FilePath in
@@ -505,7 +505,7 @@
   if (listening_to_launch && had_windows) {
     AppRuntimeEventRouter::DispatchOnLaunchedEvent(
         context, app, extensions::AppLaunchSource::kSourceRestart,
-        absl::nullopt);
+        std::nullopt);
   }
 }
 
diff --git a/apps/saved_files_service.cc b/apps/saved_files_service.cc
index 10fc8c4..5e535ba 100644
--- a/apps/saved_files_service.cc
+++ b/apps/saved_files_service.cc
@@ -12,6 +12,7 @@
 #include <unordered_map>
 #include <utility>
 
+#include <optional>
 #include "apps/saved_files_service_factory.h"
 #include "base/json/values_util.h"
 #include "base/memory/raw_ptr.h"
@@ -25,7 +26,6 @@
 #include "extensions/common/permissions/api_permission.h"
 #include "extensions/common/permissions/permission_set.h"
 #include "extensions/common/permissions/permissions_data.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace apps {
 
@@ -105,7 +105,7 @@
 // Clears all SavedFileEntry for the app from ExtensionPrefs.
 void ClearSavedFileEntries(ExtensionPrefs* prefs,
                            const std::string& extension_id) {
-  prefs->UpdateExtensionPref(extension_id, kFileEntries, absl::nullopt);
+  prefs->UpdateExtensionPref(extension_id, kFileEntries, std::nullopt);
 }
 
 // Returns all SavedFileEntries for the app.
@@ -127,13 +127,13 @@
     const base::Value* path_value = file_entry->Find(kFileEntryPath);
     if (!path_value)
       continue;
-    absl::optional<base::FilePath> file_path =
+    std::optional<base::FilePath> file_path =
         base::ValueToFilePath(*path_value);
     if (!file_path)
       continue;
     bool is_directory =
         file_entry->FindBool(kFileEntryIsDirectory).value_or(false);
-    const absl::optional<int> sequence_number =
+    const std::optional<int> sequence_number =
         file_entry->FindInt(kFileEntrySequenceNumber);
     if (!sequence_number || sequence_number.value() == 0)
       continue;
diff --git a/ash/public/cpp/scale_utility.cc b/ash/public/cpp/scale_utility.cc
index e55a0f4..d1672f3 100644
--- a/ash/public/cpp/scale_utility.cc
+++ b/ash/public/cpp/scale_utility.cc
@@ -10,8 +10,9 @@
 namespace ash {
 
 float GetScaleFactorForTransform(const gfx::Transform& transform) {
-  if (absl::optional<gfx::DecomposedTransform> decomp = transform.Decompose())
+  if (std::optional<gfx::DecomposedTransform> decomp = transform.Decompose()) {
     return decomp->scale[0];
+  }
   return 1.0f;
 }
 
diff --git a/ash/public/cpp/system_notification_builder.h b/ash/public/cpp/system_notification_builder.h
index 0ddb7357..b3df262 100644
--- a/ash/public/cpp/system_notification_builder.h
+++ b/ash/public/cpp/system_notification_builder.h
@@ -6,6 +6,7 @@
 #define ASH_PUBLIC_CPP_SYSTEM_NOTIFICATION_BUILDER_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "ash/constants/notifier_catalogs.h"
@@ -262,7 +263,7 @@
   std::unique_ptr<message_center::Notification> BuildPtr(bool keep_timestamp);
 
   // Get a NotifierId by combining `catalog_name_` and `id_` if `notifier_id_`
-  // is `absl::nullopt`, otherwise returns the value of `notifier_id_`.
+  // is `std::nullopt`, otherwise returns the value of `notifier_id_`.
   // The `notifier_id_` should never be read directly but only through this
   // method.
   message_center::NotifierId GetNotifierId() const;
@@ -275,7 +276,7 @@
   std::u16string message_;
   std::u16string display_source_;
   GURL origin_url_;
-  absl::optional<message_center::NotifierId> notifier_id_;
+  std::optional<message_center::NotifierId> notifier_id_;
   NotificationCatalogName catalog_name_ = NotificationCatalogName::kNone;
   scoped_refptr<message_center::NotificationDelegate> delegate_ = nullptr;
   raw_ptr<const gfx::VectorIcon, ExperimentalAsh> small_image_ =
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.cc
index 089fdb8b..729124be 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.h"
 
 #include <memory>
+#include <optional>
 
 #include "base/check.h"
 #include "base/check_op.h"
@@ -26,7 +27,7 @@
   crypto::SignatureVerifier::SignatureAlgorithm Algorithm() const override;
   std::vector<uint8_t> GetSubjectPublicKeyInfo() const override;
   std::vector<uint8_t> GetWrappedKey() const override;
-  absl::optional<std::vector<uint8_t>> SignSlowly(
+  std::optional<std::vector<uint8_t>> SignSlowly(
       base::span<const uint8_t> data) override;
 
  private:
@@ -63,7 +64,7 @@
   return wrapped;
 }
 
-absl::optional<std::vector<uint8_t>> ECSigningKey::SignSlowly(
+std::optional<std::vector<uint8_t>> ECSigningKey::SignSlowly(
     base::span<const uint8_t> data) {
   std::vector<uint8_t> signature;
   auto signer = crypto::ECSignatureCreator::Create(key_.get());
@@ -78,7 +79,7 @@
 ECSigningKeyProvider::ECSigningKeyProvider() = default;
 ECSigningKeyProvider::~ECSigningKeyProvider() = default;
 
-absl::optional<crypto::SignatureVerifier::SignatureAlgorithm>
+std::optional<crypto::SignatureVerifier::SignatureAlgorithm>
 ECSigningKeyProvider::SelectAlgorithm(
     base::span<const crypto::SignatureVerifier::SignatureAlgorithm>
         acceptable_algorithms) {
@@ -87,7 +88,7 @@
       return crypto::SignatureVerifier::ECDSA_SHA256;
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 std::unique_ptr<crypto::UnexportableSigningKey>
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.h
index c2ddc155..66329d0 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.h
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.h
@@ -21,7 +21,7 @@
   ~ECSigningKeyProvider() override;
 
   // crypto::UnexportableKeyProvider:
-  absl::optional<crypto::SignatureVerifier::SignatureAlgorithm> SelectAlgorithm(
+  std::optional<crypto::SignatureVerifier::SignatureAlgorithm> SelectAlgorithm(
       base::span<const crypto::SignatureVerifier::SignatureAlgorithm>
           acceptable_algorithms) override;
   std::unique_ptr<crypto::UnexportableSigningKey> GenerateSigningKeySlowly(
diff --git a/chromecast/app/cast_main_delegate.cc b/chromecast/app/cast_main_delegate.cc
index cdec40b1..245044f2 100644
--- a/chromecast/app/cast_main_delegate.cc
+++ b/chromecast/app/cast_main_delegate.cc
@@ -72,7 +72,7 @@
 
 CastMainDelegate::~CastMainDelegate() {}
 
-absl::optional<int> CastMainDelegate::BasicStartupComplete() {
+std::optional<int> CastMainDelegate::BasicStartupComplete() {
   RegisterPathProvider();
 
   logging::LoggingSettings settings;
@@ -160,7 +160,7 @@
   if (settings.logging_dest & logging::LOG_TO_FILE) {
     LOG(INFO) << "Logging to file: " << settings.log_file_path;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void CastMainDelegate::PreSandboxStartup() {
@@ -236,11 +236,11 @@
   return ShouldCreateFeatureList(invoked_in);
 }
 
-absl::optional<int> CastMainDelegate::PostEarlyInitialization(
+std::optional<int> CastMainDelegate::PostEarlyInitialization(
     InvokedIn invoked_in) {
   if (ShouldCreateFeatureList(invoked_in)) {
     // content is handling the feature list.
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   DCHECK(cast_feature_list_creator_);
@@ -284,7 +284,7 @@
 
   content::InitializeMojoCore();
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void CastMainDelegate::InitializeResourceBundle() {
diff --git a/chromecast/app/cast_main_delegate.h b/chromecast/app/cast_main_delegate.h
index d285d217..7866ee0f 100644
--- a/chromecast/app/cast_main_delegate.h
+++ b/chromecast/app/cast_main_delegate.h
@@ -7,10 +7,10 @@
 
 #include <memory>
 
+#include <optional>
 #include "build/build_config.h"
 #include "chromecast/common/cast_content_client.h"
 #include "content/public/app/content_main_delegate.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace content {
 class BrowserMainRunner;
@@ -38,7 +38,7 @@
   ~CastMainDelegate() override;
 
   // content::ContentMainDelegate implementation:
-  absl::optional<int> BasicStartupComplete() override;
+  std::optional<int> BasicStartupComplete() override;
   void PreSandboxStartup() override;
   absl::variant<int, content::MainFunctionParams> RunProcess(
       const std::string& process_type,
@@ -48,7 +48,7 @@
 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
   bool ShouldCreateFeatureList(InvokedIn invoked_in) override;
   bool ShouldInitializeMojo(InvokedIn invoked_in) override;
-  absl::optional<int> PostEarlyInitialization(InvokedIn invoked_in) override;
+  std::optional<int> PostEarlyInitialization(InvokedIn invoked_in) override;
   content::ContentClient* CreateContentClient() override;
   content::ContentBrowserClient* CreateContentBrowserClient() override;
   content::ContentGpuClient* CreateContentGpuClient() override;
diff --git a/chromecast/base/device_capabilities_impl_unittest.cc b/chromecast/base/device_capabilities_impl_unittest.cc
index c01d2f7..ed5fa51 100644
--- a/chromecast/base/device_capabilities_impl_unittest.cc
+++ b/chromecast/base/device_capabilities_impl_unittest.cc
@@ -582,7 +582,7 @@
 
 // Test MergeDictionary.
 TEST_F(DeviceCapabilitiesImplTest, MergeDictionary) {
-  absl::optional<base::Value::Dict> deserialized_value =
+  std::optional<base::Value::Dict> deserialized_value =
       base::JSONReader::ReadDict(kSampleDictionaryCapability);
   ASSERT_TRUE(deserialized_value);
 
diff --git a/chromecast/base/metrics/cast_metrics_helper_unittest.cc b/chromecast/base/metrics/cast_metrics_helper_unittest.cc
index 2a8dadd..ebc6a3178 100644
--- a/chromecast/base/metrics/cast_metrics_helper_unittest.cc
+++ b/chromecast/base/metrics/cast_metrics_helper_unittest.cc
@@ -37,7 +37,7 @@
 constexpr base::TimeDelta kAppLoadTimeout = base::Minutes(5);
 
 MATCHER_P2(HasDouble, key, value, "") {
-  const absl::optional<base::Value> v = base::JSONReader::Read(arg);
+  const std::optional<base::Value> v = base::JSONReader::Read(arg);
   if (!v || !v->is_dict()) {
     return false;
   }
@@ -47,7 +47,7 @@
 }
 
 MATCHER_P2(HasInt, key, value, "") {
-  const absl::optional<base::Value> v = base::JSONReader::Read(arg);
+  const std::optional<base::Value> v = base::JSONReader::Read(arg);
   if (!v || !v->is_dict()) {
     return false;
   }
@@ -57,7 +57,7 @@
 }
 
 MATCHER_P2(HasString, key, value, "") {
-  const absl::optional<base::Value> v = base::JSONReader::Read(arg);
+  const std::optional<base::Value> v = base::JSONReader::Read(arg);
   if (!v || !v->is_dict()) {
     return false;
   }
diff --git a/chromecast/bindings/shared/proto_serializer.h b/chromecast/bindings/shared/proto_serializer.h
index 451d061..258e864 100644
--- a/chromecast/bindings/shared/proto_serializer.h
+++ b/chromecast/bindings/shared/proto_serializer.h
@@ -5,8 +5,8 @@
 #ifndef CHROMECAST_BINDINGS_SHARED_PROTO_SERIALIZER_H_
 #define CHROMECAST_BINDINGS_SHARED_PROTO_SERIALIZER_H_
 
+#include <optional>
 #include "base/base64.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace chromecast {
 namespace bindings {
@@ -32,15 +32,15 @@
   // Deserializes |base64| to its proto representation, parsed into |result|.
   // Returns a value if parsing is successful; otherwise, returns false. Used
   // by bindings frontends and backends for consistent serialization logic.
-  static absl::optional<T> Deserialize(base::StringPiece base64_proto) {
+  static std::optional<T> Deserialize(base::StringPiece base64_proto) {
     std::string decoded;
     if (!base::Base64Decode(base64_proto, &decoded)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     T result;
-    return result.ParseFromString(decoded) ? absl::make_optional<T>(result)
-                                           : absl::nullopt;
+    return result.ParseFromString(decoded) ? std::make_optional<T>(result)
+                                           : std::nullopt;
   }
 };
 
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc
index 4cce48520..77755d3 100644
--- a/chromecast/browser/cast_content_browser_client.cc
+++ b/chromecast/browser/cast_content_browser_client.cc
@@ -691,14 +691,14 @@
   return true;
 }
 
-absl::optional<service_manager::Manifest>
+std::optional<service_manager::Manifest>
 CastContentBrowserClient::GetServiceManifestOverlay(
     base::StringPiece service_name) {
   if (service_name == ServiceManagerContext::kBrowserServiceName) {
     return GetCastContentBrowserOverlayManifest();
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 std::vector<service_manager::Manifest>
@@ -828,7 +828,7 @@
 void CastContentBrowserClient::RegisterNonNetworkSubresourceURLLoaderFactories(
     int render_process_id,
     int render_frame_id,
-    const absl::optional<url::Origin>& request_initiator_origin,
+    const std::optional<url::Origin>& request_initiator_origin,
     NonNetworkURLLoaderFactoryMap* factories) {
   if (render_frame_id == MSG_ROUTING_NONE) {
     LOG(ERROR) << "Service worker not supported.";
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h
index 82edb81c..77a22da 100644
--- a/chromecast/browser/cast_content_browser_client.h
+++ b/chromecast/browser/cast_content_browser_client.h
@@ -167,7 +167,7 @@
   virtual void RunServiceInstance(
       const service_manager::Identity& identity,
       mojo::PendingReceiver<service_manager::mojom::Service>* receiver);
-  virtual absl::optional<service_manager::Manifest> GetServiceManifestOverlay(
+  virtual std::optional<service_manager::Manifest> GetServiceManifestOverlay(
       base::StringPiece service_name);
   std::vector<service_manager::Manifest> GetExtraServiceManifests();
   std::vector<std::string> GetStartupServices();
@@ -245,7 +245,7 @@
   void RegisterNonNetworkSubresourceURLLoaderFactories(
       int render_process_id,
       int render_frame_id,
-      const absl::optional<url::Origin>& request_initiator_origin,
+      const std::optional<url::Origin>& request_initiator_origin,
       NonNetworkURLLoaderFactoryMap* factories) override;
   void OnNetworkServiceCreated(
       network::mojom::NetworkService* network_service) override;
diff --git a/chromecast/browser/cast_media_blocker.h b/chromecast/browser/cast_media_blocker.h
index 12706bd..2a5f176a 100644
--- a/chromecast/browser/cast_media_blocker.h
+++ b/chromecast/browser/cast_media_blocker.h
@@ -52,7 +52,7 @@
   void MediaSessionInfoChanged(
       media_session::mojom::MediaSessionInfoPtr session_info) override;
   void MediaSessionMetadataChanged(
-      const absl::optional<media_session::MediaMetadata>& metadata) override {}
+      const std::optional<media_session::MediaMetadata>& metadata) override {}
   void MediaSessionActionsChanged(
       const std::vector<media_session::mojom::MediaSessionAction>& action)
       override {}
@@ -61,7 +61,7 @@
                            std::vector<media_session::MediaImage>>& images)
       override {}
   void MediaSessionPositionChanged(
-      const absl::optional<media_session::MediaPosition>& position) override {}
+      const std::optional<media_session::MediaPosition>& position) override {}
 
  private:
   friend shell::CastMediaBlockerTest;
diff --git a/chromecast/browser/cast_web_contents.h b/chromecast/browser/cast_web_contents.h
index d0fa2bb..4bec6c8 100644
--- a/chromecast/browser/cast_web_contents.h
+++ b/chromecast/browser/cast_web_contents.h
@@ -8,6 +8,7 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/containers/flat_set.h"
 #include "base/functional/callback_forward.h"
 #include "base/observer_list.h"
@@ -26,7 +27,6 @@
 #include "mojo/public/cpp/bindings/receiver_set.h"
 #include "mojo/public/cpp/bindings/remote_set.h"
 #include "services/service_manager/public/cpp/interface_provider.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/messaging/web_message_port.h"
 #include "ui/gfx/geometry/rect.h"
 #include "url/gurl.h"
diff --git a/chromecast/browser/cast_web_contents_browsertest.cc b/chromecast/browser/cast_web_contents_browsertest.cc
index 49f0ecb..d9885f9 100644
--- a/chromecast/browser/cast_web_contents_browsertest.cc
+++ b/chromecast/browser/cast_web_contents_browsertest.cc
@@ -175,8 +175,8 @@
   ~TestMessageReceiver() override = default;
 
   void WaitForNextIncomingMessage(
-      base::OnceCallback<
-          void(std::string, absl::optional<blink::WebMessagePort>)> callback) {
+      base::OnceCallback<void(std::string,
+                              std::optional<blink::WebMessagePort>)> callback) {
     DCHECK(message_received_callback_.is_null())
         << "Only one waiting event is allowed.";
     message_received_callback_ = std::move(callback);
@@ -194,12 +194,12 @@
       return false;
     }
 
-    absl::optional<blink::WebMessagePort> incoming_port = absl::nullopt;
+    std::optional<blink::WebMessagePort> incoming_port = std::nullopt;
     // Only one MessagePort should be sent to here.
     if (!message.ports.empty()) {
       DCHECK(message.ports.size() == 1)
           << "Only one control port can be provided";
-      incoming_port = absl::make_optional<blink::WebMessagePort>(
+      incoming_port = std::make_optional<blink::WebMessagePort>(
           std::move(message.ports[0]));
     }
 
@@ -216,7 +216,7 @@
   }
 
   base::OnceCallback<void(std::string,
-                          absl::optional<blink::WebMessagePort> incoming_port)>
+                          std::optional<blink::WebMessagePort> incoming_port)>
       message_received_callback_;
 
   base::OnceCallback<void()> on_pipe_error_callback_;
@@ -809,7 +809,7 @@
     auto quit_closure = run_loop.QuitClosure();
     auto received_message_callback = base::BindOnce(
         [](base::OnceClosure loop_quit_closure, std::string port_msg,
-           absl::optional<blink::WebMessagePort> incoming_port) {
+           std::optional<blink::WebMessagePort> incoming_port) {
           EXPECT_EQ("got_port", port_msg);
           std::move(loop_quit_closure).Run();
         },
@@ -830,7 +830,7 @@
     auto quit_closure = run_loop.QuitClosure();
     auto received_message_callback = base::BindOnce(
         [](base::OnceClosure loop_quit_closure, std::string port_msg,
-           absl::optional<blink::WebMessagePort> incoming_port) {
+           std::optional<blink::WebMessagePort> incoming_port) {
           EXPECT_EQ("ack ping", port_msg);
           std::move(loop_quit_closure).Run();
         },
@@ -876,7 +876,7 @@
     auto quit_closure = run_loop.QuitClosure();
     auto received_message_callback = base::BindOnce(
         [](base::OnceClosure loop_quit_closure, std::string port_msg,
-           absl::optional<blink::WebMessagePort> incoming_port) {
+           std::optional<blink::WebMessagePort> incoming_port) {
           EXPECT_EQ("got_port", port_msg);
           std::move(loop_quit_closure).Run();
         },
diff --git a/chromecast/browser/cast_web_contents_impl.cc b/chromecast/browser/cast_web_contents_impl.cc
index e3dd24e..43890e6 100644
--- a/chromecast/browser/cast_web_contents_impl.cc
+++ b/chromecast/browser/cast_web_contents_impl.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include <optional>
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "base/logging.h"
@@ -41,7 +42,6 @@
 #include "mojo/public/cpp/bindings/associated_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "net/base/net_errors.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
 #include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h"
 #include "third_party/blink/public/mojom/autoplay/autoplay.mojom.h"
@@ -397,7 +397,7 @@
   data_utf16 = base::UTF8ToUTF16(data);
 
   // If origin is set as wildcard, no origin scoping would be applied.
-  absl::optional<std::u16string> target_origin_utf16;
+  std::optional<std::u16string> target_origin_utf16;
   constexpr char kWildcardOrigin[] = "*";
   if (target_origin != kWildcardOrigin) {
     target_origin_utf16 = base::UTF8ToUTF16(target_origin);
diff --git a/chromecast/browser/cast_web_contents_impl.h b/chromecast/browser/cast_web_contents_impl.h
index 43afceb5..b164a30 100644
--- a/chromecast/browser/cast_web_contents_impl.h
+++ b/chromecast/browser/cast_web_contents_impl.h
@@ -11,6 +11,7 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/containers/flat_map.h"
 #include "base/containers/flat_set.h"
 #include "base/memory/platform_shared_memory_region.h"
@@ -36,7 +37,6 @@
 #include "mojo/public/cpp/bindings/associated_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "services/service_manager/public/cpp/interface_provider.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/mojom/favicon/favicon_url.mojom-forward.h"
 
 namespace content {
@@ -175,13 +175,13 @@
 
   content::WebContents* web_contents_;
   mojom::CastWebViewParamsPtr params_;
-  absl::optional<url_rewrite::UrlRequestRewriteRulesManager>
+  std::optional<url_rewrite::UrlRequestRewriteRulesManager>
       url_rewrite_rules_manager_;
   PageState page_state_;
   PageState last_state_;
   shell::RemoteDebuggingServer* const remote_debugging_server_;
   std::unique_ptr<CastMediaBlocker> media_blocker_;
-  absl::optional<std::vector<std::string>> activity_url_filter_;
+  std::optional<std::vector<std::string>> activity_url_filter_;
 
   // Retained so that this observer can be removed before being destroyed:
   content::RenderProcessHost* main_process_host_;
diff --git a/chromecast/browser/cast_web_preferences.h b/chromecast/browser/cast_web_preferences.h
index e7d12c8..31e5c6e 100644
--- a/chromecast/browser/cast_web_preferences.h
+++ b/chromecast/browser/cast_web_preferences.h
@@ -5,8 +5,8 @@
 #ifndef CHROMECAST_BROWSER_CAST_WEB_PREFERENCES_H_
 #define CHROMECAST_BROWSER_CAST_WEB_PREFERENCES_H_
 
+#include <optional>
 #include "base/supports_user_data.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/mojom/webpreferences/web_preferences.mojom.h"
 
 namespace chromecast {
@@ -18,10 +18,10 @@
   struct Preferences {
     Preferences();
 
-    absl::optional<blink::mojom::AutoplayPolicy> autoplay_policy;
-    absl::optional<bool> hide_scrollbars;
-    absl::optional<bool> javascript_enabled;
-    absl::optional<bool> supports_multiple_windows;
+    std::optional<blink::mojom::AutoplayPolicy> autoplay_policy;
+    std::optional<bool> hide_scrollbars;
+    std::optional<bool> javascript_enabled;
+    std::optional<bool> supports_multiple_windows;
   };
 
   // Unique key used to identify CastWebPreferences in WebContents' user data.
diff --git a/chromecast/browser/devtools/remote_debugging_server.cc b/chromecast/browser/devtools/remote_debugging_server.cc
index 4cb67d3..b5b2e1f 100644
--- a/chromecast/browser/devtools/remote_debugging_server.cc
+++ b/chromecast/browser/devtools/remote_debugging_server.cc
@@ -90,7 +90,7 @@
     std::unique_ptr<net::ServerSocket> socket(
         new net::TCPServerSocket(nullptr, net::NetLogSource()));
 
-    if (socket->Listen(endpoint_, kBackLog, /*ipv6_only=*/absl::nullopt) !=
+    if (socket->Listen(endpoint_, kBackLog, /*ipv6_only=*/std::nullopt) !=
         net::OK) {
       return nullptr;
     }
diff --git a/chromecast/browser/service_manager_context.cc b/chromecast/browser/service_manager_context.cc
index f7d6fd78..d3435c1 100644
--- a/chromecast/browser/service_manager_context.cc
+++ b/chromecast/browser/service_manager_context.cc
@@ -9,6 +9,7 @@
 #include <string>
 #include <utility>
 
+#include <optional>
 #include "base/command_line.h"
 #include "base/feature_list.h"
 #include "base/functional/bind.h"
@@ -43,7 +44,6 @@
 #include "services/service_manager/service_manager.h"
 #include "services/service_manager/service_process_host.h"
 #include "services/service_manager/service_process_launcher.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/buildflags.h"
 #include "ui/base/ui_base_features.h"
 
@@ -316,7 +316,7 @@
   manifests.push_back(GetBrowserManifest());
   manifests.push_back(GetSystemManifest(cast_content_browser_client_));
   for (auto& manifest : manifests) {
-    absl::optional<service_manager::Manifest> overlay =
+    std::optional<service_manager::Manifest> overlay =
         cast_content_browser_client_->GetServiceManifestOverlay(
             manifest.service_name);
     if (overlay)
diff --git a/chromecast/browser/webui/cast_resource_data_source.h b/chromecast/browser/webui/cast_resource_data_source.h
index 7c74e09..edc1205 100644
--- a/chromecast/browser/webui/cast_resource_data_source.h
+++ b/chromecast/browser/webui/cast_resource_data_source.h
@@ -7,11 +7,11 @@
 
 #include <string>
 
+#include <optional>
 #include "chromecast/browser/webui/mojom/webui.mojom.h"
 #include "content/public/browser/url_data_source.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace chromecast {
 
@@ -47,7 +47,7 @@
   const bool for_webui_;
   mojo::Remote<mojom::Resources> remote_;
 
-  absl::optional<std::string> frame_src_;
+  std::optional<std::string> frame_src_;
   bool deny_xframe_options_ = true;
 };
 
diff --git a/chromecast/cast_core/grpc/grpc_server_reactor.h b/chromecast/cast_core/grpc/grpc_server_reactor.h
index 8578e1e..2c666da 100644
--- a/chromecast/cast_core/grpc/grpc_server_reactor.h
+++ b/chromecast/cast_core/grpc/grpc_server_reactor.h
@@ -8,11 +8,11 @@
 #include <grpcpp/generic/async_generic_service.h>
 #include <grpcpp/grpcpp.h>
 
+#include <optional>
 #include "base/check_op.h"
 #include "base/logging.h"
 #include "base/memory/raw_ptr.h"
 #include "chromecast/cast_core/grpc/grpc_status_or.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace cast {
 namespace utils {
@@ -132,8 +132,8 @@
   const std::string name_;
   raw_ptr<grpc::CallbackServerContext> context_;
 
-  absl::optional<grpc::ByteBuffer> request_byte_buffer_;
-  absl::optional<grpc::ByteBuffer> response_byte_buffer_;
+  std::optional<grpc::ByteBuffer> request_byte_buffer_;
+  std::optional<grpc::ByteBuffer> response_byte_buffer_;
 };
 
 }  // namespace utils
diff --git a/chromecast/cast_core/grpc/grpc_status_or.h b/chromecast/cast_core/grpc/grpc_status_or.h
index 0b67351..fec7cca 100644
--- a/chromecast/cast_core/grpc/grpc_status_or.h
+++ b/chromecast/cast_core/grpc/grpc_status_or.h
@@ -10,8 +10,8 @@
 #include <string>
 #include <type_traits>
 
+#include <optional>
 #include "base/check.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace cast {
 namespace utils {
@@ -118,7 +118,7 @@
 
  private:
   grpc::Status status_;
-  absl::optional<T> data_;
+  std::optional<T> data_;
 };
 
 }  // namespace utils
diff --git a/chromecast/cast_core/runtime/browser/cast_runtime_metrics_recorder.cc b/chromecast/cast_core/runtime/browser/cast_runtime_metrics_recorder.cc
index 5c72fde4..67c1898 100644
--- a/chromecast/cast_core/runtime/browser/cast_runtime_metrics_recorder.cc
+++ b/chromecast/cast_core/runtime/browser/cast_runtime_metrics_recorder.cc
@@ -7,6 +7,7 @@
 #include <cfloat>
 #include <cmath>
 
+#include <optional>
 #include "base/json/json_string_value_serializer.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_base.h"
@@ -18,7 +19,6 @@
 #include "base/values.h"
 #include "chromecast/base/metrics/cast_histograms.h"
 #include "chromecast/base/metrics/cast_metrics_helper.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/metrics_proto/cast_logs.pb.h"
 
 namespace chromecast {
@@ -252,7 +252,7 @@
   }
 
   // Gets event creation time. If unavailable use now.
-  absl::optional<double> maybe_event_time = value_dict.FindDouble(kEventTime);
+  std::optional<double> maybe_event_time = value_dict.FindDouble(kEventTime);
   double event_time = 0;
   if (maybe_event_time && maybe_event_time.value() > 0) {
     event_time = maybe_event_time.value();
@@ -285,7 +285,7 @@
     std::unique_ptr<CastEventBuilder> event_builder(CreateEventBuilder(*name));
     PopulateEventBuilder(event_builder.get(), event_time, app_id, sdk_version,
                          session_id);
-    absl::optional<double> maybe_event_value =
+    std::optional<double> maybe_event_value =
         value_dict.FindDouble(kEventValue);
     if (maybe_event_value) {
       double event_value = maybe_event_value.value();
@@ -304,7 +304,7 @@
   }
 
   for (auto kv : *multiple_events) {
-    absl::optional<double> maybe_event_value = kv.second.GetIfDouble();
+    std::optional<double> maybe_event_value = kv.second.GetIfDouble();
     if (!maybe_event_value) {
       continue;
     }
diff --git a/chromecast/cast_core/runtime/browser/core_conversions.cc b/chromecast/cast_core/runtime/browser/core_conversions.cc
index 50dfa5e..ab58ce5 100644
--- a/chromecast/cast_core/runtime/browser/core_conversions.cc
+++ b/chromecast/cast_core/runtime/browser/core_conversions.cc
@@ -76,7 +76,7 @@
   if (core_config.has_cast_web_app_config()) {
     config.url = GURL(core_config.cast_web_app_config().url());
     if (!config.url->is_valid()) {
-      config.url = absl::nullopt;
+      config.url = std::nullopt;
     }
   }
 
diff --git a/chromecast/cast_core/runtime/browser/core_streaming_config_manager.cc b/chromecast/cast_core/runtime/browser/core_streaming_config_manager.cc
index 815b1e6..c2e7e38 100644
--- a/chromecast/cast_core/runtime/browser/core_streaming_config_manager.cc
+++ b/chromecast/cast_core/runtime/browser/core_streaming_config_manager.cc
@@ -62,9 +62,9 @@
     const PlatformInfoSerializer& deserializer) {
   cast_streaming::ReceiverConfig constraints;
 
-  const absl::optional<int> width = deserializer.MaxWidth();
-  const absl::optional<int> height = deserializer.MaxHeight();
-  const absl::optional<int> frame_rate = deserializer.MaxFrameRate();
+  const std::optional<int> width = deserializer.MaxWidth();
+  const std::optional<int> height = deserializer.MaxHeight();
+  const std::optional<int> frame_rate = deserializer.MaxFrameRate();
   if (width && *width && height && *height && frame_rate && *frame_rate) {
     cast_streaming::ReceiverConfig::Display display;
     display.dimensions = gfx::Rect{*width, *height};
@@ -209,7 +209,7 @@
 
   DCHECK(ports.empty());
 
-  absl::optional<PlatformInfoSerializer> deserializer =
+  std::optional<PlatformInfoSerializer> deserializer =
       PlatformInfoSerializer::Deserialize(message);
   if (!deserializer) {
     LOG(ERROR) << "AV Settings with invalid protobuf received: " << message;
diff --git a/chromecast/cast_core/runtime/browser/core_streaming_config_manager_unittest.cc b/chromecast/cast_core/runtime/browser/core_streaming_config_manager_unittest.cc
index 03610bbe..6a6bc805d 100644
--- a/chromecast/cast_core/runtime/browser/core_streaming_config_manager_unittest.cc
+++ b/chromecast/cast_core/runtime/browser/core_streaming_config_manager_unittest.cc
@@ -82,7 +82,7 @@
   auto config = streaming_config_manager_.config();
   ASSERT_EQ(config.audio_limits.size(), size_t{1});
   auto& limit = config.audio_limits.back();
-  EXPECT_EQ(limit.codec, absl::nullopt);
+  EXPECT_EQ(limit.codec, std::nullopt);
   EXPECT_EQ(limit.channel_layout, ::media::CHANNEL_LAYOUT_STEREO);
 }
 
diff --git a/chromecast/cast_core/runtime/browser/grpc_resource_data_source.h b/chromecast/cast_core/runtime/browser/grpc_resource_data_source.h
index b3dd32b..5542b44 100644
--- a/chromecast/cast_core/runtime/browser/grpc_resource_data_source.h
+++ b/chromecast/cast_core/runtime/browser/grpc_resource_data_source.h
@@ -5,9 +5,9 @@
 #ifndef CHROMECAST_CAST_CORE_RUNTIME_BROWSER_GRPC_RESOURCE_DATA_SOURCE_H_
 #define CHROMECAST_CAST_CORE_RUNTIME_BROWSER_GRPC_RESOURCE_DATA_SOURCE_H_
 
+#include <optional>
 #include "base/task/sequenced_task_runner.h"
 #include "content/public/browser/url_data_source.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/cast_core/public/src/proto/v2/core_application_service.castcore.pb.h"
 
 namespace chromecast {
@@ -67,7 +67,7 @@
   const bool for_webui_;
   cast::v2::CoreApplicationServiceStub* const core_app_service_stub_;
 
-  absl::optional<std::string> frame_src_;
+  std::optional<std::string> frame_src_;
   bool deny_xframe_options_ = true;
 
   base::WeakPtrFactory<GrpcResourceDataSource> weak_factory_{this};
diff --git a/chromecast/cast_core/runtime/browser/runtime_application_service_impl.h b/chromecast/cast_core/runtime/browser/runtime_application_service_impl.h
index fd1d2ba..7878e09 100644
--- a/chromecast/cast_core/runtime/browser/runtime_application_service_impl.h
+++ b/chromecast/cast_core/runtime/browser/runtime_application_service_impl.h
@@ -163,11 +163,11 @@
   // use.
   std::unique_ptr<MessagePortServiceGrpc> message_port_service_;
 
-  absl::optional<cast::utils::GrpcServer> grpc_server_;
-  absl::optional<cast::v2::CoreApplicationServiceStub> core_app_stub_;
-  absl::optional<cast::v2::CoreMessagePortApplicationServiceStub>
+  std::optional<cast::utils::GrpcServer> grpc_server_;
+  std::optional<cast::v2::CoreApplicationServiceStub> core_app_stub_;
+  std::optional<cast::v2::CoreMessagePortApplicationServiceStub>
       core_message_port_app_stub_;
-  absl::optional<std::string> cast_media_service_grpc_endpoint_;
+  std::optional<std::string> cast_media_service_grpc_endpoint_;
 
   SEQUENCE_CHECKER(sequence_checker_);
 
diff --git a/chromecast/cast_core/runtime/browser/runtime_service_impl.h b/chromecast/cast_core/runtime/browser/runtime_service_impl.h
index 1a0b918..7440104a 100644
--- a/chromecast/cast_core/runtime/browser/runtime_service_impl.h
+++ b/chromecast/cast_core/runtime/browser/runtime_service_impl.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 
+#include <optional>
 #include "base/memory/weak_ptr.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/time/time.h"
@@ -18,7 +19,6 @@
 #include "chromecast/cast_core/runtime/browser/runtime_application_service_impl.h"
 #include "components/cast_receiver/browser/public/runtime_application_dispatcher.h"
 #include "components/cast_receiver/common/public/status.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/cast_core/public/src/proto/metrics/metrics_recorder.castcore.pb.h"
 #include "third_party/cast_core/public/src/proto/runtime/runtime_service.castcore.pb.h"
 
@@ -118,12 +118,12 @@
   // Allows metrics, histogram, action recording, which can be reported by
   // CastRuntimeMetricsRecorderService if Cast Core starts it.
   CastRuntimeMetricsRecorder metrics_recorder_;
-  absl::optional<CastRuntimeActionRecorder> action_recorder_;
+  std::optional<CastRuntimeActionRecorder> action_recorder_;
 
-  absl::optional<cast::utils::GrpcServer> grpc_server_;
-  absl::optional<cast::metrics::MetricsRecorderServiceStub>
+  std::optional<cast::utils::GrpcServer> grpc_server_;
+  std::optional<cast::metrics::MetricsRecorderServiceStub>
       metrics_recorder_stub_;
-  absl::optional<CastRuntimeMetricsRecorderService> metrics_recorder_service_;
+  std::optional<CastRuntimeMetricsRecorderService> metrics_recorder_service_;
 
   // Heartbeat period as set by Cast Core.
   base::TimeDelta heartbeat_period_;
diff --git a/chromecast/cast_core/runtime/browser/url_rewrite/url_request_rewrite_type_converters.cc b/chromecast/cast_core/runtime/browser/url_rewrite/url_request_rewrite_type_converters.cc
index 7d70a43..2b5a824 100644
--- a/chromecast/cast_core/runtime/browser/url_rewrite/url_request_rewrite_type_converters.cc
+++ b/chromecast/cast_core/runtime/browser/url_rewrite/url_request_rewrite_type_converters.cc
@@ -42,7 +42,7 @@
     url_rewrite::mojom::UrlRequestRewriteRemoveHeaderPtr remove_header =
         url_rewrite::mojom::UrlRequestRewriteRemoveHeader::New();
     if (!input.query_pattern().empty())
-      remove_header->query_pattern = absl::make_optional(input.query_pattern());
+      remove_header->query_pattern = std::make_optional(input.query_pattern());
     if (!input.header_name().empty())
       remove_header->header_name = input.header_name();
     return remove_header;
diff --git a/chromecast/cast_core/runtime/browser/url_rewrite/url_request_rewrite_type_converters_unittest.cc b/chromecast/cast_core/runtime/browser/url_rewrite/url_request_rewrite_type_converters_unittest.cc
index f381363..4000965 100644
--- a/chromecast/cast_core/runtime/browser/url_rewrite/url_request_rewrite_type_converters_unittest.cc
+++ b/chromecast/cast_core/runtime/browser/url_rewrite/url_request_rewrite_type_converters_unittest.cc
@@ -4,12 +4,12 @@
 
 #include "chromecast/cast_core/runtime/browser/url_rewrite/url_request_rewrite_type_converters.h"
 
+#include <optional>
 #include "base/run_loop.h"
 #include "base/strings/string_piece.h"
 #include "components/url_rewrite/browser/url_request_rewrite_rules_validation.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/cast_core/public/src/proto/v2/url_rewrite.pb.h"
 
 namespace chromecast {
@@ -28,7 +28,7 @@
 }
 
 cast::v2::UrlRequestRewrite CreateRewriteRemoveHeader(
-    absl::optional<std::string> query_pattern,
+    std::optional<std::string> query_pattern,
     std::string header_name) {
   cast::v2::UrlRequestRewrite rewrite;
   auto* remove_header = rewrite.mutable_remove_header();
@@ -107,7 +107,7 @@
 // Tests RemoveHeader rewrites are properly converted to their Mojo equivalent.
 TEST_F(UrlRequestRewriteTypeConvertersTest, ConvertRemoveHeader) {
   EXPECT_TRUE(UpdateRulesFromRewrite(
-      CreateRewriteRemoveHeader(absl::make_optional("Test"), "Header")));
+      CreateRewriteRemoveHeader(std::make_optional("Test"), "Header")));
   ASSERT_THAT(cached_rules_->rules, SizeIs(1));
   ASSERT_FALSE(cached_rules_->rules[0]->hosts_filter);
   ASSERT_FALSE(cached_rules_->rules[0]->schemes_filter);
@@ -122,7 +122,7 @@
 
   // Create a RemoveHeader rewrite with no pattern.
   EXPECT_TRUE(UpdateRulesFromRewrite(
-      CreateRewriteRemoveHeader(absl::nullopt, "Header")));
+      CreateRewriteRemoveHeader(std::nullopt, "Header")));
   ASSERT_THAT(cached_rules_->rules, SizeIs(1));
   ASSERT_FALSE(cached_rules_->rules[0]->hosts_filter);
   ASSERT_FALSE(cached_rules_->rules[0]->schemes_filter);
diff --git a/chromecast/common/cast_content_client.cc b/chromecast/common/cast_content_client.cc
index 7fa579b..951155e 100644
--- a/chromecast/common/cast_content_client.cc
+++ b/chromecast/common/cast_content_client.cc
@@ -31,9 +31,9 @@
 #include "url/url_util.h"
 
 #if BUILDFLAG(IS_ANDROID)
+#include <optional>
 #include "chromecast/common/media/cast_media_drm_bridge_client.h"
 #include "components/cdm/common/android_cdm_registration.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #endif
 
 #if !BUILDFLAG(IS_FUCHSIA)
@@ -226,11 +226,11 @@
     cdms->push_back(
         content::CdmInfo(kChromecastPlayreadyKeySystem,
                          content::CdmInfo::Robustness::kSoftwareSecure,
-                         absl::nullopt, kPlayReadyCdmType));
+                         std::nullopt, kPlayReadyCdmType));
     cdms->push_back(
         content::CdmInfo(kChromecastPlayreadyKeySystem,
                          content::CdmInfo::Robustness::kHardwareSecure,
-                         absl::nullopt, kPlayReadyCdmType));
+                         std::nullopt, kPlayReadyCdmType));
 #endif  // BUILDFLAG(ENABLE_PLAYREADY)
 #endif  // BUILDFLAG(BUNDLE_WIDEVINE_CDM) && BUILDFLAG(IS_LINUX)
   }
diff --git a/chromecast/common/cast_resource_delegate.cc b/chromecast/common/cast_resource_delegate.cc
index e065a14..65a2cf0 100644
--- a/chromecast/common/cast_resource_delegate.cc
+++ b/chromecast/common/cast_resource_delegate.cc
@@ -68,9 +68,9 @@
   return NULL;
 }
 
-absl::optional<std::string> CastResourceDelegate::LoadDataResourceString(
+std::optional<std::string> CastResourceDelegate::LoadDataResourceString(
     int resource_id) {
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool CastResourceDelegate::GetRawDataResource(
diff --git a/chromecast/common/cast_resource_delegate.h b/chromecast/common/cast_resource_delegate.h
index 78e35b4..912a365 100644
--- a/chromecast/common/cast_resource_delegate.h
+++ b/chromecast/common/cast_resource_delegate.h
@@ -48,7 +48,7 @@
   base::RefCountedStaticMemory* LoadDataResourceBytes(
       int resource_id,
       ui::ResourceScaleFactor scale_factor) override;
-  absl::optional<std::string> LoadDataResourceString(int resource_id) override;
+  std::optional<std::string> LoadDataResourceString(int resource_id) override;
   bool GetRawDataResource(int resource_id,
                           ui::ResourceScaleFactor scale_factor,
                           base::StringPiece* value) const override;
diff --git a/chromecast/crash/linux/crash_testing_utils.cc b/chromecast/crash/linux/crash_testing_utils.cc
index 5f8f014..01a95ad0 100644
--- a/chromecast/crash/linux/crash_testing_utils.cc
+++ b/chromecast/crash/linux/crash_testing_utils.cc
@@ -31,10 +31,10 @@
 const char kRatelimitPeriodStartKey[] = "period_start";
 const char kRatelimitPeriodDumpsKey[] = "period_dumps";
 
-absl::optional<base::Value::List> ParseLockFile(const std::string& path) {
+std::optional<base::Value::List> ParseLockFile(const std::string& path) {
   std::string lockfile_string;
   RCHECK(base::ReadFileToString(base::FilePath(path), &lockfile_string),
-         absl::nullopt, "Failed to read file");
+         std::nullopt, "Failed to read file");
 
   std::vector<std::string> lines = base::SplitString(
       lockfile_string, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
@@ -45,10 +45,10 @@
   for (const std::string& line : lines) {
     if (line.size() == 0)
       continue;
-    absl::optional<base::Value> dump_info = base::JSONReader::Read(line);
-    RCHECK(dump_info.has_value(), absl::nullopt, "Invalid DumpInfo");
+    std::optional<base::Value> dump_info = base::JSONReader::Read(line);
+    RCHECK(dump_info.has_value(), std::nullopt, "Invalid DumpInfo");
     DumpInfo info(&dump_info.value());
-    RCHECK(info.valid(), absl::nullopt, "Invalid DumpInfo");
+    RCHECK(info.valid(), std::nullopt, "Invalid DumpInfo");
     dumps.Append(std::move(dump_info.value()));
   }
 
@@ -92,7 +92,7 @@
 }  // namespace
 
 std::unique_ptr<DumpInfo> CreateDumpInfo(const std::string& json_string) {
-  absl::optional<base::Value> value = base::JSONReader::Read(json_string);
+  std::optional<base::Value> value = base::JSONReader::Read(json_string);
   return value.has_value() ? std::make_unique<DumpInfo>(&value.value())
                            : std::make_unique<DumpInfo>(nullptr);
 }
@@ -100,7 +100,7 @@
 bool FetchDumps(const std::string& lockfile_path,
                 std::vector<std::unique_ptr<DumpInfo>>* dumps) {
   DCHECK(dumps);
-  absl::optional<base::Value::List> dump_list = ParseLockFile(lockfile_path);
+  std::optional<base::Value::List> dump_list = ParseLockFile(lockfile_path);
   RCHECK(dump_list, false, "Failed to parse lockfile");
 
   dumps->clear();
@@ -137,7 +137,7 @@
 bool AppendLockFile(const std::string& lockfile_path,
                     const std::string& metadata_path,
                     const DumpInfo& dump) {
-  absl::optional<base::Value::List> contents = ParseLockFile(lockfile_path);
+  std::optional<base::Value::List> contents = ParseLockFile(lockfile_path);
   if (!contents) {
     CreateFiles(lockfile_path, metadata_path);
     if (!(contents = ParseLockFile(lockfile_path))) {
diff --git a/chromecast/crash/linux/synchronized_minidump_manager.cc b/chromecast/crash/linux/synchronized_minidump_manager.cc
index 5698e03..9ceaefc0 100644
--- a/chromecast/crash/linux/synchronized_minidump_manager.cc
+++ b/chromecast/crash/linux/synchronized_minidump_manager.cc
@@ -15,6 +15,7 @@
 #include <string>
 #include <utility>
 
+#include <optional>
 #include "base/command_line.h"
 #include "base/files/dir_reader_posix.h"
 #include "base/files/file_util.h"
@@ -27,7 +28,6 @@
 #include "base/strings/string_split.h"
 #include "chromecast/base/path_utils.h"
 #include "chromecast/crash/linux/dump_info.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // if |cond| is false, returns |retval|.
 #define RCHECK(cond, retval) \
@@ -66,7 +66,7 @@
 // Gets the ratelimit parameter dictionary given a deserialized |metadata|.
 // Returns nullptr if invalid.
 base::Value::Dict* GetRatelimitParams(
-    absl::optional<base::Value::Dict>& metadata) {
+    std::optional<base::Value::Dict>& metadata) {
   if (!metadata)
     return nullptr;
   return metadata->FindDict(kLockfileRatelimitKey);
@@ -74,12 +74,11 @@
 
 // Returns the time of the current ratelimit period's start in |metadata|.
 // Returns base::Time() if an error occurs.
-base::Time GetRatelimitPeriodStart(
-    absl::optional<base::Value::Dict>& metadata) {
+base::Time GetRatelimitPeriodStart(std::optional<base::Value::Dict>& metadata) {
   base::Value::Dict* ratelimit_params = GetRatelimitParams(metadata);
   RCHECK(ratelimit_params, base::Time());
 
-  absl::optional<double> seconds =
+  std::optional<double> seconds =
       ratelimit_params->FindDouble(kLockfileRatelimitPeriodStartKey);
   RCHECK(seconds, base::Time());
 
@@ -91,7 +90,7 @@
 
 // Sets the time of the current ratelimit period's start in |metadata| to
 // |period_start|. Returns true on success, false on error.
-bool SetRatelimitPeriodStart(absl::optional<base::Value::Dict>& metadata,
+bool SetRatelimitPeriodStart(std::optional<base::Value::Dict>& metadata,
                              base::Time period_start) {
   DCHECK(!period_start.is_null());
 
@@ -105,18 +104,18 @@
 
 // Gets the number of dumps added to |metadata| in the current ratelimit
 // period. Returns < 0 on error.
-int GetRatelimitPeriodDumps(absl::optional<base::Value::Dict>& metadata) {
+int GetRatelimitPeriodDumps(std::optional<base::Value::Dict>& metadata) {
   base::Value::Dict* ratelimit_params = GetRatelimitParams(metadata);
   if (!ratelimit_params)
     return -1;
-  absl::optional<int> period_dumps =
+  std::optional<int> period_dumps =
       ratelimit_params->FindInt(kLockfileRatelimitPeriodDumpsKey);
   return period_dumps.value_or(-1);
 }
 
 // Sets the current ratelimit period's number of dumps in |metadata| to
 // |period_dumps|. Returns true on success, false on error.
-bool SetRatelimitPeriodDumps(absl::optional<base::Value::Dict>& metadata,
+bool SetRatelimitPeriodDumps(std::optional<base::Value::Dict>& metadata,
                              int period_dumps) {
   DCHECK_GE(period_dumps, 0);
 
@@ -129,7 +128,7 @@
 }
 
 // Returns true if |metadata| contains valid metadata, false otherwise.
-bool ValidateMetadata(absl::optional<base::Value::Dict>& metadata) {
+bool ValidateMetadata(std::optional<base::Value::Dict>& metadata) {
   RCHECK(metadata, false);
 
   // Validate ratelimit params
@@ -296,7 +295,7 @@
   for (const std::string& line : lines) {
     if (line.size() == 0)
       continue;
-    absl::optional<base::Value> dump_info = base::JSONReader::Read(line);
+    std::optional<base::Value> dump_info = base::JSONReader::Read(line);
     RCHECK(dump_info.has_value(), false);
     DumpInfo info(&dump_info.value());
     RCHECK(info.valid(), false);
@@ -312,7 +311,7 @@
       << "JSON error " << error_code << ":" << error_msg;
   RCHECK(metadata_ptr, false);
   RCHECK(metadata_ptr->is_dict(), false);
-  absl::optional<base::Value::Dict> metadata =
+  std::optional<base::Value::Dict> metadata =
       std::move(*metadata_ptr).TakeDict();
   RCHECK(ValidateMetadata(metadata), false);
 
diff --git a/chromecast/crash/linux/synchronized_minidump_manager.h b/chromecast/crash/linux/synchronized_minidump_manager.h
index ab0db4d..18d414a 100644
--- a/chromecast/crash/linux/synchronized_minidump_manager.h
+++ b/chromecast/crash/linux/synchronized_minidump_manager.h
@@ -7,10 +7,10 @@
 
 #include <vector>
 
+#include <optional>
 #include "base/files/file_path.h"
 #include "base/values.h"
 #include "chromecast/crash/linux/dump_info.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace chromecast {
 
@@ -146,8 +146,8 @@
   const base::FilePath lockfile_path_;
   const base::FilePath metadata_path_;
   int lockfile_fd_;
-  absl::optional<base::Value::Dict> metadata_;
-  absl::optional<base::Value::List> dumps_;
+  std::optional<base::Value::Dict> metadata_;
+  std::optional<base::Value::List> dumps_;
 };
 
 }  // namespace chromecast
diff --git a/chromecast/device/bluetooth/le/le_scan_manager.h b/chromecast/device/bluetooth/le/le_scan_manager.h
index 97d7a92c..5d627ba8 100644
--- a/chromecast/device/bluetooth/le/le_scan_manager.h
+++ b/chromecast/device/bluetooth/le/le_scan_manager.h
@@ -9,11 +9,11 @@
 #include <memory>
 #include <vector>
 
+#include <optional>
 #include "base/functional/callback.h"
 #include "base/memory/scoped_refptr.h"
 #include "chromecast/device/bluetooth/le/le_scan_result.h"
 #include "chromecast/device/bluetooth/le/scan_filter.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class SingleThreadTaskRunner;
@@ -82,7 +82,7 @@
       base::OnceCallback<void(std::vector<LeScanResult>)>;
   virtual void GetScanResults(
       GetScanResultsCallback cb,
-      absl::optional<ScanFilter> scan_filter = absl::nullopt) = 0;
+      std::optional<ScanFilter> scan_filter = std::nullopt) = 0;
 
   virtual void ClearScanResults() = 0;
 
diff --git a/chromecast/device/bluetooth/le/le_scan_manager_impl.cc b/chromecast/device/bluetooth/le/le_scan_manager_impl.cc
index d1b64ff..9d170a95 100644
--- a/chromecast/device/bluetooth/le/le_scan_manager_impl.cc
+++ b/chromecast/device/bluetooth/le/le_scan_manager_impl.cc
@@ -118,7 +118,7 @@
 }
 
 void LeScanManagerImpl::GetScanResults(GetScanResultsCallback cb,
-                                       absl::optional<ScanFilter> scan_filter) {
+                                       std::optional<ScanFilter> scan_filter) {
   MAKE_SURE_IO_THREAD(GetScanResults, BindToCurrentSequence(std::move(cb)),
                       std::move(scan_filter));
   std::move(cb).Run(GetScanResultsInternal(std::move(scan_filter)));
@@ -225,7 +225,7 @@
 
 // Returns a list of all scan results. The results are sorted by RSSI.
 std::vector<LeScanResult> LeScanManagerImpl::GetScanResultsInternal(
-    absl::optional<ScanFilter> scan_filter) {
+    std::optional<ScanFilter> scan_filter) {
   DCHECK(io_task_runner_->BelongsToCurrentThread());
   std::vector<LeScanResult> results;
   for (const auto& pair : addr_to_scan_results_) {
diff --git a/chromecast/device/bluetooth/le/le_scan_manager_impl.h b/chromecast/device/bluetooth/le/le_scan_manager_impl.h
index f4b5096e..4df4b822 100644
--- a/chromecast/device/bluetooth/le/le_scan_manager_impl.h
+++ b/chromecast/device/bluetooth/le/le_scan_manager_impl.h
@@ -42,7 +42,7 @@
   void RequestScan(RequestScanCallback cb) override;
   void GetScanResults(
       GetScanResultsCallback cb,
-      absl::optional<ScanFilter> service_uuid = absl::nullopt) override;
+      std::optional<ScanFilter> service_uuid = std::nullopt) override;
   void ClearScanResults() override;
   void PauseScan() override;
   void ResumeScan() override;
@@ -60,7 +60,7 @@
   // Returns a list of all BLE scan results. The results are sorted by RSSI.
   // Must be called on |io_task_runner|.
   std::vector<LeScanResult> GetScanResultsInternal(
-      absl::optional<ScanFilter> service_uuid);
+      std::optional<ScanFilter> service_uuid);
 
   void NotifyScanHandleDestroyed(int32_t id);
 
diff --git a/chromecast/device/bluetooth/le/le_scan_result.cc b/chromecast/device/bluetooth/le/le_scan_result.cc
index 539d903..511162f 100644
--- a/chromecast/device/bluetooth/le/le_scan_result.cc
+++ b/chromecast/device/bluetooth/le/le_scan_result.cc
@@ -15,19 +15,19 @@
 namespace {
 
 template <typename T, bluetooth_v2_shlib::Uuid (*converter)(T)>
-absl::optional<LeScanResult::UuidList> GetUuidsFromShort(
+std::optional<LeScanResult::UuidList> GetUuidsFromShort(
     const std::map<uint8_t, std::vector<std::vector<uint8_t>>>& type_to_data,
     uint8_t type) {
   auto it = type_to_data.find(type);
   if (it == type_to_data.end()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   LeScanResult::UuidList ret;
   for (const auto& field : it->second) {
     if (field.size() % sizeof(T)) {
       LOG(ERROR) << "Invalid length, expected multiple of " << sizeof(T);
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     for (size_t i = 0; i < field.size(); i += sizeof(T)) {
@@ -45,12 +45,12 @@
   return ret;
 }
 
-absl::optional<LeScanResult::UuidList> GetUuidsAsUuid(
+std::optional<LeScanResult::UuidList> GetUuidsAsUuid(
     const std::map<uint8_t, std::vector<std::vector<uint8_t>>>& type_to_data,
     uint8_t type) {
   auto it = type_to_data.find(type);
   if (it == type_to_data.end()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   LeScanResult::UuidList ret;
@@ -58,7 +58,7 @@
     if (field.size() % sizeof(bluetooth_v2_shlib::Uuid)) {
       LOG(ERROR) << "Invalid length, expected multiple of "
                  << sizeof(bluetooth_v2_shlib::Uuid);
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     for (size_t i = 0; i < field.size();
@@ -117,7 +117,7 @@
   return true;
 }
 
-absl::optional<std::string> LeScanResult::Name() const {
+std::optional<std::string> LeScanResult::Name() const {
   auto it = type_to_data.find(kGapCompleteName);
   if (it != type_to_data.end()) {
     DCHECK_GE(it->second.size(), 1u);
@@ -132,28 +132,28 @@
                        it->second[0].size());
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<uint8_t> LeScanResult::Flags() const {
+std::optional<uint8_t> LeScanResult::Flags() const {
   auto it = type_to_data.find(kGapFlags);
   if (it == type_to_data.end()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   DCHECK_GE(it->second.size(), 1u);
   if (it->second[0].size() != 1) {
     LOG(ERROR) << "Invalid length for flags";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return it->second[0][0];
 }
 
-absl::optional<LeScanResult::UuidList> LeScanResult::AllServiceUuids() const {
+std::optional<LeScanResult::UuidList> LeScanResult::AllServiceUuids() const {
   bool any_exist = false;
   UuidList ret;
-  auto insert_if_exists = [&ret, &any_exist](absl::optional<UuidList> list) {
+  auto insert_if_exists = [&ret, &any_exist](std::optional<UuidList> list) {
     if (list) {
       any_exist = true;
       ret.insert(ret.end(), list->begin(), list->end());
@@ -168,42 +168,42 @@
   insert_if_exists(CompleteListOf128BitServiceUuids());
 
   if (!any_exist) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return ret;
 }
 
-absl::optional<LeScanResult::UuidList>
+std::optional<LeScanResult::UuidList>
 LeScanResult::IncompleteListOf16BitServiceUuids() const {
   return GetUuidsFromShort<uint16_t, util::UuidFromInt16>(
       type_to_data, kGapIncomplete16BitServiceUuids);
 }
 
-absl::optional<LeScanResult::UuidList>
+std::optional<LeScanResult::UuidList>
 LeScanResult::CompleteListOf16BitServiceUuids() const {
   return GetUuidsFromShort<uint16_t, util::UuidFromInt16>(
       type_to_data, kGapComplete16BitServiceUuids);
 }
 
-absl::optional<LeScanResult::UuidList>
+std::optional<LeScanResult::UuidList>
 LeScanResult::IncompleteListOf32BitServiceUuids() const {
   return GetUuidsFromShort<uint32_t, util::UuidFromInt32>(
       type_to_data, kGapIncomplete32BitServiceUuids);
 }
 
-absl::optional<LeScanResult::UuidList>
+std::optional<LeScanResult::UuidList>
 LeScanResult::CompleteListOf32BitServiceUuids() const {
   return GetUuidsFromShort<uint32_t, util::UuidFromInt32>(
       type_to_data, kGapComplete32BitServiceUuids);
 }
 
-absl::optional<LeScanResult::UuidList>
+std::optional<LeScanResult::UuidList>
 LeScanResult::IncompleteListOf128BitServiceUuids() const {
   return GetUuidsAsUuid(type_to_data, kGapIncomplete128BitServiceUuids);
 }
 
-absl::optional<LeScanResult::UuidList>
+std::optional<LeScanResult::UuidList>
 LeScanResult::CompleteListOf128BitServiceUuids() const {
   return GetUuidsAsUuid(type_to_data, kGapComplete128BitServiceUuids);
 }
diff --git a/chromecast/device/bluetooth/le/le_scan_result.h b/chromecast/device/bluetooth/le/le_scan_result.h
index fc72f835..476be5d 100644
--- a/chromecast/device/bluetooth/le/le_scan_result.h
+++ b/chromecast/device/bluetooth/le/le_scan_result.h
@@ -9,9 +9,9 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/containers/span.h"
 #include "chromecast/public/bluetooth/bluetooth_types.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace chromecast {
 namespace bluetooth {
@@ -43,18 +43,18 @@
 
   bool SetAdvData(base::span<const uint8_t> adv_data);
 
-  absl::optional<std::string> Name() const;
+  std::optional<std::string> Name() const;
 
-  absl::optional<uint8_t> Flags() const;
+  std::optional<uint8_t> Flags() const;
 
   using UuidList = std::vector<bluetooth_v2_shlib::Uuid>;
-  absl::optional<UuidList> AllServiceUuids() const;
-  absl::optional<UuidList> IncompleteListOf16BitServiceUuids() const;
-  absl::optional<UuidList> CompleteListOf16BitServiceUuids() const;
-  absl::optional<UuidList> IncompleteListOf32BitServiceUuids() const;
-  absl::optional<UuidList> CompleteListOf32BitServiceUuids() const;
-  absl::optional<UuidList> IncompleteListOf128BitServiceUuids() const;
-  absl::optional<UuidList> CompleteListOf128BitServiceUuids() const;
+  std::optional<UuidList> AllServiceUuids() const;
+  std::optional<UuidList> IncompleteListOf16BitServiceUuids() const;
+  std::optional<UuidList> CompleteListOf16BitServiceUuids() const;
+  std::optional<UuidList> IncompleteListOf32BitServiceUuids() const;
+  std::optional<UuidList> CompleteListOf32BitServiceUuids() const;
+  std::optional<UuidList> IncompleteListOf128BitServiceUuids() const;
+  std::optional<UuidList> CompleteListOf128BitServiceUuids() const;
 
   using ServiceDataMap =
       std::map<bluetooth_v2_shlib::Uuid, std::vector<uint8_t>>;
diff --git a/chromecast/device/bluetooth/le/le_scan_result_test.cc b/chromecast/device/bluetooth/le/le_scan_result_test.cc
index f86d210..0c534e31 100644
--- a/chromecast/device/bluetooth/le/le_scan_result_test.cc
+++ b/chromecast/device/bluetooth/le/le_scan_result_test.cc
@@ -62,7 +62,7 @@
       std::vector<uint8_t>(
           reinterpret_cast<const uint8_t*>(kName1),
           reinterpret_cast<const uint8_t*>(kName1) + strlen(kName1)));
-  absl::optional<std::string> name = scan_result.Name();
+  std::optional<std::string> name = scan_result.Name();
   ASSERT_TRUE(name);
   EXPECT_EQ(kName1, *name);
 
diff --git a/chromecast/device/bluetooth/le/mock_le_scan_manager.h b/chromecast/device/bluetooth/le/mock_le_scan_manager.h
index 066c3ab..6a0bd00 100644
--- a/chromecast/device/bluetooth/le/mock_le_scan_manager.h
+++ b/chromecast/device/bluetooth/le/mock_le_scan_manager.h
@@ -48,9 +48,9 @@
 
   MOCK_METHOD(std::vector<LeScanResult>,
               GetScanResults,
-              (absl::optional<ScanFilter> scan_filter));
+              (std::optional<ScanFilter> scan_filter));
   void GetScanResults(GetScanResultsCallback cb,
-                      absl::optional<ScanFilter> scan_filter) override {
+                      std::optional<ScanFilter> scan_filter) override {
     std::move(cb).Run(GetScanResults(std::move(scan_filter)));
   }
   MOCK_METHOD(void, ClearScanResults, (), (override));
diff --git a/chromecast/device/bluetooth/le/scan_filter.cc b/chromecast/device/bluetooth/le/scan_filter.cc
index 7a63311..6e70492 100644
--- a/chromecast/device/bluetooth/le/scan_filter.cc
+++ b/chromecast/device/bluetooth/le/scan_filter.cc
@@ -29,7 +29,7 @@
   }
 
   if (service_uuid) {
-    absl::optional<LeScanResult::UuidList> all_uuids =
+    std::optional<LeScanResult::UuidList> all_uuids =
         scan_result.AllServiceUuids();
     if (!all_uuids) {
       return false;
@@ -41,7 +41,7 @@
   }
 
   if (!name && regex_name) {
-    absl::optional<std::string> scan_name = scan_result.Name();
+    std::optional<std::string> scan_name = scan_result.Name();
     if (!scan_name || !RE2::PartialMatch(*scan_name, *regex_name)) {
       return false;
     }
diff --git a/chromecast/device/bluetooth/le/scan_filter.h b/chromecast/device/bluetooth/le/scan_filter.h
index b9b8127..9a872ae 100644
--- a/chromecast/device/bluetooth/le/scan_filter.h
+++ b/chromecast/device/bluetooth/le/scan_filter.h
@@ -7,9 +7,9 @@
 
 #include <string>
 
+#include <optional>
 #include "chromecast/device/bluetooth/le/le_scan_result.h"
 #include "chromecast/public/bluetooth/bluetooth_types.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace chromecast {
 namespace bluetooth {
@@ -26,13 +26,13 @@
   bool Matches(const LeScanResult& scan_result) const;
 
   // Exact name.
-  absl::optional<std::string> name;
+  std::optional<std::string> name;
 
   // RE2 partial match on name. This is ignored if |name| is specified.
   // https://github.com/google/re2
-  absl::optional<std::string> regex_name;
+  std::optional<std::string> regex_name;
 
-  absl::optional<bluetooth_v2_shlib::Uuid> service_uuid;
+  std::optional<bluetooth_v2_shlib::Uuid> service_uuid;
 };
 
 }  // namespace bluetooth
diff --git a/chromecast/external_mojo/public/cpp/external_mojo_broker.cc b/chromecast/external_mojo/public/cpp/external_mojo_broker.cc
index edb1c20e..0aac0a5 100644
--- a/chromecast/external_mojo/public/cpp/external_mojo_broker.cc
+++ b/chromecast/external_mojo/public/cpp/external_mojo_broker.cc
@@ -15,6 +15,7 @@
 #include <sys/stat.h>
 #endif
 
+#include <optional>
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "base/location.h"
@@ -42,7 +43,6 @@
 #include "services/service_manager/public/cpp/service_receiver.h"
 #include "services/service_manager/public/mojom/connector.mojom.h"
 #include "services/service_manager/public/mojom/service.mojom.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_ANDROID)
 #include "base/android/bundle_utils.h"
@@ -66,7 +66,7 @@
     const std::string& service_name,
     const std::string& interface_name,
     service_manager::mojom::ConnectResult result,
-    const absl::optional<service_manager::Identity>& identity) {
+    const std::optional<service_manager::Identity>& identity) {
   if (result != service_manager::mojom::ConnectResult::SUCCEEDED) {
     LOG(ERROR) << "Failed to bind " << service_name << ":" << interface_name
                << ", result = " << result;
@@ -147,7 +147,7 @@
       connector_->BindInterface(filter.service_name(), interface_name,
                                 std::move(interface_pipe));
       std::move(callback).Run(service_manager::mojom::ConnectResult::SUCCEEDED,
-                              absl::nullopt);
+                              std::nullopt);
     }
 
     void QueryService(const std::string& service_name,
@@ -159,7 +159,7 @@
     void WarmService(const ::service_manager::ServiceFilter& filter,
                      WarmServiceCallback callback) override {
       std::move(callback).Run(service_manager::mojom::ConnectResult::SUCCEEDED,
-                              absl::nullopt);
+                              std::nullopt);
     }
 
     void RegisterServiceInstance(
diff --git a/chromecast/graphics/cast_screen.h b/chromecast/graphics/cast_screen.h
index c044f5c4..672c3a2 100644
--- a/chromecast/graphics/cast_screen.h
+++ b/chromecast/graphics/cast_screen.h
@@ -5,8 +5,8 @@
 #ifndef CHROMECAST_GRAPHICS_CAST_SCREEN_H_
 #define CHROMECAST_GRAPHICS_CAST_SCREEN_H_
 
+#include <optional>
 #include "chromecast/public/graphics_types.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/display/display.h"
 #include "ui/display/screen_base.h"
 
@@ -54,7 +54,7 @@
   bool RestorePrimaryDisplaySettings();
 
  private:
-  absl::optional<display::Display> stashed_display_settings_;
+  std::optional<display::Display> stashed_display_settings_;
 };
 
 }  // namespace chromecast
diff --git a/chromecast/media/audio/audio_clock_simulator_impl.cc b/chromecast/media/audio/audio_clock_simulator_impl.cc
index fb4b0f3..7d4a45c 100644
--- a/chromecast/media/audio/audio_clock_simulator_impl.cc
+++ b/chromecast/media/audio/audio_clock_simulator_impl.cc
@@ -8,13 +8,13 @@
 #include <cstdint>
 #include <memory>
 
+#include <optional>
 #include "base/check_op.h"
 #include "base/functional/bind.h"
 #include "chromecast/media/api/audio_clock_simulator.h"
 #include "chromecast/media/api/audio_provider.h"
 #include "media/base/audio_bus.h"
 #include "media/base/multi_channel_resampler.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace chromecast {
 namespace media {
@@ -133,7 +133,7 @@
   int64_t request_timestamp_ = 0;
   double resampler_buffered_frames_ = 0.0;
   bool in_fill_ = false;
-  absl::optional<double> pending_rate_;
+  std::optional<double> pending_rate_;
 };
 
 }  // namespace
diff --git a/chromecast/media/audio/cast_audio_renderer.cc b/chromecast/media/audio/cast_audio_renderer.cc
index 5bf3b4a..3fec7e1 100644
--- a/chromecast/media/audio/cast_audio_renderer.cc
+++ b/chromecast/media/audio/cast_audio_renderer.cc
@@ -200,7 +200,7 @@
 }
 
 void CastAudioRenderer::SetLatencyHint(
-    absl::optional<base::TimeDelta> latency_hint) {
+    std::optional<base::TimeDelta> latency_hint) {
   NOTIMPLEMENTED();
 }
 
diff --git a/chromecast/media/audio/cast_audio_renderer.h b/chromecast/media/audio/cast_audio_renderer.h
index 80d00df..fe7f27d 100644
--- a/chromecast/media/audio/cast_audio_renderer.h
+++ b/chromecast/media/audio/cast_audio_renderer.h
@@ -83,7 +83,7 @@
   void Flush(base::OnceClosure callback) override;
   void StartPlaying() override;
   void SetVolume(float volume) override;
-  void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) override;
+  void SetLatencyHint(std::optional<base::TimeDelta> latency_hint) override;
   void SetPreservesPitch(bool preserves_pitch) override;
   void SetWasPlayedWithUserActivation(
       bool was_played_with_user_activation) override;
diff --git a/chromecast/media/audio/net/audio_socket_service_tcp.cc b/chromecast/media/audio/net/audio_socket_service_tcp.cc
index e402251..8a43b2c 100644
--- a/chromecast/media/audio/net/audio_socket_service_tcp.cc
+++ b/chromecast/media/audio/net/audio_socket_service_tcp.cc
@@ -51,7 +51,7 @@
                                                           net::NetLogSource());
   int result = listen_socket_->Listen(
       net::IPEndPoint(net::IPAddress::IPv4Localhost(), port), kListenBacklog,
-      /*ipv6_only=*/absl::nullopt);
+      /*ipv6_only=*/std::nullopt);
 
   if (result != net::OK) {
     LOG(ERROR) << "Listen failed: " << net::ErrorToString(result);
diff --git a/chromecast/media/cma/backend/alsa/alsa_volume_control.cc b/chromecast/media/cma/backend/alsa/alsa_volume_control.cc
index 4b91fc61..cc79075 100644
--- a/chromecast/media/cma/backend/alsa/alsa_volume_control.cc
+++ b/chromecast/media/cma/backend/alsa/alsa_volume_control.cc
@@ -341,11 +341,11 @@
   return success;
 }
 
-absl::optional<bool> AlsaVolumeControl::IsElementAllMuted(
+std::optional<bool> AlsaVolumeControl::IsElementAllMuted(
     ScopedAlsaMixer* mixer) {
   if (!mixer || !mixer->element ||
       !alsa_->MixerSelemHasPlaybackSwitch(mixer->element)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   for (int32_t channel = 0; channel <= SND_MIXER_SCHN_LAST; ++channel) {
     int channel_unmuted;
@@ -354,7 +354,7 @@
         &channel_unmuted);
     if (err != 0) {
       LOG(ERROR) << "MixerSelemGetPlaybackSwitch: " << alsa_->StrError(err);
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (channel_unmuted) {
       return false;
diff --git a/chromecast/media/cma/backend/alsa/alsa_volume_control.h b/chromecast/media/cma/backend/alsa/alsa_volume_control.h
index 713eb685..3c9b48c 100644
--- a/chromecast/media/cma/backend/alsa/alsa_volume_control.h
+++ b/chromecast/media/cma/backend/alsa/alsa_volume_control.h
@@ -9,10 +9,10 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/timer/timer.h"
 #include "chromecast/media/cma/backend/system_volume_control.h"
 #include "media/audio/alsa/alsa_wrapper.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace chromecast {
 namespace media {
@@ -55,9 +55,9 @@
                                         unsigned int mask);
 
   bool SetElementMuted(ScopedAlsaMixer* mixer, bool muted);
-  // Returns true if all channels are muted, returns absl::nullopt if element
+  // Returns true if all channels are muted, returns std::nullopt if element
   // state is not accessible.
-  absl::optional<bool> IsElementAllMuted(ScopedAlsaMixer* mixer);
+  std::optional<bool> IsElementAllMuted(ScopedAlsaMixer* mixer);
 
   void OnVolumeOrMuteChanged();
 
diff --git a/chromecast/media/cma/backend/cast_audio_json.cc b/chromecast/media/cma/backend/cast_audio_json.cc
index 45761538..bc65ccf 100644
--- a/chromecast/media/cma/backend/cast_audio_json.cc
+++ b/chromecast/media/cma/backend/cast_audio_json.cc
@@ -29,7 +29,7 @@
 
   std::string contents;
   base::ReadFileToString(path, &contents);
-  absl::optional<base::Value> value = base::JSONReader::Read(contents);
+  std::optional<base::Value> value = base::JSONReader::Read(contents);
   if (value && value->is_dict()) {
     callback.Run(std::move(*value).TakeDict());
     return;
@@ -76,13 +76,13 @@
 
 CastAudioJsonProviderImpl::~CastAudioJsonProviderImpl() = default;
 
-absl::optional<base::Value::Dict>
+std::optional<base::Value::Dict>
 CastAudioJsonProviderImpl::GetCastAudioConfig() {
   std::string contents;
   base::ReadFileToString(CastAudioJson::GetFilePath(), &contents);
-  absl::optional<base::Value> value = base::JSONReader::Read(contents);
+  std::optional<base::Value> value = base::JSONReader::Read(contents);
   if (!value || value->is_dict()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return std::move(*value).TakeDict();
diff --git a/chromecast/media/cma/backend/cast_audio_json.h b/chromecast/media/cma/backend/cast_audio_json.h
index eeaa391..927c62c 100644
--- a/chromecast/media/cma/backend/cast_audio_json.h
+++ b/chromecast/media/cma/backend/cast_audio_json.h
@@ -5,13 +5,13 @@
 #ifndef CHROMECAST_MEDIA_CMA_BACKEND_CAST_AUDIO_JSON_H_
 #define CHROMECAST_MEDIA_CMA_BACKEND_CAST_AUDIO_JSON_H_
 
+#include <optional>
 #include "base/files/file_path.h"
 #include "base/files/file_path_watcher.h"
 #include "base/functional/callback.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/threading/sequence_bound.h"
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace chromecast {
 namespace media {
@@ -30,7 +30,7 @@
 class CastAudioJsonProvider {
  public:
   using TuningChangedCallback =
-      base::RepeatingCallback<void(absl::optional<base::Value::Dict> contents)>;
+      base::RepeatingCallback<void(std::optional<base::Value::Dict> contents)>;
 
   virtual ~CastAudioJsonProvider() = default;
 
@@ -40,7 +40,7 @@
   // at CastAudioJson::GetReadOnlyFilePath() will be returned.
   // This function will run on the thread on which it is called, and may
   // perform blocking I/O.
-  virtual absl::optional<base::Value::Dict> GetCastAudioConfig() = 0;
+  virtual std::optional<base::Value::Dict> GetCastAudioConfig() = 0;
 
   // |callback| will be called when a new cast_audio config is available.
   // |callback| will always be called from the same thread, but not necessarily
@@ -71,7 +71,7 @@
   };
 
   // CastAudioJsonProvider implementation:
-  absl::optional<base::Value::Dict> GetCastAudioConfig() override;
+  std::optional<base::Value::Dict> GetCastAudioConfig() override;
   void SetTuningChangedCallback(TuningChangedCallback callback) override;
 
   base::SequenceBound<FileWatcher> cast_audio_watcher_;
diff --git a/chromecast/media/cma/backend/cplay/cplay.cc b/chromecast/media/cma/backend/cplay/cplay.cc
index 60173fb..138b106 100644
--- a/chromecast/media/cma/backend/cplay/cplay.cc
+++ b/chromecast/media/cma/backend/cplay/cplay.cc
@@ -339,11 +339,11 @@
   // Set volume.
   std::string contents;
   base::ReadFileToString(params.cast_audio_json_path, &contents);
-  absl::optional<base::Value> parsed_json = base::JSONReader::Read(contents);
+  std::optional<base::Value> parsed_json = base::JSONReader::Read(contents);
   if (parsed_json && parsed_json->is_dict()) {
     GetVolumeMap().LoadVolumeMap(std::move(*parsed_json).TakeDict());
   } else {
-    GetVolumeMap().LoadVolumeMap(absl::nullopt);
+    GetVolumeMap().LoadVolumeMap(std::nullopt);
   }
   float volume_dbfs = GetVolumeMap().VolumeToDbFS(params.cast_volume);
   float volume_multiplier = std::pow(10.0, volume_dbfs / 20.0);
diff --git a/chromecast/media/cma/backend/mixer/mixer_input_connection.cc b/chromecast/media/cma/backend/mixer/mixer_input_connection.cc
index 341b19c..4651021 100644
--- a/chromecast/media/cma/backend/mixer/mixer_input_connection.cc
+++ b/chromecast/media/cma/backend/mixer/mixer_input_connection.cc
@@ -11,6 +11,7 @@
 #include <limits>
 #include <utility>
 
+#include <optional>
 #include "base/command_line.h"
 #include "base/functional/bind.h"
 #include "base/location.h"
@@ -35,7 +36,6 @@
 #include "media/base/audio_bus.h"
 #include "media/base/audio_timestamp_helper.h"
 #include "media/filters/audio_renderer_algorithm.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace chromecast {
 namespace media {
@@ -327,7 +327,7 @@
   const int num_channels_;
   const int sample_rate_;
 
-  absl::optional<int> pending_silence_;
+  std::optional<int> pending_silence_;
   FaderProvider fader_provider_;
   AudioFader fader_;
   bool after_silence_ = true;
diff --git a/chromecast/media/cma/backend/mixer/mock_post_processor_factory.cc b/chromecast/media/cma/backend/mixer/mock_post_processor_factory.cc
index a843325..4f71990 100644
--- a/chromecast/media/cma/backend/mixer/mock_post_processor_factory.cc
+++ b/chromecast/media/cma/backend/mixer/mock_post_processor_factory.cc
@@ -40,15 +40,15 @@
       const base::Value::Dict* processor_config_dict =
           elem.GetDict().FindDict("config");
       CHECK(processor_config_dict);
-      absl::optional<int> delay = processor_config_dict->FindInt("delay");
+      std::optional<int> delay = processor_config_dict->FindInt("delay");
       CHECK(delay.has_value());
       rendering_delay_frames_ += *delay;
-      absl::optional<bool> ringing = processor_config_dict->FindBool("ringing");
+      std::optional<bool> ringing = processor_config_dict->FindBool("ringing");
       if (ringing.has_value()) {
         ringing_ = *ringing;
       }
 
-      absl::optional<int> output_ch =
+      std::optional<int> output_ch =
           processor_config_dict->FindInt("output_channels");
       if (output_ch.has_value()) {
         num_output_channels_ = *output_ch;
diff --git a/chromecast/media/cma/backend/mixer/post_processing_pipeline_parser.cc b/chromecast/media/cma/backend/mixer/post_processing_pipeline_parser.cc
index 96c990a7..24cd5f0 100644
--- a/chromecast/media/cma/backend/mixer/post_processing_pipeline_parser.cc
+++ b/chromecast/media/cma/backend/mixer/post_processing_pipeline_parser.cc
@@ -67,7 +67,7 @@
     base::Value prerender_pipeline_in,
     base::Value pipeline_in,
     const base::Value* stream_types_in,
-    const absl::optional<int> num_input_channels_in,
+    const std::optional<int> num_input_channels_in,
     const base::Value* volume_limits_in)
     : prerender_pipeline(std::move(prerender_pipeline_in)),
       pipeline(std::move(pipeline_in)),
@@ -179,7 +179,7 @@
                  << "\" in " << file_path_ << ". Using passthrough.";
     return StreamPipelineDescriptor(base::Value(base::Value::Type::LIST),
                                     base::Value(base::Value::Type::LIST),
-                                    nullptr, absl::nullopt, nullptr);
+                                    nullptr, std::nullopt, nullptr);
   }
 
   const base::Value::Dict& stream_dict = stream_value->GetDict();
diff --git a/chromecast/media/cma/backend/mixer/post_processing_pipeline_parser.h b/chromecast/media/cma/backend/mixer/post_processing_pipeline_parser.h
index 5a5fced..546e45cd 100644
--- a/chromecast/media/cma/backend/mixer/post_processing_pipeline_parser.h
+++ b/chromecast/media/cma/backend/mixer/post_processing_pipeline_parser.h
@@ -9,9 +9,9 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/files/file_path.h"
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace chromecast {
 namespace media {
@@ -27,13 +27,13 @@
   base::Value prerender_pipeline;
   base::Value pipeline;
   const base::Value* stream_types;
-  absl::optional<int> num_input_channels;
+  std::optional<int> num_input_channels;
   const base::Value* volume_limits;
 
   StreamPipelineDescriptor(base::Value prerender_pipeline_in,
                            base::Value pipeline_in,
                            const base::Value* stream_types_in,
-                           const absl::optional<int> num_input_channels_in,
+                           const std::optional<int> num_input_channels_in,
                            const base::Value* volume_limits_in);
   ~StreamPipelineDescriptor();
   StreamPipelineDescriptor(StreamPipelineDescriptor&& other);
diff --git a/chromecast/media/cma/backend/proxy/audio_channel_push_buffer_handler.h b/chromecast/media/cma/backend/proxy/audio_channel_push_buffer_handler.h
index 584b806..e9fe91bc 100644
--- a/chromecast/media/cma/backend/proxy/audio_channel_push_buffer_handler.h
+++ b/chromecast/media/cma/backend/proxy/audio_channel_push_buffer_handler.h
@@ -5,8 +5,8 @@
 #ifndef CHROMECAST_MEDIA_CMA_BACKEND_PROXY_AUDIO_CHANNEL_PUSH_BUFFER_HANDLER_H_
 #define CHROMECAST_MEDIA_CMA_BACKEND_PROXY_AUDIO_CHANNEL_PUSH_BUFFER_HANDLER_H_
 
+#include <optional>
 #include "chromecast/media/api/cma_backend.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/cast_core/public/src/proto/runtime/cast_audio_channel_service.pb.h"
 
 namespace chromecast {
@@ -62,7 +62,7 @@
   // true.
   //
   // May only be called by the CONSUMER.
-  virtual absl::optional<PushBufferRequest> GetBufferedData() = 0;
+  virtual std::optional<PushBufferRequest> GetBufferedData() = 0;
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/proxy/buffer_id_manager.h b/chromecast/media/cma/backend/proxy/buffer_id_manager.h
index 541ea1c..2c35979 100644
--- a/chromecast/media/cma/backend/proxy/buffer_id_manager.h
+++ b/chromecast/media/cma/backend/proxy/buffer_id_manager.h
@@ -9,11 +9,11 @@
 #include <queue>
 #include <utility>
 
+#include <optional>
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
 #include "chromecast/media/api/cma_backend.h"
 #include "chromecast/media/cma/backend/proxy/audio_decoder_pipeline_node.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace chromecast {
 namespace media {
@@ -155,7 +155,7 @@
   int64_t pending_playback_time_in_microseconds_ = 0;
 
   // Information about the most recently played buffer.
-  mutable absl::optional<BufferPlayoutInfo> most_recently_played_buffer_;
+  mutable std::optional<BufferPlayoutInfo> most_recently_played_buffer_;
 
   BufferIdQueue buffer_id_queue_;
   std::queue<BufferInfo> buffer_infos_;
diff --git a/chromecast/media/cma/backend/proxy/cast_runtime_audio_channel_broker.h b/chromecast/media/cma/backend/proxy/cast_runtime_audio_channel_broker.h
index 6a13c981..aee01ae 100644
--- a/chromecast/media/cma/backend/proxy/cast_runtime_audio_channel_broker.h
+++ b/chromecast/media/cma/backend/proxy/cast_runtime_audio_channel_broker.h
@@ -7,8 +7,8 @@
 
 #include <memory>
 
+#include <optional>
 #include "base/memory/weak_ptr.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/cast_core/public/src/proto/runtime/cast_audio_channel_service.pb.h"
 #include "third_party/protobuf/src/google/protobuf/duration.pb.h"
 
@@ -71,7 +71,7 @@
 
     // Returns a PushBufferRequest to be sent across the |PushBuffer| RPC. May
     // only be called if |HasBufferedData()| is true.
-    virtual absl::optional<PushBufferRequest> GetBufferedData() = 0;
+    virtual std::optional<PushBufferRequest> GetBufferedData() = 0;
     virtual bool HasBufferedData() = 0;
 
     // Handlers for the responses of the messages defined in
@@ -103,7 +103,7 @@
 
     // Called when a |GetMediaTime| RPC call completes. If |status| is kOK, then
     // |time| is a valid non-empty MediaTime object. Else, |time| may be empty.
-    virtual void HandleGetMediaTimeResponse(absl::optional<MediaTime> time,
+    virtual void HandleGetMediaTimeResponse(std::optional<MediaTime> time,
                                             StatusCode status) = 0;
   };
 
diff --git a/chromecast/media/cma/backend/proxy/media_pipeline_buffer_extension.h b/chromecast/media/cma/backend/proxy/media_pipeline_buffer_extension.h
index 2eae453..a0b213c5 100644
--- a/chromecast/media/cma/backend/proxy/media_pipeline_buffer_extension.h
+++ b/chromecast/media/cma/backend/proxy/media_pipeline_buffer_extension.h
@@ -8,6 +8,7 @@
 #include <memory>
 #include <queue>
 
+#include <optional>
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
@@ -15,7 +16,6 @@
 #include "chromecast/media/api/cma_backend.h"
 #include "chromecast/media/cma/backend/proxy/audio_decoder_pipeline_node.h"
 #include "chromecast/public/media/cast_key_status.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace chromecast {
 
@@ -61,8 +61,8 @@
     PendingCommand& operator=(const PendingCommand& other);
     PendingCommand& operator=(PendingCommand&& other);
 
-    absl::optional<scoped_refptr<DecoderBufferBase>> buffer;
-    absl::optional<AudioConfig> config;
+    std::optional<scoped_refptr<DecoderBufferBase>> buffer;
+    std::optional<AudioConfig> config;
   };
 
   // AudioDecoderPipelineNode overrides.
diff --git a/chromecast/media/cma/backend/proxy/proxy_call_translator.cc b/chromecast/media/cma/backend/proxy/proxy_call_translator.cc
index 3cf01702..257b8f2 100644
--- a/chromecast/media/cma/backend/proxy/proxy_call_translator.cc
+++ b/chromecast/media/cma/backend/proxy/proxy_call_translator.cc
@@ -288,7 +288,7 @@
       ToGrpcTypes(std::move(buffer), buffer_id));
 }
 
-absl::optional<ProxyCallTranslator::PushBufferRequest>
+std::optional<ProxyCallTranslator::PushBufferRequest>
 ProxyCallTranslator::GetBufferedData() {
   return push_buffer_handler_.GetBufferedData();
 }
@@ -339,7 +339,7 @@
 }
 
 void ProxyCallTranslator::HandleGetMediaTimeResponse(
-    absl::optional<MediaTime> time,
+    std::optional<MediaTime> time,
     CastRuntimeAudioChannelBroker::StatusCode status) {
   NOTREACHED();
 }
diff --git a/chromecast/media/cma/backend/proxy/proxy_call_translator.h b/chromecast/media/cma/backend/proxy/proxy_call_translator.h
index ca2c11d..f597d93 100644
--- a/chromecast/media/cma/backend/proxy/proxy_call_translator.h
+++ b/chromecast/media/cma/backend/proxy/proxy_call_translator.h
@@ -7,13 +7,13 @@
 
 #include <memory>
 
+#include <optional>
 #include "base/memory/ref_counted.h"
 #include "chromecast/media/api/decoder_buffer_base.h"
 #include "chromecast/media/cma/backend/proxy/buffer_id_manager.h"
 #include "chromecast/media/cma/backend/proxy/cast_runtime_audio_channel_broker.h"
 #include "chromecast/media/cma/backend/proxy/cma_proxy_handler.h"
 #include "chromecast/media/cma/backend/proxy/push_buffer_pending_handler.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace chromecast {
 
@@ -75,7 +75,7 @@
       std::unique_ptr<CastRuntimeAudioChannelBroker> decoder_channel);
 
   // CastRuntimeAudioChannelBroker::Handler overrides:
-  absl::optional<PushBufferRequest> GetBufferedData() override;
+  std::optional<PushBufferRequest> GetBufferedData() override;
   bool HasBufferedData() override;
   void HandleInitializeResponse(
       CastRuntimeAudioChannelBroker::StatusCode status) override;
@@ -90,7 +90,7 @@
       int64_t decoded_bytes,
       CastRuntimeAudioChannelBroker::StatusCode status) override;
   void HandleGetMediaTimeResponse(
-      absl::optional<MediaTime> time,
+      std::optional<MediaTime> time,
       CastRuntimeAudioChannelBroker::StatusCode status) override;
 
   // Helper to share error handling code.
diff --git a/chromecast/media/cma/backend/proxy/push_buffer_pending_handler.cc b/chromecast/media/cma/backend/proxy/push_buffer_pending_handler.cc
index 4f4201f..2cc00726 100644
--- a/chromecast/media/cma/backend/proxy/push_buffer_pending_handler.cc
+++ b/chromecast/media/cma/backend/proxy/push_buffer_pending_handler.cc
@@ -77,7 +77,7 @@
   return delegated_handler_->HasBufferedData();
 }
 
-absl::optional<AudioChannelPushBufferHandler::PushBufferRequest>
+std::optional<AudioChannelPushBufferHandler::PushBufferRequest>
 PushBufferPendingHandler::GetBufferedData() {
   // The pending data is only considered by the producer sequence, so this
   // consumer sequence call does not consider it.
diff --git a/chromecast/media/cma/backend/proxy/push_buffer_pending_handler.h b/chromecast/media/cma/backend/proxy/push_buffer_pending_handler.h
index f6792fb..58820f8 100644
--- a/chromecast/media/cma/backend/proxy/push_buffer_pending_handler.h
+++ b/chromecast/media/cma/backend/proxy/push_buffer_pending_handler.h
@@ -58,7 +58,7 @@
   CmaBackend::BufferStatus PushBuffer(
       const PushBufferRequest& request) override;
   bool HasBufferedData() const override;
-  absl::optional<PushBufferRequest> GetBufferedData() override;
+  std::optional<PushBufferRequest> GetBufferedData() override;
 
  private:
   friend class PushBufferPendingHandlerTest;
diff --git a/chromecast/media/cma/backend/proxy/push_buffer_pending_handler_unittest.cc b/chromecast/media/cma/backend/proxy/push_buffer_pending_handler_unittest.cc
index 911b5f4..000cc0d 100644
--- a/chromecast/media/cma/backend/proxy/push_buffer_pending_handler_unittest.cc
+++ b/chromecast/media/cma/backend/proxy/push_buffer_pending_handler_unittest.cc
@@ -71,7 +71,7 @@
 
   MOCK_METHOD1(PushBuffer, CmaBackend::BufferStatus(const PushBufferRequest&));
   MOCK_CONST_METHOD0(HasBufferedData, bool());
-  MOCK_METHOD0(GetBufferedData, absl::optional<PushBufferRequest>());
+  MOCK_METHOD0(GetBufferedData, std::optional<PushBufferRequest>());
 };
 
 }  // namespace
diff --git a/chromecast/media/cma/backend/proxy/push_buffer_queue.cc b/chromecast/media/cma/backend/proxy/push_buffer_queue.cc
index 04b2333..f824ada 100644
--- a/chromecast/media/cma/backend/proxy/push_buffer_queue.cc
+++ b/chromecast/media/cma/backend/proxy/push_buffer_queue.cc
@@ -32,9 +32,9 @@
 PushBufferQueue::PushBufferQueue()
     : producer_handler_(this),
       consumer_handler_(this),
-      consumer_stream_(absl::in_place, &consumer_handler_),
-      protobuf_consumer_stream_(absl::in_place, &consumer_stream_.value(), 1),
-      producer_stream_(absl::in_place, &producer_handler_) {
+      consumer_stream_(std::in_place, &consumer_handler_),
+      protobuf_consumer_stream_(std::in_place, &consumer_stream_.value(), 1),
+      producer_stream_(std::in_place, &producer_handler_) {
   DETACH_FROM_SEQUENCE(producer_sequence_checker_);
   DETACH_FROM_SEQUENCE(consumer_sequence_checker_);
 }
@@ -70,7 +70,7 @@
     // when the entire |buffer_| is full at time of writing.
     bytes_written_during_current_write_ = 0;
     producer_handler_.overflow();
-    producer_stream_ = absl::nullopt;
+    producer_stream_ = std::nullopt;
     producer_stream_.emplace(&producer_handler_);
   }
 
@@ -82,7 +82,7 @@
   return !is_in_invalid_state_ && GetAvailableyByteCount() != size_t{0};
 }
 
-absl::optional<PushBufferQueue::PushBufferRequest>
+std::optional<PushBufferQueue::PushBufferRequest>
 PushBufferQueue::GetBufferedData() {
   auto result = GetBufferedDataImpl();
   if (result.has_value()) {
@@ -92,7 +92,7 @@
   return result;
 }
 
-absl::optional<PushBufferQueue::PushBufferRequest>
+std::optional<PushBufferQueue::PushBufferRequest>
 PushBufferQueue::GetBufferedDataImpl() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(consumer_sequence_checker_);
   DCHECK(HasBufferedData());
@@ -124,12 +124,12 @@
 
     // If |!succeeded|, the streams have ended up in an unexpected state and
     // need to be recreated.
-    protobuf_consumer_stream_ = absl::nullopt;
-    consumer_stream_ = absl::nullopt;
+    protobuf_consumer_stream_ = std::nullopt;
+    consumer_stream_ = std::nullopt;
     consumer_stream_.emplace(&consumer_handler_);
     protobuf_consumer_stream_.emplace(&consumer_stream_.value(), 1);
 
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   consecuitive_read_failures_ = 0;
diff --git a/chromecast/media/cma/backend/proxy/push_buffer_queue.h b/chromecast/media/cma/backend/proxy/push_buffer_queue.h
index 6442e07..53ebb2f 100644
--- a/chromecast/media/cma/backend/proxy/push_buffer_queue.h
+++ b/chromecast/media/cma/backend/proxy/push_buffer_queue.h
@@ -9,11 +9,11 @@
 #include <istream>
 #include <ostream>
 
+#include <optional>
 #include "base/sequence_checker.h"
 #include "chromecast/media/api/cma_backend.h"
 #include "chromecast/media/api/decoder_buffer_base.h"
 #include "chromecast/media/cma/backend/proxy/audio_channel_push_buffer_handler.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/cast_core/public/src/proto/runtime/cast_audio_channel_service.pb.h"
 #include "third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl.h"
 
@@ -47,7 +47,7 @@
   CmaBackend::BufferStatus PushBuffer(
       const PushBufferRequest& request) override;
   bool HasBufferedData() const override;
-  absl::optional<PushBufferRequest> GetBufferedData() override;
+  std::optional<PushBufferRequest> GetBufferedData() override;
 
  private:
   // These classes exist for the following 2 reasons:
@@ -128,7 +128,7 @@
 
   // Helper methods to be used for test hooks.
   bool PushBufferImpl(const PushBufferRequest& request);
-  absl::optional<PushBufferRequest> GetBufferedDataImpl();
+  std::optional<PushBufferRequest> GetBufferedDataImpl();
 
   // Buffer where serialized PushBufferRequest data is stored.
   char buffer_[kBufferSizeBytes];
@@ -168,14 +168,14 @@
   // Input streams backed by this instance. They must be optional so that they
   // can be re-created following a failed read. These should only be used by the
   // CONSUMER.
-  absl::optional<std::istream> consumer_stream_;
-  absl::optional<google::protobuf::io::IstreamInputStream>
+  std::optional<std::istream> consumer_stream_;
+  std::optional<google::protobuf::io::IstreamInputStream>
       protobuf_consumer_stream_;
 
   // Output stream backed by this instance. This must be optional so it can be
   // re-created following a failed write. It should only be used by the
   // PRODUCER.
-  absl::optional<std::ostream> producer_stream_;
+  std::optional<std::ostream> producer_stream_;
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/proxy/push_buffer_queue_unittest.cc b/chromecast/media/cma/backend/proxy/push_buffer_queue_unittest.cc
index 3ad7dc5..a41e7bfb 100644
--- a/chromecast/media/cma/backend/proxy/push_buffer_queue_unittest.cc
+++ b/chromecast/media/cma/backend/proxy/push_buffer_queue_unittest.cc
@@ -7,12 +7,12 @@
 #include <atomic>
 #include <sstream>
 
+#include <optional>
 #include "base/functional/bind.h"
 #include "base/location.h"
 #include "base/threading/thread.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/cast_core/public/src/proto/runtime/cast_audio_channel_service.grpc.pb.h"
 
 namespace chromecast {
@@ -49,7 +49,7 @@
   void ReadData(const std::string& name,
                 const PushBufferQueue::PushBufferRequest& target_buffer) {
     ASSERT_TRUE(queue_.HasBufferedData()) << name;
-    absl::optional<PushBufferRequest> get = queue_.GetBufferedData();
+    std::optional<PushBufferRequest> get = queue_.GetBufferedData();
     ASSERT_TRUE(get.has_value()) << name;
     CheckEqual("first", get.value(), target_buffer);
   }
@@ -137,7 +137,7 @@
     return queue_.PushBufferImpl(request);
   }
 
-  absl::optional<PushBufferQueue::PushBufferRequest> StartGetBufferedData() {
+  std::optional<PushBufferQueue::PushBufferRequest> StartGetBufferedData() {
     return queue_.GetBufferedDataImpl();
   }
 
@@ -270,7 +270,7 @@
   UpdateBufferWriteStreamPositions();
 
   ASSERT_TRUE(queue_.HasBufferedData());
-  absl::optional<PushBufferRequest> pulled_buffer = queue_.GetBufferedData();
+  std::optional<PushBufferRequest> pulled_buffer = queue_.GetBufferedData();
   EXPECT_FALSE(pulled_buffer.has_value());
   EXPECT_TRUE(queue_.HasBufferedData());
 
diff --git a/chromecast/media/cma/backend/volume_control.cc b/chromecast/media/cma/backend/volume_control.cc
index 3fd2d01..17f899e6 100644
--- a/chromecast/media/cma/backend/volume_control.cc
+++ b/chromecast/media/cma/backend/volume_control.cc
@@ -203,7 +203,7 @@
 
     for (auto type : {AudioContentType::kMedia, AudioContentType::kAlarm,
                       AudioContentType::kCommunication}) {
-      absl::optional<double> dbfs =
+      std::optional<double> dbfs =
           stored_values_.FindDouble(ContentTypeToDbFSPath(type));
       CHECK(dbfs);
       volumes_[type] = VolumeControl::DbFSToVolume(*dbfs);
diff --git a/chromecast/media/cma/backend/volume_map.cc b/chromecast/media/cma/backend/volume_map.cc
index 200e69a..05fb504 100644
--- a/chromecast/media/cma/backend/volume_map.cc
+++ b/chromecast/media/cma/backend/volume_map.cc
@@ -49,7 +49,7 @@
 }
 
 void VolumeMap::LoadVolumeMap(
-    absl::optional<base::Value::Dict> cast_audio_config) {
+    std::optional<base::Value::Dict> cast_audio_config) {
   if (!cast_audio_config) {
     LOG(WARNING) << "No cast audio config found; using default volume map.";
     UseDefaultVolumeMap();
@@ -70,14 +70,14 @@
   for (const auto& value : *volume_map_list) {
     const base::Value::Dict& volume_map_entry = value.GetDict();
 
-    absl::optional<double> level = volume_map_entry.FindDouble(kKeyLevel);
+    std::optional<double> level = volume_map_entry.FindDouble(kKeyLevel);
     CHECK(level);
     CHECK_GE(*level, 0.0);
     CHECK_LE(*level, 1.0);
     CHECK_GT(*level, prev_level);
     prev_level = *level;
 
-    absl::optional<double> db = volume_map_entry.FindDouble(kKeyDb);
+    std::optional<double> db = volume_map_entry.FindDouble(kKeyDb);
     CHECK(db);
     CHECK_LE(*db, 0.0);
 
diff --git a/chromecast/media/cma/backend/volume_map.h b/chromecast/media/cma/backend/volume_map.h
index 4d3bdb9..d5e87b7c 100644
--- a/chromecast/media/cma/backend/volume_map.h
+++ b/chromecast/media/cma/backend/volume_map.h
@@ -36,7 +36,7 @@
 
   float DbFSToVolume(float db);
 
-  void LoadVolumeMap(absl::optional<base::Value::Dict> cast_audio_config);
+  void LoadVolumeMap(std::optional<base::Value::Dict> cast_audio_config);
 
  private:
   struct LevelToDb {
diff --git a/chromecast/media/cma/backend/volume_map_unittest.cc b/chromecast/media/cma/backend/volume_map_unittest.cc
index aa0c3ef..cb85ce2 100644
--- a/chromecast/media/cma/backend/volume_map_unittest.cc
+++ b/chromecast/media/cma/backend/volume_map_unittest.cc
@@ -39,7 +39,7 @@
   }
 
  private:
-  absl::optional<base::Value::Dict> GetCastAudioConfig() override {
+  std::optional<base::Value::Dict> GetCastAudioConfig() override {
     return base::test::ParseJsonDict(file_contents_);
   }
 
diff --git a/chromecast/media/cma/base/decoder_config_adapter.cc b/chromecast/media/cma/base/decoder_config_adapter.cc
index 12f63880..ff5c964 100644
--- a/chromecast/media/cma/base/decoder_config_adapter.cc
+++ b/chromecast/media/cma/base/decoder_config_adapter.cc
@@ -352,7 +352,7 @@
   video_config.matrix = static_cast<MatrixID>(config.color_space_info().matrix);
   video_config.range = static_cast<RangeID>(config.color_space_info().range);
 
-  absl::optional<::gfx::HDRMetadata> hdr_metadata = config.hdr_metadata();
+  std::optional<::gfx::HDRMetadata> hdr_metadata = config.hdr_metadata();
   if (hdr_metadata) {
     video_config.have_hdr_metadata = true;
 
diff --git a/chromecast/media/cma/decoder/cast_audio_decoder.cc b/chromecast/media/cma/decoder/cast_audio_decoder.cc
index a4f0560..75081d4 100644
--- a/chromecast/media/cma/decoder/cast_audio_decoder.cc
+++ b/chromecast/media/cma/decoder/cast_audio_decoder.cc
@@ -10,6 +10,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/containers/queue.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
@@ -30,7 +31,6 @@
 #include "media/base/sample_format.h"
 #include "media/base/status.h"
 #include "media/filters/ffmpeg_audio_decoder.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace chromecast {
 namespace media {
diff --git a/chromecast/media/gpu/cast_gpu_factory_impl.cc b/chromecast/media/gpu/cast_gpu_factory_impl.cc
index cb5b392..e457318 100644
--- a/chromecast/media/gpu/cast_gpu_factory_impl.cc
+++ b/chromecast/media/gpu/cast_gpu_factory_impl.cc
@@ -175,7 +175,7 @@
       request_overlay_info_cb, gfx::ColorSpace::CreateSRGB());
 }
 
-absl::optional<::media::VideoEncodeAccelerator::SupportedProfiles>
+std::optional<::media::VideoEncodeAccelerator::SupportedProfiles>
 CastGpuFactoryImpl::GetVideoEncodeAcceleratorSupportedProfiles() {
   return ::media::VideoEncodeAccelerator::SupportedProfiles();
 }
diff --git a/chromecast/media/gpu/cast_gpu_factory_impl.h b/chromecast/media/gpu/cast_gpu_factory_impl.h
index 1428830..3be4f47 100644
--- a/chromecast/media/gpu/cast_gpu_factory_impl.h
+++ b/chromecast/media/gpu/cast_gpu_factory_impl.h
@@ -63,7 +63,7 @@
   std::unique_ptr<media::VideoDecoder> CreateVideoDecoder(
       ::media::MediaLog* media_log,
       ::media::RequestOverlayInfoCB request_overlay_info_cb) override;
-  absl::optional<media::VideoEncodeAccelerator::SupportedProfiles>
+  std::optional<media::VideoEncodeAccelerator::SupportedProfiles>
   GetVideoEncodeAcceleratorSupportedProfiles() override;
   bool IsEncoderSupportKnown() override;
   void NotifyEncoderSupportKnown(base::OnceClosure) override;
diff --git a/chromecast/media/service/cast_renderer.cc b/chromecast/media/service/cast_renderer.cc
index b7336543..9408c93 100644
--- a/chromecast/media/service/cast_renderer.cc
+++ b/chromecast/media/service/cast_renderer.cc
@@ -348,8 +348,8 @@
   std::move(cdm_attached_cb).Run(true);
 }
 
-void CastRenderer::SetLatencyHint(
-    absl::optional<base::TimeDelta> latency_hint) {}
+void CastRenderer::SetLatencyHint(std::optional<base::TimeDelta> latency_hint) {
+}
 
 void CastRenderer::Flush(base::OnceClosure flush_cb) {
   DCHECK(task_runner_->BelongsToCurrentThread());
diff --git a/chromecast/media/service/cast_renderer.h b/chromecast/media/service/cast_renderer.h
index 8f0963f..7e4398f1 100644
--- a/chromecast/media/service/cast_renderer.h
+++ b/chromecast/media/service/cast_renderer.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 
+#include <optional>
 #include "base/memory/weak_ptr.h"
 #include "base/no_destructor.h"
 #include "base/unguessable_token.h"
@@ -22,7 +23,6 @@
 #include "media/mojo/mojom/frame_interface_factory.mojom.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/rect_f.h"
 #include "ui/gfx/overlay_transform.h"
 
@@ -69,7 +69,7 @@
                   ::media::PipelineStatusCallback init_cb) override;
   void SetCdm(::media::CdmContext* cdm_context,
               CdmAttachedCB cdm_attached_cb) override;
-  void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) override;
+  void SetLatencyHint(std::optional<base::TimeDelta> latency_hint) override;
   void Flush(base::OnceClosure flush_cb) override;
   void StartPlayingFrom(base::TimeDelta time) override;
   void SetPlaybackRate(double playback_rate) override;
@@ -150,7 +150,7 @@
     return *g_overlay_composited_callback;
   }
 
-  absl::optional<float> pending_volume_;
+  std::optional<float> pending_volume_;
 
   const bool is_buffering_enabled_;
 
diff --git a/chromecast/renderer/activity_filtering_websocket_handshake_throttle.cc b/chromecast/renderer/activity_filtering_websocket_handshake_throttle.cc
index 7ebae0a5..6bd75a13 100644
--- a/chromecast/renderer/activity_filtering_websocket_handshake_throttle.cc
+++ b/chromecast/renderer/activity_filtering_websocket_handshake_throttle.cc
@@ -25,7 +25,7 @@
 
   // Pass through allowed URLs, block otherwise.
   if (url_filter_->UrlMatchesWhitelist(gurl)) {
-    std::move(completion_callback).Run(absl::nullopt);
+    std::move(completion_callback).Run(std::nullopt);
     return;
   }
 
diff --git a/chromecast/renderer/cast_content_renderer_client.cc b/chromecast/renderer/cast_content_renderer_client.cc
index 07d3940..f0b5d1c 100644
--- a/chromecast/renderer/cast_content_renderer_client.cc
+++ b/chromecast/renderer/cast_content_renderer_client.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include <optional>
 #include "base/command_line.h"
 #include "base/feature_list.h"
 #include "base/strings/string_number_conversions.h"
@@ -40,7 +41,6 @@
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "services/network/public/cpp/is_potentially_trustworthy.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/browser_interface_broker_proxy.h"
 #include "third_party/blink/public/platform/web_runtime_features.h"
 #include "third_party/blink/public/web/web_frame_widget.h"
@@ -338,7 +338,7 @@
       std::move(throttle_provider));
 }
 
-absl::optional<::media::AudioRendererAlgorithmParameters>
+std::optional<::media::AudioRendererAlgorithmParameters>
 CastContentRendererClient::GetAudioRendererAlgorithmParameters(
     ::media::AudioParameters audio_parameters) {
 #if BUILDFLAG(IS_ANDROID)
@@ -347,9 +347,9 @@
   parameters.starting_capacity = kAudioRendererStartingCapacity;
   parameters.starting_capacity_for_encrypted =
       kAudioRendererStartingCapacityEncrypted;
-  return absl::optional<::media::AudioRendererAlgorithmParameters>(parameters);
+  return std::optional<::media::AudioRendererAlgorithmParameters>(parameters);
 #else
-  return absl::nullopt;
+  return std::nullopt;
 #endif
 }
 
diff --git a/chromecast/renderer/cast_content_renderer_client.h b/chromecast/renderer/cast_content_renderer_client.h
index 78cb57d..c6a3cbb 100644
--- a/chromecast/renderer/cast_content_renderer_client.h
+++ b/chromecast/renderer/cast_content_renderer_client.h
@@ -75,7 +75,7 @@
   std::unique_ptr<blink::URLLoaderThrottleProvider>
   CreateURLLoaderThrottleProvider(
       blink::URLLoaderThrottleProviderType type) override;
-  absl::optional<::media::AudioRendererAlgorithmParameters>
+  std::optional<::media::AudioRendererAlgorithmParameters>
   GetAudioRendererAlgorithmParameters(
       ::media::AudioParameters audio_parameters) override;
 
diff --git a/chromecast/renderer/feature_manager_on_associated_interface.cc b/chromecast/renderer/feature_manager_on_associated_interface.cc
index 34dc5d1..1824f4f 100644
--- a/chromecast/renderer/feature_manager_on_associated_interface.cc
+++ b/chromecast/renderer/feature_manager_on_associated_interface.cc
@@ -57,7 +57,7 @@
       LOG(ERROR) << __func__ << " failed to receive valid app_id";
     }
     bool allow_insecure_content = false;
-    absl::optional<bool> allow_insecure_content_received =
+    std::optional<bool> allow_insecure_content_received =
         feature->config.FindBool(feature::kKeyAllowInsecureContent);
     if (allow_insecure_content_received) {
       allow_insecure_content = *allow_insecure_content_received;
diff --git a/chromecast/renderer/media/key_systems_cast.cc b/chromecast/renderer/media/key_systems_cast.cc
index 8c048c96..15b6fa2 100644
--- a/chromecast/renderer/media/key_systems_cast.cc
+++ b/chromecast/renderer/media/key_systems_cast.cc
@@ -6,6 +6,7 @@
 
 #include <string>
 
+#include <optional>
 #include "base/check.h"
 #include "base/command_line.h"
 #include "build/build_config.h"
@@ -15,7 +16,6 @@
 #include "media/base/eme_constants.h"
 #include "media/base/key_system_info.h"
 #include "media/media_buildflags.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/widevine/cdm/buildflags.h"
 
 #if BUILDFLAG(ENABLE_WIDEVINE)
diff --git a/chromecast/shared/platform_info_serializer.cc b/chromecast/shared/platform_info_serializer.cc
index 77c280ee..20468c3 100644
--- a/chromecast/shared/platform_info_serializer.cc
+++ b/chromecast/shared/platform_info_serializer.cc
@@ -27,13 +27,13 @@
     PlatformInfoSerializer&& other) = default;
 
 // static
-absl::optional<PlatformInfoSerializer> PlatformInfoSerializer::Deserialize(
+std::optional<PlatformInfoSerializer> PlatformInfoSerializer::Deserialize(
     base::StringPiece base64) {
-  absl::optional<cast::bindings::MediaCapabilitiesMessage> proto =
+  std::optional<cast::bindings::MediaCapabilitiesMessage> proto =
       chromecast::bindings::ProtoSerializer<
           cast::bindings::MediaCapabilitiesMessage>::Deserialize(base64);
   if (!proto) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   PlatformInfoSerializer parser;
@@ -184,82 +184,81 @@
   }
 }
 
-absl::optional<int> PlatformInfoSerializer::MaxWidth() const {
+std::optional<int> PlatformInfoSerializer::MaxWidth() const {
   return platform_info_.max_width();
 }
 
-absl::optional<int> PlatformInfoSerializer::MaxHeight() const {
+std::optional<int> PlatformInfoSerializer::MaxHeight() const {
   return platform_info_.max_height();
 }
 
-absl::optional<int> PlatformInfoSerializer::MaxFrameRate() const {
+std::optional<int> PlatformInfoSerializer::MaxFrameRate() const {
   return platform_info_.max_frame_rate();
 }
 
-absl::optional<std::string> PlatformInfoSerializer::SupportedCryptoBlockFormat()
+std::optional<std::string> PlatformInfoSerializer::SupportedCryptoBlockFormat()
     const {
   return platform_info_.supported_cryptoblock_format();
 }
 
-absl::optional<int> PlatformInfoSerializer::MaxChannels() const {
+std::optional<int> PlatformInfoSerializer::MaxChannels() const {
   return platform_info_.max_channels();
 }
 
-absl::optional<bool> PlatformInfoSerializer::PcmSurroundSoundSupported() const {
+std::optional<bool> PlatformInfoSerializer::PcmSurroundSoundSupported() const {
   return platform_info_.is_pcm_surround_sound_supported();
 }
 
-absl::optional<bool> PlatformInfoSerializer::IsPlatformDolbyVisionEnabled()
+std::optional<bool> PlatformInfoSerializer::IsPlatformDolbyVisionEnabled()
     const {
   return platform_info_.is_platform_dolby_vision_enabled();
 }
 
-absl::optional<bool> PlatformInfoSerializer::IsDolbyVisionSupported() const {
+std::optional<bool> PlatformInfoSerializer::IsDolbyVisionSupported() const {
   return platform_info_.is_dolby_vision_supported();
 }
 
-absl::optional<bool> PlatformInfoSerializer::IsDolbyVision4kP60Supported()
+std::optional<bool> PlatformInfoSerializer::IsDolbyVision4kP60Supported()
     const {
   return platform_info_.is_dolby_vision4k_p60_supported();
 }
 
-absl::optional<bool>
+std::optional<bool>
 PlatformInfoSerializer::IsDolbyVisionSupportedByCurrentHdmiMode() const {
   return platform_info_.is_dolby_vision_supported_by_current_hdmi_mode();
 }
 
-absl::optional<bool> PlatformInfoSerializer::IsHdmiVideoModeSwitchEnabled()
+std::optional<bool> PlatformInfoSerializer::IsHdmiVideoModeSwitchEnabled()
     const {
   return platform_info_.is_hdmi_video_mode_switch_enabled();
 }
 
-absl::optional<bool> PlatformInfoSerializer::IsPlatformHevcEnabled() const {
+std::optional<bool> PlatformInfoSerializer::IsPlatformHevcEnabled() const {
   return platform_info_.is_platform_hevc_enabled();
 }
 
-absl::optional<bool> PlatformInfoSerializer::IsHdmiModeHdrCheckEnforced()
-    const {
+std::optional<bool> PlatformInfoSerializer::IsHdmiModeHdrCheckEnforced() const {
   return platform_info_.is_hdmi_mode_hdr_check_enforced();
 }
 
-absl::optional<bool> PlatformInfoSerializer::IsHdrSupportedByCurrentHdmiMode()
+std::optional<bool> PlatformInfoSerializer::IsHdrSupportedByCurrentHdmiMode()
     const {
   return platform_info_.is_hdr_supported_by_current_hdmi_mode();
 }
 
-absl::optional<bool> PlatformInfoSerializer::IsSmpteSt2084Supported() const {
+std::optional<bool> PlatformInfoSerializer::IsSmpteSt2084Supported() const {
   return platform_info_.is_smpte_st2084_supported();
 }
 
-absl::optional<bool> PlatformInfoSerializer::IsHlgSupported() const {
+std::optional<bool> PlatformInfoSerializer::IsHlgSupported() const {
   return platform_info_.is_hlg_supported();
 }
 
-absl::optional<bool> PlatformInfoSerializer::IsHdrFeatureEnabled() const {
+std::optional<bool> PlatformInfoSerializer::IsHdrFeatureEnabled() const {
   return platform_info_.is_hdr_feature_enabled();
 }
 
-absl::optional<std::vector<int>>
+std::optional<std::vector<int>>
 PlatformInfoSerializer::SupportedLegacyVp9Levels() const {
   std::vector<int> levels;
   levels.reserve(platform_info_.supported_legacy_vp9_levels_size());
@@ -270,20 +269,19 @@
   return levels;
 }
 
-absl::optional<int> PlatformInfoSerializer::HdcpVersion() const {
+std::optional<int> PlatformInfoSerializer::HdcpVersion() const {
   return platform_info_.hdcp_version();
 }
 
-absl::optional<int> PlatformInfoSerializer::SpatialRenderingSupportMask()
-    const {
+std::optional<int> PlatformInfoSerializer::SpatialRenderingSupportMask() const {
   return platform_info_.spatial_rendering_support_mask();
 }
 
-absl::optional<int> PlatformInfoSerializer::MaxFillRate() const {
+std::optional<int> PlatformInfoSerializer::MaxFillRate() const {
   return platform_info_.max_fill_rate();
 }
 
-absl::optional<std::vector<PlatformInfoSerializer::AudioCodecInfo>>
+std::optional<std::vector<PlatformInfoSerializer::AudioCodecInfo>>
 PlatformInfoSerializer::SupportedAudioCodecs() const {
   std::vector<AudioCodecInfo> infos;
   infos.reserve(platform_info_.supported_audio_codecs_size());
@@ -311,12 +309,12 @@
   }
 
   return infos.empty()
-             ? absl::nullopt
-             : absl::make_optional<
+             ? std::nullopt
+             : std::make_optional<
                    std::vector<PlatformInfoSerializer::AudioCodecInfo>>(infos);
 }
 
-absl::optional<std::vector<PlatformInfoSerializer::VideoCodecInfo>>
+std::optional<std::vector<PlatformInfoSerializer::VideoCodecInfo>>
 PlatformInfoSerializer::SupportedVideoCodecs() const {
   std::vector<VideoCodecInfo> infos;
   infos.reserve(platform_info_.supported_video_codecs_size());
@@ -340,8 +338,8 @@
   }
 
   return infos.empty()
-             ? absl::nullopt
-             : absl::make_optional<
+             ? std::nullopt
+             : std::make_optional<
                    std::vector<PlatformInfoSerializer::VideoCodecInfo>>(infos);
 }
 
diff --git a/chromecast/shared/platform_info_serializer.h b/chromecast/shared/platform_info_serializer.h
index 5ee3fda..fcb4718 100644
--- a/chromecast/shared/platform_info_serializer.h
+++ b/chromecast/shared/platform_info_serializer.h
@@ -8,9 +8,9 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/strings/string_piece.h"
 #include "chromecast/public/media/decoder_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/cast_core/public/src/proto/bindings/media_capabilities.pb.h"
 
 namespace chromecast {
@@ -42,7 +42,7 @@
   cast::bindings::MediaCapabilitiesMessage* platform_info();
 
   std::string Serialize() const;
-  static absl::optional<PlatformInfoSerializer> Deserialize(
+  static std::optional<PlatformInfoSerializer> Deserialize(
       base::StringPiece base64);
 
   // Setters for known valid properties.
@@ -69,34 +69,34 @@
   void SetSupportedAudioCodecs(std::vector<AudioCodecInfo> codec_infos);
   void SetSupportedVideoCodecs(std::vector<VideoCodecInfo> codec_infos);
 
-  // Getters for the same properties. Returns absl::nullopt if no such value is
+  // Getters for the same properties. Returns std::nullopt if no such value is
   // set, and the set value in all other cases.
-  absl::optional<int> MaxWidth() const;
-  absl::optional<int> MaxHeight() const;
-  absl::optional<int> MaxFrameRate() const;
-  absl::optional<std::string> SupportedCryptoBlockFormat() const;
-  absl::optional<int> MaxChannels() const;
-  absl::optional<bool> PcmSurroundSoundSupported() const;
-  absl::optional<bool> IsPlatformDolbyVisionEnabled() const;
-  absl::optional<bool> IsDolbyVisionSupported() const;
-  absl::optional<bool> IsDolbyVision4kP60Supported() const;
-  absl::optional<bool> IsDolbyVisionSupportedByCurrentHdmiMode() const;
-  absl::optional<bool> IsHdmiVideoModeSwitchEnabled() const;
-  absl::optional<bool> IsPlatformHevcEnabled() const;
-  absl::optional<bool> IsHdmiModeHdrCheckEnforced() const;
-  absl::optional<bool> IsHdrSupportedByCurrentHdmiMode() const;
-  absl::optional<bool> IsSmpteSt2084Supported() const;
-  absl::optional<bool> IsHlgSupported() const;
-  absl::optional<bool> IsHdrFeatureEnabled() const;
-  absl::optional<int> HdcpVersion() const;
-  absl::optional<int> SpatialRenderingSupportMask() const;
-  absl::optional<int> MaxFillRate() const;
-  absl::optional<std::vector<AudioCodecInfo>> SupportedAudioCodecs() const;
-  absl::optional<std::vector<VideoCodecInfo>> SupportedVideoCodecs() const;
+  std::optional<int> MaxWidth() const;
+  std::optional<int> MaxHeight() const;
+  std::optional<int> MaxFrameRate() const;
+  std::optional<std::string> SupportedCryptoBlockFormat() const;
+  std::optional<int> MaxChannels() const;
+  std::optional<bool> PcmSurroundSoundSupported() const;
+  std::optional<bool> IsPlatformDolbyVisionEnabled() const;
+  std::optional<bool> IsDolbyVisionSupported() const;
+  std::optional<bool> IsDolbyVision4kP60Supported() const;
+  std::optional<bool> IsDolbyVisionSupportedByCurrentHdmiMode() const;
+  std::optional<bool> IsHdmiVideoModeSwitchEnabled() const;
+  std::optional<bool> IsPlatformHevcEnabled() const;
+  std::optional<bool> IsHdmiModeHdrCheckEnforced() const;
+  std::optional<bool> IsHdrSupportedByCurrentHdmiMode() const;
+  std::optional<bool> IsSmpteSt2084Supported() const;
+  std::optional<bool> IsHlgSupported() const;
+  std::optional<bool> IsHdrFeatureEnabled() const;
+  std::optional<int> HdcpVersion() const;
+  std::optional<int> SpatialRenderingSupportMask() const;
+  std::optional<int> MaxFillRate() const;
+  std::optional<std::vector<AudioCodecInfo>> SupportedAudioCodecs() const;
+  std::optional<std::vector<VideoCodecInfo>> SupportedVideoCodecs() const;
 
   // Deprecated fields.
   void SetSupportedLegacyVp9Levels(std::vector<int> levels);
-  absl::optional<std::vector<int>> SupportedLegacyVp9Levels() const;
+  std::optional<std::vector<int>> SupportedLegacyVp9Levels() const;
 
  private:
   // All currently produced values.
diff --git a/chromecast/shared/platform_info_serializer_unittest.cc b/chromecast/shared/platform_info_serializer_unittest.cc
index 60f4e16..661720e 100644
--- a/chromecast/shared/platform_info_serializer_unittest.cc
+++ b/chromecast/shared/platform_info_serializer_unittest.cc
@@ -12,7 +12,7 @@
 PlatformInfoSerializer ConvertAndValidate(
     const PlatformInfoSerializer& parser) {
   std::string base64 = parser.Serialize();
-  absl::optional<PlatformInfoSerializer> deserialized_parser =
+  std::optional<PlatformInfoSerializer> deserialized_parser =
       PlatformInfoSerializer::Deserialize(base64);
   EXPECT_TRUE(deserialized_parser);
   EXPECT_EQ(parser.Serialize(), deserialized_parser->Serialize());
diff --git a/codelabs/cpp101/solutions/factor.cc b/codelabs/cpp101/solutions/factor.cc
index b937563..3372918 100644
--- a/codelabs/cpp101/solutions/factor.cc
+++ b/codelabs/cpp101/solutions/factor.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <optional>
 #include "base/at_exit.h"
 #include "base/command_line.h"
 #include "base/functional/bind.h"
@@ -12,21 +13,20 @@
 #include "base/test/task_environment.h"
 #include "base/test/test_timeouts.h"
 #include "base/time/time.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
-absl::optional<int> FindNonTrivialFactor(int n) {
+std::optional<int> FindNonTrivialFactor(int n) {
   // Really naive algorithm.
   for (int i = 2; i < n; ++i) {
     if (n % i == 0) {
       return i;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-void FindNonTrivialFactorHelper(int n, absl::optional<int>* result) {
+void FindNonTrivialFactorHelper(int n, std::optional<int>* result) {
   *result = FindNonTrivialFactor(n);
 }
 
@@ -66,7 +66,7 @@
 
   base::RunLoop run_loop;
 
-  absl::optional<int> result;
+  std::optional<int> result;
   // Notice that we're posting the long-running factoring operation to
   // `base::ThreadPool` to avoid blocking the main thread.
   //
diff --git a/components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_utils.h b/components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_utils.h
index bdc5bb04..019dbca 100644
--- a/components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_utils.h
+++ b/components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_utils.h
@@ -5,6 +5,8 @@
 #ifndef COMPONENTS_SAFE_BROWSING_CORE_BROWSER_HASHPREFIX_REALTIME_HASH_REALTIME_UTILS_H_
 #define COMPONENTS_SAFE_BROWSING_CORE_BROWSER_HASHPREFIX_REALTIME_HASH_REALTIME_UTILS_H_
 
+#include <optional>
+
 #include "components/safe_browsing/core/common/proto/safebrowsingv5.pb.h"
 #include "services/network/public/mojom/fetch_api.mojom.h"
 #include "url/gurl.h"
@@ -76,17 +78,17 @@
 // Based on the user's browser session and location, specifies whether
 // hash-prefix real-time lookups are eligible. Outside of tests,
 // |stored_permanent_country| should be determined with the helper function
-// |hash_realtime_utils::GetCountryCode|. If it's passed in as absl::nullopt,
+// |hash_realtime_utils::GetCountryCode|. If it's passed in as std::nullopt,
 // the location is considered eligible.
 bool IsHashRealTimeLookupEligibleInSessionAndLocation(
-    absl::optional<std::string> stored_permanent_country);
+    std::optional<std::string> stored_permanent_country);
 
 // Returns the stored permanent country. If |variations_service| is null,
-// returns absl::nullopt. This should be used only as a helper to determine the
+// returns std::nullopt. This should be used only as a helper to determine the
 // country code to pass into |IsHashRealTimeLookupEligibleInSessionAndLocation|
 // and |DetermineHashRealTimeSelection|. This is separated out into a function
 // to simplify tests.
-absl::optional<std::string> GetCountryCode(
+std::optional<std::string> GetCountryCode(
     variations::VariationsService* variations_service);
 
 // Based on the user's settings and session, determines which hash-prefix
@@ -94,11 +96,11 @@
 // this will log metrics related to whether hash real-time lookups were
 // available or why not. Outside of tests, |stored_permanent_country| should be
 // determined with the helper function |hash_realtime_utils::GetCountryCode|.
-// If it's passed in as absl::nullopt, the location is considered eligible.
+// If it's passed in as std::nullopt, the location is considered eligible.
 HashRealTimeSelection DetermineHashRealTimeSelection(
     bool is_off_the_record,
     PrefService* prefs,
-    absl::optional<std::string> stored_permanent_country,
+    std::optional<std::string> stored_permanent_country,
     bool log_usage_histograms = false);
 
 // A helper for consumers that want to recompute
diff --git a/components/services/storage/sandboxed_vfs_delegate.cc b/components/services/storage/sandboxed_vfs_delegate.cc
index 1bb53636..cb87156 100644
--- a/components/services/storage/sandboxed_vfs_delegate.cc
+++ b/components/services/storage/sandboxed_vfs_delegate.cc
@@ -7,11 +7,11 @@
 #include <cstdint>
 #include <utility>
 
+#include <optional>
 #include "base/files/file.h"
 #include "base/files/file_error_or.h"
 #include "base/files/file_path.h"
 #include "components/services/storage/public/cpp/filesystem/filesystem_proxy.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace storage {
 
@@ -34,12 +34,12 @@
   return filesystem_->DeleteFile(file_path) ? SQLITE_OK : SQLITE_IOERR_DELETE;
 }
 
-absl::optional<sql::SandboxedVfs::PathAccessInfo>
+std::optional<sql::SandboxedVfs::PathAccessInfo>
 SandboxedVfsDelegate::GetPathAccess(const base::FilePath& file_path) {
-  absl::optional<FilesystemProxy::PathAccessInfo> info =
+  std::optional<FilesystemProxy::PathAccessInfo> info =
       filesystem_->GetPathAccess(file_path);
   if (!info)
-    return absl::nullopt;
+    return std::nullopt;
 
   sql::SandboxedVfs::PathAccessInfo access;
   access.can_read = info->can_read;
diff --git a/components/services/storage/sandboxed_vfs_delegate.h b/components/services/storage/sandboxed_vfs_delegate.h
index 206a28f..9535f8b4 100644
--- a/components/services/storage/sandboxed_vfs_delegate.h
+++ b/components/services/storage/sandboxed_vfs_delegate.h
@@ -21,7 +21,7 @@
   // sql::SandboxedVfs::Delegate implementation:
   base::File OpenFile(const base::FilePath& file_path,
                       int sqlite_requested_flags) override;
-  absl::optional<sql::SandboxedVfs::PathAccessInfo> GetPathAccess(
+  std::optional<sql::SandboxedVfs::PathAccessInfo> GetPathAccess(
       const base::FilePath& file_path) override;
   int DeleteFile(const base::FilePath& file_path, bool sync_dir) override;
   bool SetFileLength(const base::FilePath& file_path,
diff --git a/components/signin/public/base/signin_client.h b/components/signin/public/base/signin_client.h
index 398b2a1..3c79a90 100644
--- a/components/signin/public/base/signin_client.h
+++ b/components/signin/public/base/signin_client.h
@@ -6,6 +6,7 @@
 #define COMPONENTS_SIGNIN_PUBLIC_BASE_SIGNIN_CLIENT_H_
 
 #include <memory>
+#include <optional>
 
 #include "base/callback_list.h"
 #include "base/functional/callback.h"
@@ -23,7 +24,6 @@
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
 #include "components/account_manager_core/account.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #endif
 
 class PrefService;
@@ -126,12 +126,12 @@
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
   // Returns an account used to sign into Chrome OS session if available.
-  virtual absl::optional<account_manager::Account>
+  virtual std::optional<account_manager::Account>
   GetInitialPrimaryAccount() = 0;
 
   // Returns whether account used to sign into Chrome OS is a child account.
   // Returns nullopt for secondary / non-main profiles in LaCrOS.
-  virtual absl::optional<bool> IsInitialPrimaryAccountChild() const = 0;
+  virtual std::optional<bool> IsInitialPrimaryAccountChild() const = 0;
 
   // Remove account.
   virtual void RemoveAccount(
@@ -153,7 +153,7 @@
           event_source) = 0;
 
  protected:
-  absl::optional<SignoutDecision> is_clear_primary_account_allowed_for_testing_;
+  std::optional<SignoutDecision> is_clear_primary_account_allowed_for_testing_;
 };
 
 namespace base {
diff --git a/components/sync/invalidations/fcm_handler.h b/components/sync/invalidations/fcm_handler.h
index 16779b8..85ffdadc 100644
--- a/components/sync/invalidations/fcm_handler.h
+++ b/components/sync/invalidations/fcm_handler.h
@@ -5,6 +5,7 @@
 #ifndef COMPONENTS_SYNC_INVALIDATIONS_FCM_HANDLER_H_
 #define COMPONENTS_SYNC_INVALIDATIONS_FCM_HANDLER_H_
 
+#include <optional>
 #include <string>
 
 #include "base/containers/circular_deque.h"
@@ -78,7 +79,7 @@
   void RemoveTokenObserver(FCMRegistrationTokenObserver* observer);
 
   // Used to get an obtained FCM token. Returns null if it doesn't have a token.
-  const absl::optional<std::string>& GetFCMRegistrationToken() const;
+  const std::optional<std::string>& GetFCMRegistrationToken() const;
 
   // GCMAppHandler overrides.
   void ShutdownHandler() override;
@@ -111,7 +112,7 @@
 
   // Contains an FCM registration token. Token is null if the experiment is off
   // or we don't have a valid token yet and contains valid token otherwise.
-  absl::optional<std::string> fcm_registration_token_;
+  std::optional<std::string> fcm_registration_token_;
 
   base::OneShotTimer token_validation_timer_;
 
diff --git a/content/browser/preloading/prefetch/prefetch_streaming_url_loader_common_types.h b/content/browser/preloading/prefetch/prefetch_streaming_url_loader_common_types.h
index 9252c7d3..70edd64a 100644
--- a/content/browser/preloading/prefetch/prefetch_streaming_url_loader_common_types.h
+++ b/content/browser/preloading/prefetch/prefetch_streaming_url_loader_common_types.h
@@ -5,6 +5,7 @@
 #ifndef CONTENT_BROWSER_PRELOADING_PREFETCH_PREFETCH_STREAMING_URL_LOADER_COMMON_TYPES_H_
 #define CONTENT_BROWSER_PRELOADING_PREFETCH_PREFETCH_STREAMING_URL_LOADER_COMMON_TYPES_H_
 
+#include <optional>
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "services/network/public/mojom/url_loader.mojom-forward.h"
@@ -76,7 +77,7 @@
 
 // This callback is used by the owner to determine if the prefetch is valid
 // based on |head|. If the prefetch should be servable based on |head|, then
-// the callback should return `absl::nullopt`. Otherwise it should return a
+// the callback should return `std::nullopt`. Otherwise it should return a
 // failure reason.
 enum class PrefetchErrorOnResponseReceived {
   kPrefetchWasDecoy,
@@ -86,7 +87,7 @@
   kFailedMIMENotSupported
 };
 using >
-    base::OnceCallback<absl::optional<PrefetchErrorOnResponseReceived>(
+    base::OnceCallback<std::optional<PrefetchErrorOnResponseReceived>(
         network::mojom::URLResponseHead* head)>;
 
 using >
diff --git a/content/browser/utility_sandbox_delegate.h b/content/browser/utility_sandbox_delegate.h
index 49b9f842..0e07a97 100644
--- a/content/browser/utility_sandbox_delegate.h
+++ b/content/browser/utility_sandbox_delegate.h
@@ -5,6 +5,7 @@
 #ifndef CONTENT_BROWSER_UTILITY_SANDBOX_DELEGATE_H_
 #define CONTENT_BROWSER_UTILITY_SANDBOX_DELEGATE_H_
 
+#include <optional>
 #include "base/command_line.h"
 #include "base/environment.h"
 #include "base/files/file_path.h"
@@ -73,7 +74,7 @@
 #endif  // BUILDFLAG(IS_WIN)
 
 #if BUILDFLAG(USE_ZYGOTE)
-  absl::optional<raw_ptr<ZygoteCommunication>> zygote_;
+  std::optional<raw_ptr<ZygoteCommunication>> zygote_;
 #endif  // BUILDFLAG(USE_ZYGOTE)
 
   sandbox::mojom::Sandbox sandbox_type_;
diff --git a/content/public/test/permissions_test_utils.h b/content/public/test/permissions_test_utils.h
index 0f17e27..f64eaa1 100644
--- a/content/public/test/permissions_test_utils.h
+++ b/content/public/test/permissions_test_utils.h
@@ -5,6 +5,7 @@
 #ifndef CONTENT_PUBLIC_TEST_PERMISSIONS_TEST_UTILS_H_
 #define CONTENT_PUBLIC_TEST_PERMISSIONS_TEST_UTILS_H_
 
+#include <optional>
 #include "third_party/blink/public/mojom/permissions/permission_status.mojom.h"
 
 namespace blink {
@@ -21,7 +22,7 @@
 
 void SetPermissionControllerOverrideForDevTools(
     PermissionController* permission_controller,
-    const absl::optional<url::Origin>& origin,
+    const std::optional<url::Origin>& origin,
     blink::PermissionType permission,
     const blink::mojom::PermissionStatus& status);
 
diff --git a/crypto/aead.cc b/crypto/aead.cc
index b3b26d9..b0845c307 100644
--- a/crypto/aead.cc
+++ b/crypto/aead.cc
@@ -87,7 +87,7 @@
   return true;
 }
 
-absl::optional<std::vector<uint8_t>> Aead::Open(
+std::optional<std::vector<uint8_t>> Aead::Open(
     base::span<const uint8_t> ciphertext,
     base::span<const uint8_t> nonce,
     base::span<const uint8_t> additional_data) const {
@@ -98,7 +98,7 @@
   size_t output_length;
   if (!Open(ciphertext, nonce, additional_data, ret.data(), &output_length,
             max_output_length)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   ret.resize(output_length);
diff --git a/crypto/aead.h b/crypto/aead.h
index 9a0c7061..0bfe4721 100644
--- a/crypto/aead.h
+++ b/crypto/aead.h
@@ -12,10 +12,10 @@
 #include <string_view>
 #include <vector>
 
+#include <optional>
 #include "base/containers/span.h"
 #include "base/memory/raw_ptr.h"
 #include "crypto/crypto_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 struct evp_aead_st;
 
@@ -56,7 +56,7 @@
             std::string_view additional_data,
             std::string* ciphertext) const;
 
-  absl::optional<std::vector<uint8_t>> Open(
+  std::optional<std::vector<uint8_t>> Open(
       base::span<const uint8_t> ciphertext,
       base::span<const uint8_t> nonce,
       base::span<const uint8_t> additional_data) const;
@@ -85,7 +85,7 @@
             size_t* output_length,
             size_t max_output_length) const;
 
-  absl::optional<base::span<const uint8_t>> key_;
+  std::optional<base::span<const uint8_t>> key_;
   raw_ptr<const evp_aead_st> aead_;
 };
 
diff --git a/crypto/aead_unittest.cc b/crypto/aead_unittest.cc
index 4f9a1c4..fc8a423 100644
--- a/crypto/aead_unittest.cc
+++ b/crypto/aead_unittest.cc
@@ -51,7 +51,7 @@
       aead.Seal(kPlaintext, nonce, kAdditionalData);
   EXPECT_LT(sizeof(kPlaintext), ciphertext.size());
 
-  absl::optional<std::vector<uint8_t>> decrypted =
+  std::optional<std::vector<uint8_t>> decrypted =
       aead.Open(ciphertext, nonce, kAdditionalData);
   ASSERT_TRUE(decrypted);
   ASSERT_EQ(decrypted->size(), sizeof(kPlaintext));
diff --git a/crypto/apple_keychain.h b/crypto/apple_keychain.h
index c248cb6..ebb7915d 100644
--- a/crypto/apple_keychain.h
+++ b/crypto/apple_keychain.h
@@ -7,9 +7,9 @@
 
 #include <Security/Security.h>
 
+#include <optional>
 #include "build/build_config.h"
 #include "crypto/crypto_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace crypto {
 
@@ -79,7 +79,7 @@
   ~ScopedKeychainUserInteractionAllowed();
 
  private:
-  absl::optional<Boolean> was_allowed_;
+  std::optional<Boolean> was_allowed_;
 };
 
 #endif  // BUILDFLAG(IS_MAC)
diff --git a/crypto/encryptor.cc b/crypto/encryptor.cc
index 46e3be0..0677147 100644
--- a/crypto/encryptor.cc
+++ b/crypto/encryptor.cc
@@ -99,7 +99,7 @@
                             std::string_view input,
                             std::string* output) {
   std::string result(MaxOutput(do_encrypt, input.size()), '\0');
-  absl::optional<size_t> len =
+  std::optional<size_t> len =
       (mode_ == CTR)
           ? CryptCTR(do_encrypt, base::as_bytes(base::make_span(input)),
                      base::as_writable_bytes(base::make_span(result)))
@@ -117,9 +117,9 @@
                            base::span<const uint8_t> input,
                            std::vector<uint8_t>* output) {
   std::vector<uint8_t> result(MaxOutput(do_encrypt, input.size()));
-  absl::optional<size_t> len = (mode_ == CTR)
-                                   ? CryptCTR(do_encrypt, input, result)
-                                   : Crypt(do_encrypt, input, result);
+  std::optional<size_t> len = (mode_ == CTR)
+                                  ? CryptCTR(do_encrypt, input, result)
+                                  : Crypt(do_encrypt, input, result);
   if (!len)
     return false;
 
@@ -134,9 +134,9 @@
   return result;
 }
 
-absl::optional<size_t> Encryptor::Crypt(bool do_encrypt,
-                                        base::span<const uint8_t> input,
-                                        base::span<uint8_t> output) {
+std::optional<size_t> Encryptor::Crypt(bool do_encrypt,
+                                       base::span<const uint8_t> input,
+                                       base::span<uint8_t> output) {
   DCHECK(key_);  // Must call Init() before En/De-crypt.
 
   const EVP_CIPHER* cipher = GetCipherForKey(key_);
@@ -151,7 +151,7 @@
   if (!EVP_CipherInit_ex(ctx.get(), cipher, nullptr,
                          reinterpret_cast<const uint8_t*>(key.data()),
                          iv_.data(), do_encrypt)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Encrypting needs a block size of space to allow for any padding.
@@ -159,31 +159,31 @@
   int out_len;
   if (!EVP_CipherUpdate(ctx.get(), output.data(), &out_len, input.data(),
                         input.size()))
-    return absl::nullopt;
+    return std::nullopt;
 
   // Write out the final block plus padding (if any) to the end of the data
   // just written.
   int tail_len;
   if (!EVP_CipherFinal_ex(ctx.get(), output.data() + out_len, &tail_len))
-    return absl::nullopt;
+    return std::nullopt;
 
   out_len += tail_len;
   DCHECK_LE(out_len, static_cast<int>(output.size()));
   return out_len;
 }
 
-absl::optional<size_t> Encryptor::CryptCTR(bool do_encrypt,
-                                           base::span<const uint8_t> input,
-                                           base::span<uint8_t> output) {
+std::optional<size_t> Encryptor::CryptCTR(bool do_encrypt,
+                                          base::span<const uint8_t> input,
+                                          base::span<uint8_t> output) {
   if (iv_.size() != AES_BLOCK_SIZE) {
     LOG(ERROR) << "Counter value not set in CTR mode.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   AES_KEY aes_key;
   if (AES_set_encrypt_key(reinterpret_cast<const uint8_t*>(key_->key().data()),
                           key_->key().size() * 8, &aes_key) != 0) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   uint8_t ecount_buf[AES_BLOCK_SIZE] = { 0 };
diff --git a/crypto/encryptor.h b/crypto/encryptor.h
index 88ebb88..ee77f4b 100644
--- a/crypto/encryptor.h
+++ b/crypto/encryptor.h
@@ -12,11 +12,11 @@
 #include <string>
 #include <string_view>
 
+#include <optional>
 #include "base/containers/span.h"
 #include "base/memory/raw_ptr.h"
 #include "build/build_config.h"
 #include "crypto/crypto_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace crypto {
 
@@ -86,12 +86,12 @@
   // On success, these helper functions return the number of bytes written to
   // |output|.
   size_t MaxOutput(bool do_encrypt, size_t length);
-  absl::optional<size_t> Crypt(bool do_encrypt,
-                               base::span<const uint8_t> input,
-                               base::span<uint8_t> output);
-  absl::optional<size_t> CryptCTR(bool do_encrypt,
-                                  base::span<const uint8_t> input,
-                                  base::span<uint8_t> output);
+  std::optional<size_t> Crypt(bool do_encrypt,
+                              base::span<const uint8_t> input,
+                              base::span<uint8_t> output);
+  std::optional<size_t> CryptCTR(bool do_encrypt,
+                                 base::span<const uint8_t> input,
+                                 base::span<uint8_t> output);
 
   // In CBC mode, the IV passed to Init(). In CTR mode, the counter value passed
   // to SetCounter().
diff --git a/crypto/unexportable_key.h b/crypto/unexportable_key.h
index 63acf4b6..f4aa85a 100644
--- a/crypto/unexportable_key.h
+++ b/crypto/unexportable_key.h
@@ -7,9 +7,9 @@
 
 #include <memory>
 
+#include <optional>
 #include "crypto/crypto_export.h"
 #include "crypto/signature_verifier.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace crypto {
 
@@ -50,7 +50,7 @@
   // during signing.
   //
   // Note: this may take a second or more to run.
-  virtual absl::optional<std::vector<uint8_t>> SignSlowly(
+  virtual std::optional<std::vector<uint8_t>> SignSlowly(
       base::span<const uint8_t> data) = 0;
 };
 
@@ -62,7 +62,7 @@
   // SelectAlgorithm returns which signature algorithm from
   // |acceptable_algorithms| would be used if |acceptable_algorithms| was passed
   // to |GenerateSigningKeySlowly|.
-  virtual absl::optional<SignatureVerifier::SignatureAlgorithm> SelectAlgorithm(
+  virtual std::optional<SignatureVerifier::SignatureAlgorithm> SelectAlgorithm(
       base::span<const SignatureVerifier::SignatureAlgorithm>
           acceptable_algorithms) = 0;
 
@@ -133,7 +133,7 @@
   // during signing.
   //
   // Note: this is expected to be under 10ms.
-  virtual absl::optional<std::vector<uint8_t>> Sign(
+  virtual std::optional<std::vector<uint8_t>> Sign(
       base::span<const uint8_t> data) = 0;
 
   // Deletes the key from storage in the virtual machine. As the virtual machine
@@ -150,7 +150,7 @@
   // SelectAlgorithm returns which signature algorithm from
   // |acceptable_algorithms| would be used if |acceptable_algorithms| was passed
   // to |GenerateSigningKeySlowly|.
-  virtual absl::optional<SignatureVerifier::SignatureAlgorithm> SelectAlgorithm(
+  virtual std::optional<SignatureVerifier::SignatureAlgorithm> SelectAlgorithm(
       base::span<const SignatureVerifier::SignatureAlgorithm>
           acceptable_algorithms) = 0;
 
diff --git a/crypto/unexportable_key_metrics.cc b/crypto/unexportable_key_metrics.cc
index 2b4b9a95..6624242 100644
--- a/crypto/unexportable_key_metrics.cc
+++ b/crypto/unexportable_key_metrics.cc
@@ -177,7 +177,7 @@
 
   const uint8_t msg[] = {1, 2, 3, 4};
   base::ElapsedTimer message_signing_timer;
-  absl::optional<std::vector<uint8_t>> signed_bytes = current_key->Sign(msg);
+  std::optional<std::vector<uint8_t>> signed_bytes = current_key->Sign(msg);
   ReportUmaTpmOperation(TPMOperation::kMessageSigning, supported_virtual_algo,
                         message_signing_timer.Elapsed(),
                         signed_bytes.has_value(), KeyType::kVirtualizedKey);
@@ -257,7 +257,7 @@
 
   const uint8_t msg[] = {1, 2, 3, 4};
   base::ElapsedTimer message_signing_timer;
-  absl::optional<std::vector<uint8_t>> signed_bytes =
+  std::optional<std::vector<uint8_t>> signed_bytes =
       current_key->SignSlowly(msg);
   ReportUmaTpmOperation(TPMOperation::kMessageSigning, supported_algo,
                         message_signing_timer.Elapsed(),
diff --git a/crypto/unexportable_key_software_unsecure.cc b/crypto/unexportable_key_software_unsecure.cc
index 64ca3f0..e6167ec 100644
--- a/crypto/unexportable_key_software_unsecure.cc
+++ b/crypto/unexportable_key_software_unsecure.cc
@@ -50,7 +50,7 @@
     return CBBToVector(cbb.get());
   }
 
-  absl::optional<std::vector<uint8_t>> SignSlowly(
+  std::optional<std::vector<uint8_t>> SignSlowly(
       base::span<const uint8_t> data) override {
     std::vector<uint8_t> ret(ECDSA_size(key_.get()));
     std::array<uint8_t, kSHA256Length> digest = SHA256Hash(data);
@@ -69,7 +69,7 @@
  public:
   ~SoftwareProvider() override = default;
 
-  absl::optional<SignatureVerifier::SignatureAlgorithm> SelectAlgorithm(
+  std::optional<SignatureVerifier::SignatureAlgorithm> SelectAlgorithm(
       base::span<const SignatureVerifier::SignatureAlgorithm>
           acceptable_algorithms) override {
     for (auto algo : acceptable_algorithms) {
@@ -78,7 +78,7 @@
       }
     }
 
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   std::unique_ptr<UnexportableSigningKey> GenerateSigningKeySlowly(
diff --git a/crypto/unexportable_key_unittest.cc b/crypto/unexportable_key_unittest.cc
index 85c97df0..4b29336 100644
--- a/crypto/unexportable_key_unittest.cc
+++ b/crypto/unexportable_key_unittest.cc
@@ -6,11 +6,11 @@
 
 #include <tuple>
 
+#include <optional>
 #include "base/logging.h"
 #include "base/time/time.h"
 #include "crypto/scoped_mock_unexportable_key_provider.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -47,7 +47,7 @@
   SCOPED_TRACE(static_cast<int>(algo));
   SCOPED_TRACE(mock_enabled);
 
-  absl::optional<crypto::ScopedMockUnexportableKeyProvider> mock;
+  std::optional<crypto::ScopedMockUnexportableKeyProvider> mock;
   if (mock_enabled) {
     mock.emplace();
   }
@@ -78,7 +78,7 @@
   const uint8_t msg[] = {1, 2, 3, 4};
 
   const base::TimeTicks sign_start = base::TimeTicks::Now();
-  const absl::optional<std::vector<uint8_t>> sig = key->SignSlowly(msg);
+  const std::optional<std::vector<uint8_t>> sig = key->SignSlowly(msg);
   LOG(INFO) << "Signing took " << (base::TimeTicks::Now() - sign_start);
   ASSERT_TRUE(sig);
 
@@ -94,7 +94,7 @@
   LOG(INFO) << "Import took " << (base::TimeTicks::Now() - import2_start);
 
   const base::TimeTicks sign2_start = base::TimeTicks::Now();
-  const absl::optional<std::vector<uint8_t>> sig2 = key->SignSlowly(msg);
+  const std::optional<std::vector<uint8_t>> sig2 = key->SignSlowly(msg);
   LOG(INFO) << "Signing took " << (base::TimeTicks::Now() - sign2_start);
   ASSERT_TRUE(sig2);
 
diff --git a/crypto/unexportable_key_win.cc b/crypto/unexportable_key_win.cc
index 58d1441..7e39e10 100644
--- a/crypto/unexportable_key_win.cc
+++ b/crypto/unexportable_key_win.cc
@@ -49,7 +49,7 @@
 
 // BCryptAlgorithmFor returns the BCrypt algorithm ID for the given Chromium
 // signing algorithm.
-absl::optional<LPCWSTR> BCryptAlgorithmFor(
+std::optional<LPCWSTR> BCryptAlgorithmFor(
     SignatureVerifier::SignatureAlgorithm algo) {
   switch (algo) {
     case SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA256:
@@ -59,18 +59,18 @@
       return BCRYPT_ECDSA_P256_ALGORITHM;
 
     default:
-      return absl::nullopt;
+      return std::nullopt;
   }
 }
 
 // GetBestSupported returns the first element of |acceptable_algorithms| that
 // |provider| supports, or |nullopt| if there isn't any.
-absl::optional<SignatureVerifier::SignatureAlgorithm> GetBestSupported(
+std::optional<SignatureVerifier::SignatureAlgorithm> GetBestSupported(
     NCRYPT_PROV_HANDLE provider,
     base::span<const SignatureVerifier::SignatureAlgorithm>
         acceptable_algorithms) {
   for (auto algo : acceptable_algorithms) {
-    absl::optional<LPCWSTR> bcrypto_algo_name = BCryptAlgorithmFor(algo);
+    std::optional<LPCWSTR> bcrypto_algo_name = BCryptAlgorithmFor(algo);
     if (!bcrypto_algo_name) {
       continue;
     }
@@ -82,22 +82,22 @@
     }
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 // GetKeyProperty returns the given NCrypt key property of |key|.
-absl::optional<std::vector<uint8_t>> GetKeyProperty(NCRYPT_KEY_HANDLE key,
-                                                    LPCWSTR property) {
+std::optional<std::vector<uint8_t>> GetKeyProperty(NCRYPT_KEY_HANDLE key,
+                                                   LPCWSTR property) {
   SCOPED_MAY_LOAD_LIBRARY_AT_BACKGROUND_PRIORITY();
   DWORD size;
   if (FAILED(NCryptGetProperty(key, property, nullptr, 0, &size, 0))) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   std::vector<uint8_t> ret(size);
   if (FAILED(
           NCryptGetProperty(key, property, ret.data(), ret.size(), &size, 0))) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   CHECK_EQ(ret.size(), size);
 
@@ -105,30 +105,30 @@
 }
 
 // ExportKey returns |key| exported in the given format or nullopt on error.
-absl::optional<std::vector<uint8_t>> ExportKey(NCRYPT_KEY_HANDLE key,
-                                               LPCWSTR format) {
+std::optional<std::vector<uint8_t>> ExportKey(NCRYPT_KEY_HANDLE key,
+                                              LPCWSTR format) {
   SCOPED_MAY_LOAD_LIBRARY_AT_BACKGROUND_PRIORITY();
   DWORD output_size;
   if (FAILED(NCryptExportKey(key, 0, format, nullptr, nullptr, 0, &output_size,
                              0))) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   std::vector<uint8_t> output(output_size);
   if (FAILED(NCryptExportKey(key, 0, format, nullptr, output.data(),
                              output.size(), &output_size, 0))) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   CHECK_EQ(output.size(), output_size);
 
   return output;
 }
 
-absl::optional<std::vector<uint8_t>> GetP256ECDSASPKI(NCRYPT_KEY_HANDLE key) {
-  const absl::optional<std::vector<uint8_t>> pub_key =
+std::optional<std::vector<uint8_t>> GetP256ECDSASPKI(NCRYPT_KEY_HANDLE key) {
+  const std::optional<std::vector<uint8_t>> pub_key =
       ExportKey(key, BCRYPT_ECCPUBLIC_BLOB);
   if (!pub_key) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // The exported key is a |BCRYPT_ECCKEY_BLOB| followed by the bytes of the
@@ -136,7 +136,7 @@
   // https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/ns-bcrypt-bcrypt_ecckey_blob
   BCRYPT_ECCKEY_BLOB header;
   if (pub_key->size() < sizeof(header)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   memcpy(&header, pub_key->data(), sizeof(header));
   // |cbKey| is documented[1] as "the length, in bytes, of the key". It is
@@ -145,23 +145,23 @@
        header.dwMagic != BCRYPT_ECDSA_PUBLIC_GENERIC_MAGIC) ||
       header.cbKey != 256 / 8 ||
       pub_key->size() - sizeof(BCRYPT_ECCKEY_BLOB) != 64) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Sometimes NCrypt will return a generic dwMagic even when asked for a P-256
   // key. In that case, do extra validation to make sure that `key` is in fact
   // a P-256 key.
   if (header.dwMagic == BCRYPT_ECDSA_PUBLIC_GENERIC_MAGIC) {
-    const absl::optional<std::vector<uint8_t>> curve_name =
+    const std::optional<std::vector<uint8_t>> curve_name =
         GetKeyProperty(key, NCRYPT_ECC_CURVE_NAME_PROPERTY);
     if (!curve_name) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     if (curve_name->size() != sizeof(BCRYPT_ECC_CURVE_NISTP256) ||
         memcmp(curve_name->data(), BCRYPT_ECC_CURVE_NISTP256,
                sizeof(BCRYPT_ECC_CURVE_NISTP256)) != 0) {
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
 
@@ -174,7 +174,7 @@
   bssl::UniquePtr<EC_POINT> point(EC_POINT_new(p256.get()));
   if (!EC_POINT_oct2point(p256.get(), point.get(), x962, sizeof(x962),
                           /*ctx=*/nullptr)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   bssl::UniquePtr<EC_KEY> ec_key(
       EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
@@ -188,11 +188,11 @@
   return CBBToVector(cbb.get());
 }
 
-absl::optional<std::vector<uint8_t>> GetRSASPKI(NCRYPT_KEY_HANDLE key) {
-  const absl::optional<std::vector<uint8_t>> pub_key =
+std::optional<std::vector<uint8_t>> GetRSASPKI(NCRYPT_KEY_HANDLE key) {
+  const std::optional<std::vector<uint8_t>> pub_key =
       ExportKey(key, BCRYPT_RSAPUBLIC_BLOB);
   if (!pub_key) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // The exported key is a |BCRYPT_RSAKEY_BLOB| followed by the bytes of the
@@ -200,11 +200,11 @@
   // https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/ns-bcrypt-bcrypt_rsakey_blob
   BCRYPT_RSAKEY_BLOB header;
   if (pub_key->size() < sizeof(header)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   memcpy(&header, pub_key->data(), sizeof(header));
   if (header.Magic != static_cast<ULONG>(BCRYPT_RSAPUBLIC_MAGIC)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   size_t bytes_needed;
@@ -212,7 +212,7 @@
                       base::CheckAdd(header.cbPublicExp, header.cbModulus))
            .AssignIfValid(&bytes_needed) ||
       pub_key->size() < bytes_needed) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   bssl::UniquePtr<BIGNUM> e(
@@ -233,8 +233,8 @@
   return CBBToVector(cbb.get());
 }
 
-absl::optional<std::vector<uint8_t>> SignECDSA(NCRYPT_KEY_HANDLE key,
-                                               base::span<const uint8_t> data) {
+std::optional<std::vector<uint8_t>> SignECDSA(NCRYPT_KEY_HANDLE key,
+                                              base::span<const uint8_t> data) {
   base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                 base::BlockingType::WILL_BLOCK);
 
@@ -248,7 +248,7 @@
     if (FAILED(NCryptSignHash(key, nullptr, digest.data(), digest.size(),
                               sig.data(), sig.size(), &sig_size,
                               NCRYPT_SILENT_FLAG))) {
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
   CHECK_EQ(sig.size(), sig_size);
@@ -265,8 +265,8 @@
   return CBBToVector(cbb.get());
 }
 
-absl::optional<std::vector<uint8_t>> SignRSA(NCRYPT_KEY_HANDLE key,
-                                             base::span<const uint8_t> data) {
+std::optional<std::vector<uint8_t>> SignRSA(NCRYPT_KEY_HANDLE key,
+                                            base::span<const uint8_t> data) {
   base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                 base::BlockingType::WILL_BLOCK);
 
@@ -279,14 +279,14 @@
   if (FAILED(NCryptSignHash(key, &padding_info, digest.data(), digest.size(),
                             nullptr, 0, &sig_size,
                             NCRYPT_SILENT_FLAG | BCRYPT_PAD_PKCS1))) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   std::vector<uint8_t> sig(sig_size);
   if (FAILED(NCryptSignHash(key, &padding_info, digest.data(), digest.size(),
                             sig.data(), sig.size(), &sig_size,
                             NCRYPT_SILENT_FLAG | BCRYPT_PAD_PKCS1))) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   CHECK_EQ(sig.size(), sig_size);
 
@@ -313,7 +313,7 @@
 
   std::vector<uint8_t> GetWrappedKey() const override { return wrapped_; }
 
-  absl::optional<std::vector<uint8_t>> SignSlowly(
+  std::optional<std::vector<uint8_t>> SignSlowly(
       base::span<const uint8_t> data) override {
     return SignECDSA(key_.get(), data);
   }
@@ -344,7 +344,7 @@
 
   std::vector<uint8_t> GetWrappedKey() const override { return wrapped_; }
 
-  absl::optional<std::vector<uint8_t>> SignSlowly(
+  std::optional<std::vector<uint8_t>> SignSlowly(
       base::span<const uint8_t> data) override {
     return SignRSA(key_.get(), data);
   }
@@ -361,7 +361,7 @@
  public:
   ~UnexportableKeyProviderWin() override = default;
 
-  absl::optional<SignatureVerifier::SignatureAlgorithm> SelectAlgorithm(
+  std::optional<SignatureVerifier::SignatureAlgorithm> SelectAlgorithm(
       base::span<const SignatureVerifier::SignatureAlgorithm>
           acceptable_algorithms) override {
     ScopedNCryptProvider provider;
@@ -370,7 +370,7 @@
       if (FAILED(NCryptOpenStorageProvider(
               ScopedNCryptProvider::Receiver(provider).get(),
               MS_PLATFORM_CRYPTO_PROVIDER, /*flags=*/0))) {
-        return absl::nullopt;
+        return std::nullopt;
       }
     }
 
@@ -393,7 +393,7 @@
       }
     }
 
-    absl::optional<SignatureVerifier::SignatureAlgorithm> algo =
+    std::optional<SignatureVerifier::SignatureAlgorithm> algo =
         GetBestSupported(provider.get(), acceptable_algorithms);
     if (!algo) {
       return nullptr;
@@ -415,13 +415,13 @@
       }
     }
 
-    const absl::optional<std::vector<uint8_t>> wrapped_key =
+    const std::optional<std::vector<uint8_t>> wrapped_key =
         ExportKey(key.get(), BCRYPT_OPAQUE_KEY_BLOB);
     if (!wrapped_key) {
       return nullptr;
     }
 
-    absl::optional<std::vector<uint8_t>> spki;
+    std::optional<std::vector<uint8_t>> spki;
     switch (*algo) {
       case SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256:
         spki = GetP256ECDSASPKI(key.get());
@@ -466,7 +466,7 @@
       }
     }
 
-    const absl::optional<std::vector<uint8_t>> algo_bytes =
+    const std::optional<std::vector<uint8_t>> algo_bytes =
         GetKeyProperty(key.get(), NCRYPT_ALGORITHM_PROPERTY);
     if (!algo_bytes) {
       return nullptr;
@@ -478,7 +478,7 @@
     static const wchar_t kECDSA[] = L"ECDSA";
     static const wchar_t kRSA[] = BCRYPT_RSA_ALGORITHM;
 
-    absl::optional<std::vector<uint8_t>> spki;
+    std::optional<std::vector<uint8_t>> spki;
     if (algo_bytes->size() == sizeof(kECDSA) &&
         memcmp(algo_bytes->data(), kECDSA, sizeof(kECDSA)) == 0) {
       spki = GetP256ECDSASPKI(key.get());
@@ -521,10 +521,10 @@
 
   std::string GetKeyName() const override { return name_; }
 
-  absl::optional<std::vector<uint8_t>> Sign(
+  std::optional<std::vector<uint8_t>> Sign(
       base::span<const uint8_t> data) override {
     if (!key_.is_valid()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     return SignECDSA(key_.get(), data);
@@ -569,10 +569,10 @@
 
   std::string GetKeyName() const override { return name_; }
 
-  absl::optional<std::vector<uint8_t>> Sign(
+  std::optional<std::vector<uint8_t>> Sign(
       base::span<const uint8_t> data) override {
     if (!key_.is_valid()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     return SignRSA(key_.get(), data);
@@ -606,7 +606,7 @@
  public:
   ~VirtualUnexportableKeyProviderWin() override = default;
 
-  absl::optional<SignatureVerifier::SignatureAlgorithm> SelectAlgorithm(
+  std::optional<SignatureVerifier::SignatureAlgorithm> SelectAlgorithm(
       base::span<const SignatureVerifier::SignatureAlgorithm>
           acceptable_algorithms) override {
     ScopedNCryptProvider provider;
@@ -617,7 +617,7 @@
           MS_KEY_STORAGE_PROVIDER, /*dwFlags=*/0);
       if (FAILED(status)) {
         base::UmaHistogramSparse(kMetricVirtualOpenStorageError, status);
-        return absl::nullopt;
+        return std::nullopt;
       }
     }
 
@@ -643,7 +643,7 @@
       }
     }
 
-    absl::optional<SignatureVerifier::SignatureAlgorithm> algo =
+    std::optional<SignatureVerifier::SignatureAlgorithm> algo =
         GetBestSupported(provider.get(), acceptable_algorithms);
     if (!algo) {
       return nullptr;
@@ -671,7 +671,7 @@
       }
     }
 
-    absl::optional<std::vector<uint8_t>> spki;
+    std::optional<std::vector<uint8_t>> spki;
     switch (*algo) {
       case SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256:
         spki = GetP256ECDSASPKI(key.get());
@@ -719,7 +719,7 @@
       }
     }
 
-    const absl::optional<std::vector<uint8_t>> algo_bytes =
+    const std::optional<std::vector<uint8_t>> algo_bytes =
         GetKeyProperty(key.get(), NCRYPT_ALGORITHM_PROPERTY);
 
     // This is the expected behavior, but note it is different from
@@ -727,7 +727,7 @@
     static const wchar_t kECDSA[] = BCRYPT_ECDSA_P256_ALGORITHM;
     static const wchar_t kRSA[] = BCRYPT_RSA_ALGORITHM;
 
-    absl::optional<std::vector<uint8_t>> spki;
+    std::optional<std::vector<uint8_t>> spki;
     if (algo_bytes->size() == sizeof(kECDSA) &&
         memcmp(algo_bytes->data(), kECDSA, sizeof(kECDSA)) == 0) {
       spki = GetP256ECDSASPKI(key.get());
diff --git a/dbus/end_to_end_async_unittest.cc b/dbus/end_to_end_async_unittest.cc
index 4a31038c..ae43c4c 100644
--- a/dbus/end_to_end_async_unittest.cc
+++ b/dbus/end_to_end_async_unittest.cc
@@ -9,6 +9,7 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "base/memory/raw_ptr.h"
@@ -26,7 +27,6 @@
 #include "dbus/object_proxy.h"
 #include "dbus/test_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace dbus {
 
@@ -252,7 +252,7 @@
   }
 
   base::test::SingleThreadTaskEnvironment task_environment_;
-  absl::optional<base::ScopedDisallowBlocking> disallow_blocking_;
+  std::optional<base::ScopedDisallowBlocking> disallow_blocking_;
   std::unique_ptr<base::RunLoop> run_loop_;
   std::vector<std::string> response_strings_;
   std::vector<std::string> error_names_;
diff --git a/dbus/object_manager_unittest.cc b/dbus/object_manager_unittest.cc
index 859220a..eb38eda 100644
--- a/dbus/object_manager_unittest.cc
+++ b/dbus/object_manager_unittest.cc
@@ -11,6 +11,7 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/functional/bind.h"
 #include "base/memory/raw_ptr.h"
 #include "base/message_loop/message_pump_type.h"
@@ -26,7 +27,6 @@
 #include "dbus/property.h"
 #include "dbus/test_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace dbus {
 
@@ -208,7 +208,7 @@
   }
 
   base::test::SingleThreadTaskEnvironment task_environment_;
-  absl::optional<base::ScopedDisallowBlocking> disallow_blocking_;
+  std::optional<base::ScopedDisallowBlocking> disallow_blocking_;
   std::unique_ptr<base::RunLoop> run_loop_;
   std::unique_ptr<base::Thread> dbus_thread_;
   scoped_refptr<Bus> bus_;
diff --git a/dbus/property_unittest.cc b/dbus/property_unittest.cc
index 2842509f..3461686 100644
--- a/dbus/property_unittest.cc
+++ b/dbus/property_unittest.cc
@@ -156,7 +156,7 @@
   }
 
   base::test::SingleThreadTaskEnvironment task_environment_;
-  absl::optional<base::ScopedDisallowBlocking> disallow_blocking_;
+  std::optional<base::ScopedDisallowBlocking> disallow_blocking_;
   std::unique_ptr<base::RunLoop> run_loop_;
   std::unique_ptr<base::Thread> dbus_thread_;
   scoped_refptr<Bus> bus_;
diff --git a/fuchsia_web/common/test/frame_test_util.cc b/fuchsia_web/common/test/frame_test_util.cc
index a36ffb5..d9fea4d 100644
--- a/fuchsia_web/common/test/frame_test_util.cc
+++ b/fuchsia_web/common/test/frame_test_util.cc
@@ -7,6 +7,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/check.h"
 #include "base/fuchsia/mem_buffer_util.h"
 #include "base/json/json_reader.h"
@@ -15,7 +16,6 @@
 #include "base/test/test_future.h"
 #include "fuchsia_web/common/test/fit_adapter.h"
 #include "fuchsia_web/common/test/test_navigation_listener.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 bool LoadUrlAndExpectResponse(
     fuchsia::web::NavigationController* navigation_controller,
@@ -37,8 +37,8 @@
   return LoadUrlAndExpectResponse(controller.get(), std::move(params), url);
 }
 
-absl::optional<base::Value> ExecuteJavaScript(fuchsia::web::Frame* frame,
-                                              base::StringPiece script) {
+std::optional<base::Value> ExecuteJavaScript(fuchsia::web::Frame* frame,
+                                             base::StringPiece script) {
   base::test::TestFuture<fuchsia::web::Frame_ExecuteJavaScript_Result> result;
   frame->ExecuteJavaScript({"*"}, base::MemBufferFromString(script, "test"),
                            CallbackToFitFunction(result.GetCallback()));
@@ -46,7 +46,7 @@
   if (!result.Wait() || !result.Get().is_response())
     return {};
 
-  absl::optional<std::string> result_json =
+  std::optional<std::string> result_json =
       base::StringFromMemBuffer(result.Get().response().result);
   if (!result_json) {
     return {};
diff --git a/fuchsia_web/common/test/frame_test_util.h b/fuchsia_web/common/test/frame_test_util.h
index 8845577..4c01cbf 100644
--- a/fuchsia_web/common/test/frame_test_util.h
+++ b/fuchsia_web/common/test/frame_test_util.h
@@ -8,9 +8,9 @@
 #include <fuchsia/mem/cpp/fidl.h>
 #include <fuchsia/web/cpp/fidl.h>
 
+#include <optional>
 #include "base/strings/string_piece.h"
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // Uses |navigation_controller| to load |url| with |load_url_params|. Returns
 // after the load is completed. Returns true if the load was successful, false
@@ -25,9 +25,9 @@
     base::StringPiece url);
 
 // Executes |script| in the context of |frame|'s top-level document.
-// Returns an un-set |absl::optional<>| on failure.
-absl::optional<base::Value> ExecuteJavaScript(fuchsia::web::Frame* frame,
-                                              base::StringPiece script);
+// Returns an un-set |std::optional<>| on failure.
+std::optional<base::Value> ExecuteJavaScript(fuchsia::web::Frame* frame,
+                                             base::StringPiece script);
 
 // Creates and returns a LoadUrlParams with was_user_activated set to true.
 // This allows user actions to propagate to the frame, allowing features such as
diff --git a/fuchsia_web/common/test/url_request_rewrite_test_util.cc b/fuchsia_web/common/test/url_request_rewrite_test_util.cc
index 4430966..af6c4c9 100644
--- a/fuchsia_web/common/test/url_request_rewrite_test_util.cc
+++ b/fuchsia_web/common/test/url_request_rewrite_test_util.cc
@@ -26,7 +26,7 @@
 }
 
 fuchsia::web::UrlRequestRewrite CreateRewriteRemoveHeader(
-    absl::optional<base::StringPiece> query_pattern,
+    std::optional<base::StringPiece> query_pattern,
     base::StringPiece header_name) {
   fuchsia::web::UrlRequestRewriteRemoveHeader remove_header;
   if (query_pattern)
diff --git a/fuchsia_web/common/test/url_request_rewrite_test_util.h b/fuchsia_web/common/test/url_request_rewrite_test_util.h
index 6fe6d6c..1b8e8cc 100644
--- a/fuchsia_web/common/test/url_request_rewrite_test_util.h
+++ b/fuchsia_web/common/test/url_request_rewrite_test_util.h
@@ -7,8 +7,8 @@
 
 #include <fuchsia/web/cpp/fidl.h>
 
+#include <optional>
 #include "base/strings/string_piece.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // Utility functions to create a fuchsia.web.UrlRequestRewrite in one line.
 
@@ -17,7 +17,7 @@
     base::StringPiece header_value);
 
 fuchsia::web::UrlRequestRewrite CreateRewriteRemoveHeader(
-    absl::optional<base::StringPiece> query_pattern,
+    std::optional<base::StringPiece> query_pattern,
     base::StringPiece header_name);
 
 fuchsia::web::UrlRequestRewrite CreateRewriteSubstituteQueryPattern(
diff --git a/fuchsia_web/runners/cast/api_bindings_client.h b/fuchsia_web/runners/cast/api_bindings_client.h
index 3bffa7d..c682cd0 100644
--- a/fuchsia_web/runners/cast/api_bindings_client.h
+++ b/fuchsia_web/runners/cast/api_bindings_client.h
@@ -9,10 +9,10 @@
 #include <fuchsia/web/cpp/fidl.h>
 #include <vector>
 
+#include <optional>
 #include "base/memory/weak_ptr.h"
 #include "components/cast/message_port/message_port.h"
 #include "components/cast/named_message_port_connector/named_message_port_connector.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // Injects scripts received from the ApiBindings service, and provides connected
 // ports to the Agent.
@@ -60,7 +60,7 @@
   // Used by AttachToFrame() to invoke `on_error_callback` asynchronously.
   void CallOnErrorCallback(base::OnceClosure on_error_callback);
 
-  absl::optional<std::vector<chromium::cast::ApiBinding>> bindings_;
+  std::optional<std::vector<chromium::cast::ApiBinding>> bindings_;
   fuchsia::web::Frame* frame_ = nullptr;
   cast_api_bindings::NamedMessagePortConnector* connector_ = nullptr;
   chromium::cast::ApiBindingsPtr bindings_service_;
diff --git a/fuchsia_web/runners/cast/api_bindings_client_browsertest.cc b/fuchsia_web/runners/cast/api_bindings_client_browsertest.cc
index d20b1fb..b6a88ad 100644
--- a/fuchsia_web/runners/cast/api_bindings_client_browsertest.cc
+++ b/fuchsia_web/runners/cast/api_bindings_client_browsertest.cc
@@ -144,7 +144,7 @@
   port->ReceiveMessage(CallbackToFitFunction(response.GetCallback()));
   ASSERT_TRUE(response.Wait());
 
-  absl::optional<std::string> response_string =
+  std::optional<std::string> response_string =
       base::StringFromMemBuffer(response.Get().data());
   ASSERT_TRUE(response_string.has_value());
   EXPECT_EQ("ack ping", *response_string);
diff --git a/fuchsia_web/runners/cast/application_controller_impl.h b/fuchsia_web/runners/cast/application_controller_impl.h
index 1d23824..187349c 100644
--- a/fuchsia_web/runners/cast/application_controller_impl.h
+++ b/fuchsia_web/runners/cast/application_controller_impl.h
@@ -11,7 +11,7 @@
 #include <lib/fidl/cpp/binding.h>
 #include <lib/fidl/cpp/interface_request.h>
 
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include <optional>
 
 class ApplicationControllerImpl final
     : public fidl::Server<chromium_cast::ApplicationController> {
@@ -43,7 +43,7 @@
       GetPrivateMemorySizeCompleter::Sync& completer) override;
 
  private:
-  absl::optional<fidl::ServerBinding<chromium_cast::ApplicationController>>
+  std::optional<fidl::ServerBinding<chromium_cast::ApplicationController>>
       binding_;
   fuchsia::web::Frame* const frame_;
   const uint64_t trace_flow_id_;
diff --git a/fuchsia_web/runners/cast/application_controller_impl_unittest.cc b/fuchsia_web/runners/cast/application_controller_impl_unittest.cc
index 23a2f4d..b1bf68f 100644
--- a/fuchsia_web/runners/cast/application_controller_impl_unittest.cc
+++ b/fuchsia_web/runners/cast/application_controller_impl_unittest.cc
@@ -85,10 +85,10 @@
       base::test::SingleThreadTaskEnvironment::MainThreadType::IO};
 
   MockFrame frame_;
-  absl::optional<fidl::ServerBinding<chromium_cast::ApplicationContext>>
+  std::optional<fidl::ServerBinding<chromium_cast::ApplicationContext>>
       application_context_binding_;
   fidl::Client<chromium_cast::ApplicationContext> application_context_;
-  absl::optional<ApplicationControllerImpl> application_;
+  std::optional<ApplicationControllerImpl> application_;
 
   fidl::Client<chromium_cast::ApplicationController> application_client_;
   base::OnceClosure wait_for_controller_callback_;
diff --git a/fuchsia_web/runners/cast/cast_component.h b/fuchsia_web/runners/cast/cast_component.h
index fc8018c..f6bb93ee 100644
--- a/fuchsia_web/runners/cast/cast_component.h
+++ b/fuchsia_web/runners/cast/cast_component.h
@@ -13,6 +13,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/fuchsia/startup_context.h"
 #include "base/gtest_prod_util.h"
 #include "base/message_loop/message_pump_for_io.h"
@@ -21,7 +22,6 @@
 #include "fuchsia_web/runners/cast/application_controller_impl.h"
 #include "fuchsia_web/runners/cast/named_message_port_connector_fuchsia.h"
 #include "fuchsia_web/runners/common/web_component.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 FORWARD_DECLARE_TEST(HeadlessCastRunnerIntegrationTest, Headless);
 
@@ -53,9 +53,9 @@
     std::unique_ptr<ApiBindingsClient> api_bindings_client;
     chromium::cast::ApplicationConfig application_config;
     fidl::ClientEnd<chromium_cast::ApplicationContext> application_context;
-    absl::optional<std::vector<fuchsia::web::UrlRequestRewriteRule>>
+    std::optional<std::vector<fuchsia::web::UrlRequestRewriteRule>>
         initial_url_rewrite_rules;
-    absl::optional<fuchsia::web::FrameMediaSettings> media_settings;
+    std::optional<fuchsia::web::FrameMediaSettings> media_settings;
 
     // ID of flow used in the with the Fuchsia Trace API to trace the
     // application lifetime.
diff --git a/fuchsia_web/runners/cast/cast_runner.cc b/fuchsia_web/runners/cast/cast_runner.cc
index 5bed74dd..9652f15e 100644
--- a/fuchsia_web/runners/cast/cast_runner.cc
+++ b/fuchsia_web/runners/cast/cast_runner.cc
@@ -97,13 +97,13 @@
 // Exits the Runner process if creation of data storage fails for any reason.
 void SetDataParamsForMainContext(fuchsia::web::CreateContextParams* params) {
   // Set the web data quota based on the CastRunner configuration.
-  const absl::optional<base::Value::Dict>& config =
+  const std::optional<base::Value::Dict>& config =
       fuchsia_component_support::LoadPackageConfig();
   if (!config)
     return;
 
   constexpr char kDataQuotaBytesSwitch[] = "data-quota-bytes";
-  const absl::optional<int> data_quota_bytes =
+  const std::optional<int> data_quota_bytes =
       config->FindInt(kDataQuotaBytesSwitch);
   if (!data_quota_bytes)
     return;
@@ -130,11 +130,11 @@
 // CDM data persistence is always enabled, with an optional soft quota.
 // Exits the Runner if creation of CDM storage fails for any reason.
 void SetCdmParamsForMainContext(fuchsia::web::CreateContextParams* params) {
-  const absl::optional<base::Value::Dict>& config =
+  const std::optional<base::Value::Dict>& config =
       fuchsia_component_support::LoadPackageConfig();
   if (config) {
     constexpr char kCdmDataQuotaBytesSwitch[] = "cdm-data-quota-bytes";
-    const absl::optional<int> cdm_data_quota_bytes =
+    const std::optional<int> cdm_data_quota_bytes =
         config->FindInt(kCdmDataQuotaBytesSwitch);
     if (cdm_data_quota_bytes)
       params->set_cdm_data_quota_bytes(*cdm_data_quota_bytes);
@@ -414,26 +414,26 @@
   return config;
 }
 
-absl::optional<WebContentRunner::WebInstanceConfig>
+std::optional<WebContentRunner::WebInstanceConfig>
 CastRunner::GetWebInstanceConfigForAppConfig(
     chromium::cast::ApplicationConfig* app_config) {
   if (IsAppConfigForCastStreaming(*app_config)) {
     // TODO(crbug.com/1082821): Remove this once the CastStreamingReceiver
     // Component has been implemented.
-    return absl::make_optional(GetIsolatedWebInstanceConfigForCastStreaming());
+    return std::make_optional(GetIsolatedWebInstanceConfigForCastStreaming());
   }
 
   const bool is_isolated_app =
       app_config->has_content_directories_for_isolated_application();
   if (is_isolated_app) {
-    return absl::make_optional(
+    return std::make_optional(
         GetIsolatedWebInstanceConfigWithFuchsiaDirs(std::move(
             *app_config
                  ->mutable_content_directories_for_isolated_application())));
   }
 
   // No need to create an isolated context in other cases.
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 WebContentRunner* CastRunner::CreateIsolatedRunner(
diff --git a/fuchsia_web/runners/cast/cast_runner.h b/fuchsia_web/runners/cast/cast_runner.h
index abc8631..2c699a87 100644
--- a/fuchsia_web/runners/cast/cast_runner.h
+++ b/fuchsia_web/runners/cast/cast_runner.h
@@ -13,6 +13,7 @@
 #include <set>
 #include <vector>
 
+#include <optional>
 #include "base/containers/flat_set.h"
 #include "base/containers/unique_ptr_adapters.h"
 #include "base/fuchsia/startup_context.h"
@@ -20,7 +21,6 @@
 #include "fuchsia_web/runners/cast/cast_component.h"
 #include "fuchsia_web/runners/cast/pending_cast_component.h"
 #include "fuchsia_web/runners/common/web_content_runner.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class WebInstanceHost;
 
@@ -88,7 +88,7 @@
 
   // Returns CreateContextParams for |app_config|. Returns nullopt if there is
   // no need to create an isolated context.
-  absl::optional<WebContentRunner::WebInstanceConfig>
+  std::optional<WebContentRunner::WebInstanceConfig>
   GetWebInstanceConfigForAppConfig(
       chromium::cast::ApplicationConfig* app_config);
 
@@ -150,7 +150,7 @@
 
   // Used to fetch & cache the list of CORS exempt HTTP headers to configure
   // each web.Context with.
-  absl::optional<std::vector<std::vector<uint8_t>>> cors_exempt_headers_;
+  std::optional<std::vector<std::vector<uint8_t>>> cors_exempt_headers_;
   chromium::cast::CorsExemptHeaderProviderPtr cors_exempt_headers_provider_;
   std::vector<base::OnceClosure> on_have_cors_exempt_headers_;
 
diff --git a/fuchsia_web/runners/cast/cast_runner_integration_test.cc b/fuchsia_web/runners/cast/cast_runner_integration_test.cc
index bac17e4..30b6509 100644
--- a/fuchsia_web/runners/cast/cast_runner_integration_test.cc
+++ b/fuchsia_web/runners/cast/cast_runner_integration_test.cc
@@ -138,7 +138,7 @@
     loop.Run();
   }
 
-  absl::optional<int64_t> WaitForApplicationTerminated() {
+  std::optional<int64_t> WaitForApplicationTerminated() {
     if (application_exit_code_.has_value()) {
       return application_exit_code_;
     }
@@ -171,7 +171,7 @@
   chromium::cast::ApplicationControllerPtr application_controller_;
   base::OnceClosure on_set_application_controller_;
 
-  absl::optional<int64_t> application_exit_code_;
+  std::optional<int64_t> application_exit_code_;
   base::OnceClosure on_application_terminated_;
 };
 
@@ -265,7 +265,7 @@
     test_port_->ReceiveMessage(CallbackToFitFunction(response.GetCallback()));
     EXPECT_TRUE(response.Wait());
 
-    absl::optional<std::string> response_string =
+    std::optional<std::string> response_string =
         base::StringFromMemBuffer(response.Get().data());
     EXPECT_TRUE(response_string.has_value());
 
@@ -400,9 +400,9 @@
   bool offer_services_ = true;
 
   // Holds the service directory and fake services offered to `component_`.
-  absl::optional<FakeComponentServices> services_;
+  std::optional<FakeComponentServices> services_;
 
-  absl::optional<fuchsia_component_support::DynamicComponentHost> component_;
+  std::optional<fuchsia_component_support::DynamicComponentHost> component_;
 
   fuchsia::web::MessagePortPtr test_port_;
 
@@ -874,7 +874,7 @@
 
   // Have the web content close itself, and wait for OnApplicationTerminated().
   EXPECT_EQ(component.ExecuteJavaScript("window.close()"), "undefined");
-  absl::optional<zx_status_t> exit_code =
+  std::optional<zx_status_t> exit_code =
       component.application_context().WaitForApplicationTerminated();
   ASSERT_TRUE(exit_code);
   EXPECT_EQ(exit_code.value(), ZX_OK);
@@ -896,7 +896,7 @@
   // Request that the component be destroyed, and wait for
   // OnApplicationTerminated().
   component.ShutdownComponent();
-  absl::optional<zx_status_t> exit_code =
+  std::optional<zx_status_t> exit_code =
       component.application_context().WaitForApplicationTerminated();
   ASSERT_TRUE(exit_code);
   EXPECT_EQ(exit_code.value(), ZX_OK);
diff --git a/fuchsia_web/runners/cast/cast_streaming.cc b/fuchsia_web/runners/cast/cast_streaming.cc
index 33b8016..f66ecd6 100644
--- a/fuchsia_web/runners/cast/cast_streaming.cc
+++ b/fuchsia_web/runners/cast/cast_streaming.cc
@@ -6,8 +6,8 @@
 
 #include <string>
 
+#include <optional>
 #include "components/fuchsia_component_support/config_reader.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -26,7 +26,7 @@
 }
 
 std::string GetMessagePortOriginForAppId(const std::string& app_id) {
-  const absl::optional<base::Value::Dict>& config =
+  const std::optional<base::Value::Dict>& config =
       fuchsia_component_support::LoadPackageConfig();
   if (!config) {
     return kCastStreamingMessagePortOrigin;
diff --git a/fuchsia_web/runners/cast/main.cc b/fuchsia_web/runners/cast/main.cc
index 6e97b98..9dc0a2d 100644
--- a/fuchsia_web/runners/cast/main.cc
+++ b/fuchsia_web/runners/cast/main.cc
@@ -9,6 +9,7 @@
 
 #include <utility>
 
+#include <optional>
 #include "base/check.h"
 #include "base/command_line.h"
 #include "base/files/file_path.h"
@@ -33,7 +34,6 @@
 #include "fuchsia_web/runners/cast/cast_runner.h"
 #include "fuchsia_web/runners/cast/cast_runner_switches.h"
 #include "fuchsia_web/webinstance_host/web_instance_host.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -49,7 +49,7 @@
 
 // Returns the value of |config_key| or false if it is not set.
 bool GetConfigBool(base::StringPiece config_key) {
-  const absl::optional<base::Value::Dict>& config =
+  const std::optional<base::Value::Dict>& config =
       fuchsia_component_support::LoadPackageConfig();
   if (config)
     return config->FindBool(config_key).value_or(false);
diff --git a/fuchsia_web/runners/cast/test/cast_runner_launcher.h b/fuchsia_web/runners/cast/test/cast_runner_launcher.h
index 3f758d7..8b28903 100644
--- a/fuchsia_web/runners/cast/test/cast_runner_launcher.h
+++ b/fuchsia_web/runners/cast/test/cast_runner_launcher.h
@@ -11,10 +11,10 @@
 #include <memory>
 #include <string_view>
 
+#include <optional>
 #include "fuchsia_web/common/test/fake_feedback_service.h"
 #include "fuchsia_web/runners/cast/test/cast_runner_features.h"
 #include "fuchsia_web/runners/cast/test/fake_cast_agent.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace test {
 
@@ -51,7 +51,7 @@
   FakeCastAgent& fake_cast_agent() { return *fake_cast_agent_; }
 
  private:
-  absl::optional<::component_testing::RealmRoot> realm_root_;
+  std::optional<::component_testing::RealmRoot> realm_root_;
 
   std::unique_ptr<sys::ServiceDirectory> exposed_services_;
 
diff --git a/fuchsia_web/runners/cast/test/fake_application_config_manager.cc b/fuchsia_web/runners/cast/test/fake_application_config_manager.cc
index 813f4ec..e7bfc24 100644
--- a/fuchsia_web/runners/cast/test/fake_application_config_manager.cc
+++ b/fuchsia_web/runners/cast/test/fake_application_config_manager.cc
@@ -9,9 +9,9 @@
 #include <string>
 #include <utility>
 
+#include <optional>
 #include "base/fuchsia/fuchsia_logging.h"
 #include "base/logging.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 constexpr char FakeApplicationConfigManager::kFakeAgentUrl[] =
     "fuchsia-pkg://fuchsia.com/fake_agent#meta/fake_agent.cmx";
@@ -60,7 +60,7 @@
   // ContextDirectoryProviders contain move-only fuchsia.io.Directory resources,
   // so if those are present then remove them, manually clone them, then
   // put them back.
-  absl::optional<std::vector<fuchsia::web::ContentDirectoryProvider>>
+  std::optional<std::vector<fuchsia::web::ContentDirectoryProvider>>
       content_directories;
   chromium::cast::ApplicationConfig& config = it->second;
   if (config.has_content_directories_for_isolated_application()) {
diff --git a/fuchsia_web/shell/cast_streaming_shell.cc b/fuchsia_web/shell/cast_streaming_shell.cc
index 63b7dd3..12a5e3ec 100644
--- a/fuchsia_web/shell/cast_streaming_shell.cc
+++ b/fuchsia_web/shell/cast_streaming_shell.cc
@@ -8,6 +8,7 @@
 #include <lib/sys/cpp/component_context.h>
 #include <lib/sys/cpp/service_directory.h>
 
+#include <optional>
 #include "base/base_paths.h"
 #include "base/check.h"
 #include "base/command_line.h"
@@ -38,7 +39,6 @@
 #include "fuchsia_web/webinstance_host/web_instance_host.h"
 #include "media/base/media_util.h"
 #include "media/gpu/test/video_test_helpers.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -88,7 +88,7 @@
 }
 
 // Set autoplay, enable all logging, and present fullscreen view of `frame`.
-absl::optional<fuchsia::element::GraphicalPresenterPtr> ConfigureFrame(
+std::optional<fuchsia::element::GraphicalPresenterPtr> ConfigureFrame(
     fuchsia::web::Frame* frame,
     fidl::InterfaceHandle<fuchsia::element::AnnotationController>
         annotation_controller) {
@@ -115,7 +115,7 @@
     return optional_exit_code.value();
   }
 
-  absl::optional<uint16_t> remote_debugging_port =
+  std::optional<uint16_t> remote_debugging_port =
       GetRemoteDebuggingPort(*command_line);
   if (!remote_debugging_port) {
     PrintUsage();
@@ -224,7 +224,7 @@
   // Send `sender_message_port` to a Sender and start it.
   cast_streaming::CastStreamingTestSender sender;
   sender.Start(std::move(sender_message_port), net::IPAddress::IPv6Localhost(),
-               absl::nullopt, GetDefaultVideoConfig());
+               std::nullopt, GetDefaultVideoConfig());
 
   // Navigate `frame` to `receiver.html`.
   fuchsia::web::LoadUrlParams load_params;
@@ -262,7 +262,7 @@
   // Load video.
   base::FilePath video_file(
       pkg_path.AppendASCII("media/test/data/bear-1280x720.ivf"));
-  absl::optional<std::vector<uint8_t>> video_stream =
+  std::optional<std::vector<uint8_t>> video_stream =
       base::ReadFileToBytes(video_file);
   CHECK(video_stream.has_value());
   media::test::EncodedDataHelper video_helper(video_stream.value(),
diff --git a/fuchsia_web/shell/remote_debugging_port.cc b/fuchsia_web/shell/remote_debugging_port.cc
index 05a550f4..729902ef 100644
--- a/fuchsia_web/shell/remote_debugging_port.cc
+++ b/fuchsia_web/shell/remote_debugging_port.cc
@@ -10,7 +10,7 @@
 
 constexpr char kRemoteDebuggingPortSwitch[] = "remote-debugging-port";
 
-absl::optional<uint16_t> GetRemoteDebuggingPort(
+std::optional<uint16_t> GetRemoteDebuggingPort(
     const base::CommandLine& command_line) {
   if (!command_line.HasSwitch(kRemoteDebuggingPortSwitch)) {
     return 0;
@@ -22,7 +22,7 @@
         port_parsed > 65535) {
       LOG(ERROR) << "Invalid value for --remote-debugging-port (must be in the "
                     "range 0-65535).";
-      return absl::nullopt;
+      return std::nullopt;
     }
     return static_cast<uint16_t>(port_parsed);
   }
diff --git a/fuchsia_web/shell/remote_debugging_port.h b/fuchsia_web/shell/remote_debugging_port.h
index 3454ff6..a8865f3 100644
--- a/fuchsia_web/shell/remote_debugging_port.h
+++ b/fuchsia_web/shell/remote_debugging_port.h
@@ -5,7 +5,7 @@
 #ifndef FUCHSIA_WEB_SHELL_REMOTE_DEBUGGING_PORT_H_
 #define FUCHSIA_WEB_SHELL_REMOTE_DEBUGGING_PORT_H_
 
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include <optional>
 
 extern const char kRemoteDebuggingPortSwitch[];
 
@@ -19,7 +19,7 @@
 // port switch. If |command_line| contains the appropriate switch, returns the
 // remote debugging port specified in the |command_line| or nullopt on parsing
 // failure.
-absl::optional<uint16_t> GetRemoteDebuggingPort(
+std::optional<uint16_t> GetRemoteDebuggingPort(
     const base::CommandLine& command_line);
 
 #endif  // FUCHSIA_WEB_SHELL_REMOTE_DEBUGGING_PORT_H_
diff --git a/fuchsia_web/shell/shell_relauncher.cc b/fuchsia_web/shell/shell_relauncher.cc
index 3aa2567..b4a9337 100644
--- a/fuchsia_web/shell/shell_relauncher.cc
+++ b/fuchsia_web/shell/shell_relauncher.cc
@@ -16,13 +16,13 @@
 #include "base/run_loop.h"
 #include "fuchsia_web/common/test/test_realm_support.h"
 
-absl::optional<int> RelaunchForWebInstanceHostIfParent(
+std::optional<int> RelaunchForWebInstanceHostIfParent(
     base::StringPiece relative_component_url,
     const base::CommandLine& command_line) {
   // Nothing to do if running from the context of a relaunched process.
   static constexpr char kNoRelaunch[] = "no-relaunch";
   if (command_line.HasSwitch(kNoRelaunch)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   auto realm_builder = component_testing::RealmBuilder::CreateFromRelativeUrl(
diff --git a/fuchsia_web/shell/shell_relauncher.h b/fuchsia_web/shell/shell_relauncher.h
index c0b2f2f9..7b0614e 100644
--- a/fuchsia_web/shell/shell_relauncher.h
+++ b/fuchsia_web/shell/shell_relauncher.h
@@ -5,8 +5,8 @@
 #ifndef FUCHSIA_WEB_SHELL_SHELL_RELAUNCHER_H_
 #define FUCHSIA_WEB_SHELL_SHELL_RELAUNCHER_H_
 
+#include <optional>
 #include "base/strings/string_piece.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class CommandLine;
@@ -17,7 +17,7 @@
 // use RealmBuilder to relaunch the shell via the given package-relative URL
 // (which includes `--no-relaunch` on its command line) with the contents of
 // this process's command line.
-absl::optional<int> RelaunchForWebInstanceHostIfParent(
+std::optional<int> RelaunchForWebInstanceHostIfParent(
     base::StringPiece relative_component_url,
     const base::CommandLine& command_line);
 
diff --git a/fuchsia_web/shell/web_engine_shell.cc b/fuchsia_web/shell/web_engine_shell.cc
index 9b1746b..b29c348 100644
--- a/fuchsia_web/shell/web_engine_shell.cc
+++ b/fuchsia_web/shell/web_engine_shell.cc
@@ -13,6 +13,7 @@
 #include <iostream>
 #include <utility>
 
+#include <optional>
 #include "base/base_paths.h"
 #include "base/check.h"
 #include "base/command_line.h"
@@ -36,7 +37,6 @@
 #include "fuchsia_web/shell/shell_relauncher.h"
 #include "fuchsia_web/webinstance_host/web_instance_host.h"
 #include "fuchsia_web/webinstance_host/web_instance_host_constants.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/widevine/cdm/buildflags.h"
 #include "url/gurl.h"
 
@@ -112,7 +112,7 @@
     }
   }
 
-  absl::optional<uint16_t> remote_debugging_port =
+  std::optional<uint16_t> remote_debugging_port =
       GetRemoteDebuggingPort(*command_line);
   if (!remote_debugging_port) {
     PrintUsage();
diff --git a/fuchsia_web/webengine/browser/accessibility_browsertest.cc b/fuchsia_web/webengine/browser/accessibility_browsertest.cc
index 8ef090c..5cf4361 100644
--- a/fuchsia_web/webengine/browser/accessibility_browsertest.cc
+++ b/fuchsia_web/webengine/browser/accessibility_browsertest.cc
@@ -144,7 +144,7 @@
 
  protected:
   // TODO(crbug.com/1038786): Maybe move to WebEngineBrowserTest.
-  absl::optional<base::TestComponentContextForProcess> test_context_;
+  std::optional<base::TestComponentContextForProcess> test_context_;
 
   FrameForTest frame_;
   FrameImpl* frame_impl_;
@@ -152,7 +152,7 @@
 
   // Binding to the fake semantics manager.
   // Optional so that it can be instantiated outside the constructor.
-  absl::optional<base::ScopedServiceBinding<
+  std::optional<base::ScopedServiceBinding<
       fuchsia::accessibility::semantics::SemanticsManager>>
       semantics_manager_binding_;
 };
diff --git a/fuchsia_web/webengine/browser/cast_streaming_browsertest.cc b/fuchsia_web/webengine/browser/cast_streaming_browsertest.cc
index 6c41f36..a80898e8 100644
--- a/fuchsia_web/webengine/browser/cast_streaming_browsertest.cc
+++ b/fuchsia_web/webengine/browser/cast_streaming_browsertest.cc
@@ -149,8 +149,8 @@
   frame.navigation_listener().RunUntilTitleEquals("loadedmetadata");
 
   EXPECT_TRUE(post_result.Wait());
-  EXPECT_NE(sender.audio_decoder_config(), absl::nullopt);
-  EXPECT_NE(sender.video_decoder_config(), absl::nullopt);
+  EXPECT_NE(sender.audio_decoder_config(), std::nullopt);
+  EXPECT_NE(sender.video_decoder_config(), std::nullopt);
 }
 
 // Check that attempting to start a video-only receiver properly disables audio.
@@ -194,6 +194,6 @@
   frame.navigation_listener().RunUntilTitleEquals("loadedmetadata");
 
   EXPECT_TRUE(post_result.Wait());
-  EXPECT_EQ(sender.audio_decoder_config(), absl::nullopt);
-  EXPECT_NE(sender.video_decoder_config(), absl::nullopt);
+  EXPECT_EQ(sender.audio_decoder_config(), std::nullopt);
+  EXPECT_NE(sender.video_decoder_config(), std::nullopt);
 }
diff --git a/fuchsia_web/webengine/browser/client_hints_browsertest.cc b/fuchsia_web/webengine/browser/client_hints_browsertest.cc
index ae9fc46..1f371ed 100644
--- a/fuchsia_web/webengine/browser/client_hints_browsertest.cc
+++ b/fuchsia_web/webengine/browser/client_hints_browsertest.cc
@@ -97,7 +97,7 @@
                              url.spec());
     frame_for_test_.navigation_listener().RunUntilUrlEquals(url);
 
-    absl::optional<base::Value> value =
+    std::optional<base::Value> value =
         ExecuteJavaScript(frame_for_test_.get(), "document.body.innerText;");
     return value->GetString();
   }
@@ -369,7 +369,7 @@
                            url.spec());
   frame_for_test_.navigation_listener().RunUntilUrlEquals(url);
 
-  absl::optional<base::Value> value =
+  std::optional<base::Value> value =
       ExecuteJavaScript(frame_for_test_.get(), "document.body.innerText;");
   EXPECT_EQ(value->GetString(), k64Bitness);
 }
diff --git a/fuchsia_web/webengine/browser/content_directory_loader_factory.cc b/fuchsia_web/webengine/browser/content_directory_loader_factory.cc
index f8ba7572..dd7850dd 100644
--- a/fuchsia_web/webengine/browser/content_directory_loader_factory.cc
+++ b/fuchsia_web/webengine/browser/content_directory_loader_factory.cc
@@ -53,7 +53,7 @@
 //            will assume the charset to be "text/plain" by default.
 scoped_refptr<net::HttpResponseHeaders> CreateHeaders(
     base::StringPiece mime_type,
-    const absl::optional<std::string>& charset) {
+    const std::optional<std::string>& charset) {
   constexpr char kXFrameOptions[] = "X-Frame-Options";
   constexpr char kXFrameOptionsValue[] = "DENY";
   constexpr char kCacheControl[] = "Cache-Control";
@@ -174,11 +174,11 @@
     auto response = network::mojom::URLResponseHead::New();
 
     // Read the charset and MIME type from the optional _metadata file.
-    absl::optional<std::string> charset;
-    absl::optional<std::string> mime_type;
+    std::optional<std::string> charset;
+    std::optional<std::string> mime_type;
     base::MemoryMappedFile metadata_mmap;
     if (MapFile(std::move(metadata_channel), &metadata_mmap)) {
-      absl::optional<base::Value> metadata_parsed = base::JSONReader::Read(
+      std::optional<base::Value> metadata_parsed = base::JSONReader::Read(
           base::StringPiece(reinterpret_cast<char*>(metadata_mmap.data()),
                             metadata_mmap.length()));
 
@@ -236,7 +236,7 @@
     }
 
     client_->OnReceiveResponse(std::move(response), std::move(consumer_handle),
-                               absl::nullopt);
+                               std::nullopt);
 
     // Start reading the contents of |mmap_| into the response DataPipe.
     body_writer_ =
@@ -257,7 +257,7 @@
       const std::vector<std::string>& removed_headers,
       const net::HttpRequestHeaders& modified_request_headers,
       const net::HttpRequestHeaders& modified_cors_exempt_request_headers,
-      const absl::optional<GURL>& new_url) override {}
+      const std::optional<GURL>& new_url) override {}
   void SetPriority(net::RequestPriority priority,
                    int32_t intra_priority_value) override {}
   void PauseReadingBodyFromNet() override {}
diff --git a/fuchsia_web/webengine/browser/context_impl.cc b/fuchsia_web/webengine/browser/context_impl.cc
index 8f25b63f..d16068b 100644
--- a/fuchsia_web/webengine/browser/context_impl.cc
+++ b/fuchsia_web/webengine/browser/context_impl.cc
@@ -130,7 +130,7 @@
 
   // Verify the explicit sites filter error page content. If the parameter is
   // present, it will be provided to the FrameImpl after it is created below.
-  absl::optional<std::string> explicit_sites_filter_error_page;
+  std::optional<std::string> explicit_sites_filter_error_page;
   if (params.has_explicit_sites_filter_error_page()) {
     explicit_sites_filter_error_page =
         base::StringFromMemData(params.explicit_sites_filter_error_page());
diff --git a/fuchsia_web/webengine/browser/cookie_manager_impl.cc b/fuchsia_web/webengine/browser/cookie_manager_impl.cc
index 36f537ad..cfb6840 100644
--- a/fuchsia_web/webengine/browser/cookie_manager_impl.cc
+++ b/fuchsia_web/webengine/browser/cookie_manager_impl.cc
@@ -189,7 +189,7 @@
                           std::move(changes));
 
   if (url) {
-    absl::optional<std::string> maybe_name;
+    std::optional<std::string> maybe_name;
     if (name)
       maybe_name = *name;
     cookie_manager_->AddCookieChangeListener(GURL(*url), maybe_name,
diff --git a/fuchsia_web/webengine/browser/cookie_manager_impl_unittest.cc b/fuchsia_web/webengine/browser/cookie_manager_impl_unittest.cc
index cb8556b..b2ea261 100644
--- a/fuchsia_web/webengine/browser/cookie_manager_impl_unittest.cc
+++ b/fuchsia_web/webengine/browser/cookie_manager_impl_unittest.cc
@@ -7,6 +7,7 @@
 #include <map>
 #include <vector>
 
+#include <optional>
 #include "base/functional/bind.h"
 #include "base/run_loop.h"
 #include "base/strings/string_piece.h"
@@ -22,7 +23,6 @@
 #include "services/network/public/mojom/network_context.mojom.h"
 #include "services/network/test/fake_test_cert_verifier_params_factory.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -45,7 +45,7 @@
       /*secure=*/true,
       /*httponly*/ false, net::CookieSameSite::NO_RESTRICTION,
       net::COOKIE_PRIORITY_MEDIUM, /*same_party=*/false,
-      /*partition_key=*/absl::nullopt);
+      /*partition_key=*/std::nullopt);
 }
 
 class CookieManagerImplTest : public testing::Test {
@@ -101,8 +101,8 @@
   }
 
   // Synchronously fetches all cookies via the |cookie_manager_|.
-  // Returns a absl::nullopt if the iterator closes before a GetNext() returns.
-  absl::optional<std::vector<fuchsia::web::Cookie>> GetAllCookies() {
+  // Returns a std::nullopt if the iterator closes before a GetNext() returns.
+  std::optional<std::vector<fuchsia::web::Cookie>> GetAllCookies() {
     base::RunLoop get_cookies_loop;
     fuchsia::web::CookiesIteratorPtr cookies_iterator;
     cookies_iterator.set_error_handler([&](zx_status_t status) {
@@ -111,7 +111,7 @@
     });
     cookie_manager_.GetCookieList(nullptr, nullptr,
                                   cookies_iterator.NewRequest());
-    absl::optional<std::vector<fuchsia::web::Cookie>> cookies;
+    std::optional<std::vector<fuchsia::web::Cookie>> cookies;
     std::function<void(std::vector<fuchsia::web::Cookie>)> get_next_callback =
         [&](std::vector<fuchsia::web::Cookie> new_cookies) {
           if (!cookies.has_value()) {
@@ -160,18 +160,18 @@
   ~GetNextCookiesIteratorResult() = default;
 
   void ExpectSingleCookie(base::StringPiece name,
-                          absl::optional<base::StringPiece> value) {
+                          std::optional<base::StringPiece> value) {
     ExpectCookieUpdates({{name, value}});
   }
 
   void ExpectDeleteSingleCookie(base::StringPiece name) {
-    ExpectCookieUpdates({{name, absl::nullopt}});
+    ExpectCookieUpdates({{name, std::nullopt}});
   }
 
   // Specifies the cookie name/value pairs expected in the GetNext() results.
-  // Deletions expectations are specified by using absl::nullopt as the value.
+  // Deletions expectations are specified by using std::nullopt as the value.
   void ExpectCookieUpdates(
-      std::map<base::StringPiece, absl::optional<base::StringPiece>> expected) {
+      std::map<base::StringPiece, std::optional<base::StringPiece>> expected) {
     ASSERT_TRUE(result_.Wait());
     ASSERT_EQ(result_.Get().size(), expected.size());
     std::map<base::StringPiece, base::StringPiece> result_updates;
@@ -362,7 +362,7 @@
 
     GetNextCookiesIteratorResult global_updates(global_changes.get());
     global_updates.ExpectCookieUpdates(
-        {{kCookieName1, absl::nullopt}, {kCookieName2, absl::nullopt}});
+        {{kCookieName1, std::nullopt}, {kCookieName2, std::nullopt}});
   }
 }
 
diff --git a/fuchsia_web/webengine/browser/fake_semantics_manager.h b/fuchsia_web/webengine/browser/fake_semantics_manager.h
index 9d048695..fd89213 100644
--- a/fuchsia_web/webengine/browser/fake_semantics_manager.h
+++ b/fuchsia_web/webengine/browser/fake_semantics_manager.h
@@ -9,9 +9,9 @@
 #include <fuchsia/accessibility/semantics/cpp/fidl_test_base.h>
 #include <lib/fidl/cpp/binding.h>
 
+#include <optional>
 #include "base/functional/callback.h"
 #include "fuchsia_web/webengine/browser/fake_semantic_tree.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class FakeSemanticsManager : public fuchsia::accessibility::semantics::testing::
                                  SemanticsManager_TestBase {
@@ -75,7 +75,7 @@
   // which can support many.
   FakeSemanticTree semantic_tree_;
 
-  absl::optional<uint32_t> hit_test_result_;
+  std::optional<uint32_t> hit_test_result_;
   int32_t num_actions_handled_ = 0;
   int32_t num_actions_unhandled_ = 0;
   int32_t expected_num_actions_ = 0;
diff --git a/fuchsia_web/webengine/browser/favicon_browsertest.cc b/fuchsia_web/webengine/browser/favicon_browsertest.cc
index 8ddaaa2..f5f702b 100644
--- a/fuchsia_web/webengine/browser/favicon_browsertest.cc
+++ b/fuchsia_web/webengine/browser/favicon_browsertest.cc
@@ -43,7 +43,7 @@
   ASSERT_TRUE(favicon.has_height());
   EXPECT_EQ(favicon.height(), expected_height);
   ASSERT_TRUE(favicon.has_data());
-  absl::optional<std::string> data = base::StringFromMemBuffer(favicon.data());
+  std::optional<std::string> data = base::StringFromMemBuffer(favicon.data());
   ASSERT_TRUE(data.has_value());
   size_t expected_size = expected_width * expected_height * sizeof(uint32_t);
   ASSERT_EQ(data->size(), expected_size);
diff --git a/fuchsia_web/webengine/browser/frame_impl.cc b/fuchsia_web/webengine/browser/frame_impl.cc
index 67ba5e2..51e83f1 100644
--- a/fuchsia_web/webengine/browser/frame_impl.cc
+++ b/fuchsia_web/webengine/browser/frame_impl.cc
@@ -253,20 +253,20 @@
       nullptr);
 }
 
-absl::optional<url::Origin> ParseAndValidateWebOrigin(
+std::optional<url::Origin> ParseAndValidateWebOrigin(
     const std::string& origin_str) {
   GURL origin_url(origin_str);
   if (!origin_url.username().empty() || !origin_url.password().empty() ||
       !origin_url.query().empty() || !origin_url.ref().empty()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (!origin_url.path().empty() && origin_url.path() != "/")
-    return absl::nullopt;
+    return std::nullopt;
 
   auto origin = url::Origin::Create(origin_url);
   if (origin.opaque())
-    return absl::nullopt;
+    return std::nullopt;
 
   return origin;
 }
@@ -378,7 +378,7 @@
   }
 
   std::unique_ptr<content::AudioStreamBrokerFactory> base_factory_;
-  absl::optional<fuchsia::media::AudioRenderUsage> output_usage_;
+  std::optional<fuchsia::media::AudioRenderUsage> output_usage_;
   base::WeakPtrFactory<AudioStreamBrokerFactory> weak_factory_{this};
 };
 
@@ -531,7 +531,7 @@
     return;
   }
 
-  absl::optional<std::u16string> script_utf16 =
+  std::optional<std::u16string> script_utf16 =
       base::ReadUTF8FromVMOAsUTF16(script);
   if (!script_utf16) {
     callback(fpromise::error(fuchsia::web::FrameError::BUFFER_NOT_UTF8));
@@ -945,7 +945,7 @@
     return;
   }
 
-  absl::optional<std::string> script_as_string =
+  std::optional<std::string> script_as_string =
       base::StringFromMemBuffer(script);
   if (!script_as_string) {
     LOG(ERROR) << "Couldn't read script from buffer.";
@@ -1003,11 +1003,11 @@
     return;
   }
 
-  absl::optional<std::u16string> origin_utf16;
+  std::optional<std::u16string> origin_utf16;
   if (origin != kWildcardOrigin)
     origin_utf16 = base::UTF8ToUTF16(origin);
 
-  absl::optional<std::u16string> data_utf16 =
+  std::optional<std::u16string> data_utf16 =
       base::ReadUTF8FromVMOAsUTF16(message.data());
   if (!data_utf16) {
     callback(fpromise::error(fuchsia::web::FrameError::BUFFER_NOT_UTF8));
diff --git a/fuchsia_web/webengine/browser/frame_impl.h b/fuchsia_web/webengine/browser/frame_impl.h
index f078887..0e15bea 100644
--- a/fuchsia_web/webengine/browser/frame_impl.h
+++ b/fuchsia_web/webengine/browser/frame_impl.h
@@ -19,6 +19,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/fuchsia/scoped_fx_logger.h"
 #include "base/gtest_prod_util.h"
 #include "base/logging.h"
@@ -35,7 +36,6 @@
 #include "fuchsia_web/webengine/browser/navigation_controller_impl.h"
 #include "fuchsia_web/webengine/browser/theme_manager.h"
 #include "fuchsia_web/webengine/web_engine_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/web_preferences/web_preferences.h"
 #include "ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia_impl.h"
 #include "ui/aura/window_tree_host.h"
@@ -116,7 +116,7 @@
   // empty, the default error page will be used.
   void EnableExplicitSitesFilter(std::string error_page);
 
-  const absl::optional<std::string>& explicit_sites_filter_error_page() const {
+  const std::optional<std::string>& explicit_sites_filter_error_page() const {
     return explicit_sites_filter_error_page_;
   }
 
@@ -387,8 +387,8 @@
   std::unique_ptr<ui::AccessibilityBridgeFuchsiaImpl> accessibility_bridge_;
 
   // Test settings.
-  absl::optional<gfx::Size> window_size_for_test_;
-  absl::optional<float> device_scale_factor_for_test_;
+  std::optional<gfx::Size> window_size_for_test_;
+  std::optional<float> device_scale_factor_for_test_;
 
   EventFilter event_filter_;
   NavigationControllerImpl navigation_controller_;
@@ -418,7 +418,7 @@
   // The error page to be displayed when a navigation to an explicit site is
   // filtered. Explicit sites are filtered if it has a value. If set to the
   // empty string, the default error page will be displayed.
-  absl::optional<std::string> explicit_sites_filter_error_page_;
+  std::optional<std::string> explicit_sites_filter_error_page_;
 
   // Used to publish Frame details to Inspect.
   inspect::Node inspect_node_;
diff --git a/fuchsia_web/webengine/browser/frame_impl_browsertest.cc b/fuchsia_web/webengine/browser/frame_impl_browsertest.cc
index 957f84fd..a3fcade 100644
--- a/fuchsia_web/webengine/browser/frame_impl_browsertest.cc
+++ b/fuchsia_web/webengine/browser/frame_impl_browsertest.cc
@@ -921,7 +921,7 @@
                                        url.spec()));
   frame.navigation_listener().RunUntilUrlAndTitleEquals(url, "done");
 
-  absl::optional<base::Value> default_dpr =
+  std::optional<base::Value> default_dpr =
       ExecuteJavaScript(frame.ptr().get(), "window.devicePixelRatio");
   ASSERT_TRUE(default_dpr);
 
@@ -933,7 +933,7 @@
   settings.set_page_scale(kZoomInScale);
   frame->SetContentAreaSettings(std::move(settings));
 
-  absl::optional<base::Value> scaled_dpr =
+  std::optional<base::Value> scaled_dpr =
       ExecuteJavaScript(frame.ptr().get(), "window.devicePixelRatio");
   ASSERT_TRUE(scaled_dpr);
 
@@ -949,7 +949,7 @@
                                        url2.spec()));
   frame.navigation_listener().RunUntilUrlAndTitleEquals(url2, "done");
 
-  absl::optional<base::Value> dpr_after_navigation =
+  std::optional<base::Value> dpr_after_navigation =
       ExecuteJavaScript(frame.ptr().get(), "window.devicePixelRatio");
   ASSERT_TRUE(scaled_dpr);
 
@@ -962,7 +962,7 @@
   settings2.set_page_scale(kDefaultScale);
   frame->SetContentAreaSettings(std::move(settings2));
 
-  absl::optional<base::Value> dpr_after_reset =
+  std::optional<base::Value> dpr_after_reset =
       ExecuteJavaScript(frame.ptr().get(), "window.devicePixelRatio");
   ASSERT_TRUE(dpr_after_reset);
 
@@ -974,7 +974,7 @@
   settings3.set_page_scale(kZoomOutScale);
   frame->SetContentAreaSettings(std::move(settings3));
 
-  absl::optional<base::Value> zoomed_out_dpr =
+  std::optional<base::Value> zoomed_out_dpr =
       ExecuteJavaScript(frame.ptr().get(), "window.devicePixelRatio");
   ASSERT_TRUE(zoomed_out_dpr);
 
@@ -998,7 +998,7 @@
                                        url.spec()));
   frame2.navigation_listener().RunUntilUrlAndTitleEquals(url, "done");
 
-  absl::optional<base::Value> frame2_dpr =
+  std::optional<base::Value> frame2_dpr =
       ExecuteJavaScript(frame2.ptr().get(), "window.devicePixelRatio");
   ASSERT_TRUE(frame2_dpr);
 
diff --git a/fuchsia_web/webengine/browser/input_browsertest.cc b/fuchsia_web/webengine/browser/input_browsertest.cc
index e89a12e0e..cf0ef1a 100644
--- a/fuchsia_web/webengine/browser/input_browsertest.cc
+++ b/fuchsia_web/webengine/browser/input_browsertest.cc
@@ -251,7 +251,7 @@
     frame_for_test_.navigation_listener().RunUntilTitleEquals(
         base::NumberToString(expected.size()));
 
-    absl::optional<base::Value> actual =
+    std::optional<base::Value> actual =
         ExecuteJavaScript(frame_for_test_.ptr().get(), kKeyDicts);
     EXPECT_EQ(*actual, base::Value(std::move(expected)));
   }
@@ -264,13 +264,13 @@
   }
 
   // Used to publish fake services.
-  absl::optional<base::TestComponentContextForProcess> component_context_;
+  std::optional<base::TestComponentContextForProcess> component_context_;
 
   FrameForTest frame_for_test_;
   ScenicTestHelper scenic_test_helper_;
-  absl::optional<FakeKeyboard> keyboard_service_;
+  std::optional<FakeKeyboard> keyboard_service_;
   base::test::ScopedFeatureList scoped_feature_list_;
-  absl::optional<
+  std::optional<
       NeverConnectedChecker<fuchsia_input_virtualkeyboard::ControllerCreator>>
       virtual_keyboard_checker_;
 };
@@ -592,7 +592,7 @@
     keyboard_input_checker_.emplace(component_context_->additional_services());
   }
 
-  absl::optional<NeverConnectedChecker<fuchsia_ui_input3::Keyboard>>
+  std::optional<NeverConnectedChecker<fuchsia_ui_input3::Keyboard>>
       keyboard_input_checker_;
 };
 
diff --git a/fuchsia_web/webengine/browser/media_browsertest.cc b/fuchsia_web/webengine/browser/media_browsertest.cc
index 8bac4a8..8928863 100644
--- a/fuchsia_web/webengine/browser/media_browsertest.cc
+++ b/fuchsia_web/webengine/browser/media_browsertest.cc
@@ -6,6 +6,7 @@
 
 #include <fuchsia/mediacodec/cpp/fidl_test_base.h>
 
+#include <optional>
 #include "base/files/file_path.h"
 #include "base/fuchsia/scoped_service_binding.h"
 #include "base/fuchsia/test_component_context_for_process.h"
@@ -17,7 +18,6 @@
 #include "fuchsia_web/webengine/features.h"
 #include "fuchsia_web/webengine/test/test_data.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -84,7 +84,7 @@
   }
 
   // Used to disconnect fuchsia.mediacodec.CodecFactory.
-  absl::optional<base::TestComponentContextForProcess> component_context_;
+  std::optional<base::TestComponentContextForProcess> component_context_;
 };
 
 // Verify that a codec only supported by a software decoder is reported as
diff --git a/fuchsia_web/webengine/browser/media_player_impl.cc b/fuchsia_web/webengine/browser/media_player_impl.cc
index 334f1b87..0274b06 100644
--- a/fuchsia_web/webengine/browser/media_player_impl.cc
+++ b/fuchsia_web/webengine/browser/media_player_impl.cc
@@ -211,7 +211,7 @@
 }
 
 void MediaPlayerImpl::MediaSessionMetadataChanged(
-    const absl::optional<media_session::MediaMetadata>& metadata_mojo) {
+    const std::optional<media_session::MediaMetadata>& metadata_mojo) {
   fuchsia_media::Metadata metadata;
   if (metadata_mojo) {
     AddMetadata(fuchsia_media::kMetadataLabelTitle, metadata_mojo->title,
@@ -247,7 +247,7 @@
 }
 
 void MediaPlayerImpl::MediaSessionPositionChanged(
-    const absl::optional<media_session::MediaPosition>& position) {
+    const std::optional<media_session::MediaPosition>& position) {
   // TODO(https://crbug.com/879317): Implement media position changes.
   NOTIMPLEMENTED_LOG_ONCE();
 }
@@ -259,7 +259,7 @@
     return;
   // std::exchange(foo, {}) returns the contents of |foo|, while ensuring that
   // |foo| is reset to the initial/empty state.
-  std::exchange(pending_info_change_callback_, absl::nullopt)
+  std::exchange(pending_info_change_callback_, std::nullopt)
       ->Reply(std::exchange(pending_info_delta_, {}));
 }
 
diff --git a/fuchsia_web/webengine/browser/media_player_impl.h b/fuchsia_web/webengine/browser/media_player_impl.h
index f128ee7e..f1c781d 100644
--- a/fuchsia_web/webengine/browser/media_player_impl.h
+++ b/fuchsia_web/webengine/browser/media_player_impl.h
@@ -8,11 +8,11 @@
 #include <fidl/fuchsia.media.sessions2/cpp/fidl.h>
 #include <string>
 
+#include <optional>
 #include "base/functional/callback.h"
 #include "fuchsia_web/webengine/web_engine_export.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "services/media_session/public/mojom/media_session.mojom.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace content {
 class MediaSession;
@@ -63,7 +63,7 @@
   void MediaSessionInfoChanged(
       media_session::mojom::MediaSessionInfoPtr info) override;
   void MediaSessionMetadataChanged(
-      const absl::optional<media_session::MediaMetadata>& metadata) override;
+      const std::optional<media_session::MediaMetadata>& metadata) override;
   void MediaSessionActionsChanged(
       const std::vector<media_session::mojom::MediaSessionAction>& action)
       override;
@@ -72,7 +72,7 @@
                            std::vector<media_session::MediaImage>>& images)
       override;
   void MediaSessionPositionChanged(
-      const absl::optional<media_session::MediaPosition>& position) override;
+      const std::optional<media_session::MediaPosition>& position) override;
 
   // Sends changes accumulated in |pending_info_delta_|, if any, to the
   // |pending_info_change_callback_|, if it is set.
@@ -95,7 +95,7 @@
   mojo::Receiver<media_session::mojom::MediaSessionObserver> observer_receiver_;
 
   // Pending PlayerInfo deltas and info-change callback.
-  absl::optional<WatchInfoChangeCompleter::Async> pending_info_change_callback_;
+  std::optional<WatchInfoChangeCompleter::Async> pending_info_change_callback_;
   fuchsia_media_sessions2::PlayerInfoDelta pending_info_delta_;
 };
 
diff --git a/fuchsia_web/webengine/browser/media_player_impl_unittest.cc b/fuchsia_web/webengine/browser/media_player_impl_unittest.cc
index f01e24a..b481c29 100644
--- a/fuchsia_web/webengine/browser/media_player_impl_unittest.cc
+++ b/fuchsia_web/webengine/browser/media_player_impl_unittest.cc
@@ -329,7 +329,7 @@
   // Calling WatchInfoChange() now should succeed, but not immediately return
   // any new data.
   base::RunLoop change_loop;
-  absl::optional<fuchsia_media_sessions2::PlayerState> state_after_change;
+  std::optional<fuchsia_media_sessions2::PlayerState> state_after_change;
 
   player_->WatchInfoChange().Then(
       [&change_loop, &state_after_change](
diff --git a/fuchsia_web/webengine/browser/message_port.cc b/fuchsia_web/webengine/browser/message_port.cc
index 8fda5e2..8efbbd6 100644
--- a/fuchsia_web/webengine/browser/message_port.cc
+++ b/fuchsia_web/webengine/browser/message_port.cc
@@ -30,14 +30,14 @@
 // Converts a fuchsia::web::WebMessage to a BlinkMessage.
 // An empty result indicates that conversion was successful.
 // Data validation errors are returned as a FrameError.
-absl::optional<fuchsia::web::FrameError> BlinkMessageFromFidl(
+std::optional<fuchsia::web::FrameError> BlinkMessageFromFidl(
     fuchsia::web::WebMessage fidl_message,
     BlinkMessage* blink_message) {
   if (!fidl_message.has_data()) {
     return fuchsia::web::FrameError::NO_DATA_IN_MESSAGE;
   }
 
-  absl::optional<std::u16string> data_utf16 =
+  std::optional<std::u16string> data_utf16 =
       base::ReadUTF8FromVMOAsUTF16(fidl_message.data());
   if (!data_utf16) {
     return fuchsia::web::FrameError::BUFFER_NOT_UTF8;
@@ -67,7 +67,7 @@
     }
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 // Defines a MessagePortAdapter, which translates and routes messages between a
@@ -103,9 +103,9 @@
 
   // Returns the next messagefrom Blink, or an empty value if there
   // are no more messages in the incoming queue.
-  absl::optional<fuchsia::web::WebMessage> GetNextBlinkMessage() {
+  std::optional<fuchsia::web::WebMessage> GetNextBlinkMessage() {
     if (message_queue_.empty())
-      return absl::nullopt;
+      return std::nullopt;
 
     return std::move(message_queue_.front());
   }
@@ -118,7 +118,7 @@
  private:
   // blink::WebMessagePort::MessageReceiver implementation:
   bool OnMessage(BlinkMessage message) override {
-    absl::optional<fuchsia::web::WebMessage> message_converted =
+    std::optional<fuchsia::web::WebMessage> message_converted =
         FidlWebMessageFromBlink(std::move(message),
                                 TransferableHostType::kLocal);
     if (!message_converted) {
@@ -178,7 +178,7 @@
 
   void OnMessageReceived(fuchsia::web::WebMessage message) {
     BlinkMessage blink_message;
-    absl::optional<fuchsia::web::FrameError> result =
+    std::optional<fuchsia::web::FrameError> result =
         BlinkMessageFromFidl(std::move(message), &blink_message);
     if (result) {
       LOG(WARNING) << "Received bad message, error: "
@@ -205,7 +205,7 @@
 
   // MessagePortAdapter implementation.
   void DeliverMessageToFidl() override {
-    absl::optional<fuchsia::web::WebMessage> message = GetNextBlinkMessage();
+    std::optional<fuchsia::web::WebMessage> message = GetNextBlinkMessage();
     if (!message)
       return;
 
@@ -259,7 +259,7 @@
     if (!pending_receive_message_callback_)
       return;
 
-    absl::optional<fuchsia::web::WebMessage> message = GetNextBlinkMessage();
+    std::optional<fuchsia::web::WebMessage> message = GetNextBlinkMessage();
     if (!message)
       return;
 
@@ -272,7 +272,7 @@
   void PostMessage(fuchsia::web::WebMessage message,
                    PostMessageCallback callback) override {
     BlinkMessage blink_message;
-    absl::optional<fuchsia::web::FrameError> status =
+    std::optional<fuchsia::web::FrameError> status =
         BlinkMessageFromFidl(std::move(message), &blink_message);
 
     if (status) {
@@ -339,7 +339,7 @@
   return adapter->NewBinding();
 }
 
-absl::optional<fuchsia::web::WebMessage> FidlWebMessageFromBlink(
+std::optional<fuchsia::web::WebMessage> FidlWebMessageFromBlink(
     BlinkMessage blink_message,
     TransferableHostType port_type) {
   fuchsia::web::WebMessage fidl_message;
@@ -370,7 +370,7 @@
   std::u16string data_utf16 = std::move(blink_message.data);
   std::string data_utf8;
   if (!base::UTF16ToUTF8(data_utf16.data(), data_utf16.size(), &data_utf8))
-    return absl::nullopt;
+    return std::nullopt;
 
   base::STLClearObject(&data_utf16);
 
@@ -378,7 +378,7 @@
   fuchsia::mem::Buffer data_buffer =
       base::MemBufferFromString(data_utf8, kBufferVmoName);
   if (!data_buffer.vmo)
-    return absl::nullopt;
+    return std::nullopt;
 
   fidl_message.set_data(std::move(data_buffer));
   return fidl_message;
diff --git a/fuchsia_web/webengine/browser/message_port.h b/fuchsia_web/webengine/browser/message_port.h
index d13136d..4aa2ecc 100644
--- a/fuchsia_web/webengine/browser/message_port.h
+++ b/fuchsia_web/webengine/browser/message_port.h
@@ -9,7 +9,7 @@
 #include <lib/fidl/cpp/interface_handle.h>
 #include <lib/fidl/cpp/interface_request.h>
 
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include <optional>
 #include "third_party/blink/public/common/messaging/web_message_port.h"
 
 // Creates a connected MessagePort from a FIDL MessagePort request and
@@ -38,7 +38,7 @@
 };
 
 // Converts a BlinkMessage to a fuchsia::web::WebMessage.
-absl::optional<fuchsia::web::WebMessage> FidlWebMessageFromBlink(
+std::optional<fuchsia::web::WebMessage> FidlWebMessageFromBlink(
     blink::WebMessagePort::Message blink_message,
     TransferableHostType port_type);
 
diff --git a/fuchsia_web/webengine/browser/mock_virtual_keyboard.h b/fuchsia_web/webengine/browser/mock_virtual_keyboard.h
index b6bc920..374f6fe8 100644
--- a/fuchsia_web/webengine/browser/mock_virtual_keyboard.h
+++ b/fuchsia_web/webengine/browser/mock_virtual_keyboard.h
@@ -8,11 +8,11 @@
 #include <fidl/fuchsia.input.virtualkeyboard/cpp/fidl.h>
 #include <lib/fidl/cpp/binding.h>
 
+#include <optional>
 #include "base/fuchsia/scoped_service_binding.h"
 #include "base/fuchsia/test_component_context_for_process.h"
 #include "base/functional/callback.h"
 #include "testing/gmock/include/gmock/gmock.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class MockVirtualKeyboardController
     : public fidl::Server<fuchsia_input_virtualkeyboard::Controller> {
@@ -48,12 +48,12 @@
   void WatchVisibility(WatchVisibilityCompleter::Sync& completer) final;
 
   base::OnceClosure on_watch_visibility_;
-  absl::optional<fidl::Server<fuchsia_input_virtualkeyboard::Controller>::
-                     WatchVisibilityCompleter::Async>
+  std::optional<fidl::Server<fuchsia_input_virtualkeyboard::Controller>::
+                    WatchVisibilityCompleter::Async>
       watch_visibility_completer_;
   fuchsia_ui_views::ViewRef view_ref_;
   fuchsia_input_virtualkeyboard::TextType text_type_;
-  absl::optional<fidl::ServerBinding<fuchsia_input_virtualkeyboard::Controller>>
+  std::optional<fidl::ServerBinding<fuchsia_input_virtualkeyboard::Controller>>
       binding_;
 };
 
diff --git a/fuchsia_web/webengine/browser/request_monitoring_browsertest.cc b/fuchsia_web/webengine/browser/request_monitoring_browsertest.cc
index e4ce6855..609c85cf 100644
--- a/fuchsia_web/webengine/browser/request_monitoring_browsertest.cc
+++ b/fuchsia_web/webengine/browser/request_monitoring_browsertest.cc
@@ -290,7 +290,7 @@
 
   std::vector<fuchsia::web::UrlRequestRewrite> rewrites;
   rewrites.push_back(CreateRewriteAddHeaders("Test", "Value"));
-  rewrites.push_back(CreateRewriteRemoveHeader(absl::nullopt, "Test"));
+  rewrites.push_back(CreateRewriteRemoveHeader(std::nullopt, "Test"));
   fuchsia::web::UrlRequestRewriteRule rule;
   rule.set_rewrites(std::move(rewrites));
   std::vector<fuchsia::web::UrlRequestRewriteRule> rules;
@@ -330,7 +330,7 @@
   std::vector<fuchsia::web::UrlRequestRewrite> rewrites;
   rewrites.push_back(CreateRewriteAddHeaders("Test", "Value"));
   rewrites.push_back(
-      CreateRewriteRemoveHeader(absl::make_optional("[pattern]"), "Test"));
+      CreateRewriteRemoveHeader(std::make_optional("[pattern]"), "Test"));
   fuchsia::web::UrlRequestRewriteRule rule;
   rule.set_rewrites(std::move(rewrites));
   std::vector<fuchsia::web::UrlRequestRewriteRule> rules;
diff --git a/fuchsia_web/webengine/browser/theme_manager.cc b/fuchsia_web/webengine/browser/theme_manager.cc
index 3413e3c..73f1ac6 100644
--- a/fuchsia_web/webengine/browser/theme_manager.cc
+++ b/fuchsia_web/webengine/browser/theme_manager.cc
@@ -137,7 +137,7 @@
        settings.theme().theme_type() == ThemeType::LIGHT)) {
     system_theme_ = settings.theme().theme_type();
   } else {
-    system_theme_ = absl::nullopt;
+    system_theme_ = std::nullopt;
   }
 
   web_contents_->OnWebPreferencesChanged();
diff --git a/fuchsia_web/webengine/browser/theme_manager.h b/fuchsia_web/webengine/browser/theme_manager.h
index b44299f..6c01c55 100644
--- a/fuchsia_web/webengine/browser/theme_manager.h
+++ b/fuchsia_web/webengine/browser/theme_manager.h
@@ -9,10 +9,10 @@
 #include <fuchsia/web/cpp/fidl.h>
 #include <lib/sys/cpp/component_context.h>
 
+#include <optional>
 #include "base/fuchsia/process_context.h"
 #include "content/public/browser/web_contents.h"
 #include "fuchsia_web/webengine/web_engine_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/web_preferences/web_preferences.h"
 
 class WEB_ENGINE_EXPORT ThemeManager {
@@ -48,8 +48,8 @@
 
   bool observed_display_service_error_ = false;
   bool did_receive_first_watch_result_ = false;
-  absl::optional<fuchsia::settings::ThemeType> requested_theme_;
-  absl::optional<fuchsia::settings::ThemeType> system_theme_;
+  std::optional<fuchsia::settings::ThemeType> requested_theme_;
+  std::optional<fuchsia::settings::ThemeType> system_theme_;
   content::WebContents* web_contents_;
   fuchsia::settings::DisplayPtr display_service_;
   base::OnceClosure on_display_error_;
diff --git a/fuchsia_web/webengine/browser/theme_manager_browsertest.cc b/fuchsia_web/webengine/browser/theme_manager_browsertest.cc
index 0e5825d..d816695 100644
--- a/fuchsia_web/webengine/browser/theme_manager_browsertest.cc
+++ b/fuchsia_web/webengine/browser/theme_manager_browsertest.cc
@@ -4,6 +4,7 @@
 
 #include <fuchsia/settings/cpp/fidl_test_base.h>
 
+#include <optional>
 #include "base/fuchsia/scoped_service_binding.h"
 #include "base/fuchsia/test_component_context_for_process.h"
 #include "base/json/json_writer.h"
@@ -19,7 +20,6 @@
 #include "fuchsia_web/webengine/test/test_data.h"
 #include "fuchsia_web/webengine/test/web_engine_browser_test.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -80,7 +80,7 @@
     theme.set_theme_type(theme_type);
     settings.set_theme(std::move(theme));
     (*watch_callback_)(std::move(settings));
-    watch_callback_ = absl::nullopt;
+    watch_callback_ = std::nullopt;
     base::RunLoop().RunUntilIdle();
   }
 
@@ -127,13 +127,13 @@
     ADD_FAILURE() << "Unexpected call: " << name;
   }
 
-  absl::optional<base::TestComponentContextForProcess> component_context_;
-  absl::optional<base::ScopedServiceBinding<fuchsia::settings::Display>>
+  std::optional<base::TestComponentContextForProcess> component_context_;
+  std::optional<base::ScopedServiceBinding<fuchsia::settings::Display>>
       display_binding_;
   FrameForTest frame_;
 
   base::OnceClosure on_watch_closure_;
-  absl::optional<WatchCallback> watch_callback_;
+  std::optional<WatchCallback> watch_callback_;
 };
 
 IN_PROC_BROWSER_TEST_F(ThemeManagerTest, Default) {
@@ -166,7 +166,7 @@
 
   ASSERT_TRUE(display_binding_->has_clients());
 
-  display_binding_ = absl::nullopt;
+  display_binding_ = std::nullopt;
   base::RunLoop().RunUntilIdle();
 
   ASSERT_FALSE(display_binding_);
diff --git a/fuchsia_web/webengine/browser/url_request_rewrite_type_converters.cc b/fuchsia_web/webengine/browser/url_request_rewrite_type_converters.cc
index 931182a..4b3fdd4 100644
--- a/fuchsia_web/webengine/browser/url_request_rewrite_type_converters.cc
+++ b/fuchsia_web/webengine/browser/url_request_rewrite_type_converters.cc
@@ -49,7 +49,7 @@
     url_rewrite::mojom::UrlRequestRewriteRemoveHeaderPtr remove_header =
         url_rewrite::mojom::UrlRequestRewriteRemoveHeader::New();
     if (input.has_query_pattern())
-      remove_header->query_pattern = absl::make_optional(input.query_pattern());
+      remove_header->query_pattern = std::make_optional(input.query_pattern());
     if (input.has_header_name()) {
       remove_header->header_name =
           std::string(BytesAsString(input.header_name()));
@@ -177,7 +177,7 @@
     }
 
     if (input.has_schemes_filter())
-      rule->schemes_filter = absl::make_optional(input.schemes_filter());
+      rule->schemes_filter = std::make_optional(input.schemes_filter());
 
     if (input.has_rewrites()) {
       rule->actions =
diff --git a/fuchsia_web/webengine/browser/url_request_rewrite_type_converters_unittest.cc b/fuchsia_web/webengine/browser/url_request_rewrite_type_converters_unittest.cc
index 0359ebb..6763122 100644
--- a/fuchsia_web/webengine/browser/url_request_rewrite_type_converters_unittest.cc
+++ b/fuchsia_web/webengine/browser/url_request_rewrite_type_converters_unittest.cc
@@ -51,7 +51,7 @@
 TEST(UrlRequestRewriteTypeConvertersTest, ConvertRemoveHeader) {
   url_rewrite::mojom::UrlRequestRewriteRulesPtr rules =
       ConvertFuchsiaRulesToMojom(
-          CreateRewriteRemoveHeader(absl::make_optional("Test"), "Header"));
+          CreateRewriteRemoveHeader(std::make_optional("Test"), "Header"));
   ASSERT_EQ(rules->rules.size(), 1u);
   ASSERT_FALSE(rules->rules[0]->hosts_filter);
   ASSERT_FALSE(rules->rules[0]->schemes_filter);
@@ -66,7 +66,7 @@
 
   // Create a RemoveHeader rewrite with no pattern.
   rules = ConvertFuchsiaRulesToMojom(
-      CreateRewriteRemoveHeader(absl::nullopt, "Header"));
+      CreateRewriteRemoveHeader(std::nullopt, "Header"));
   ASSERT_EQ(rules->rules.size(), 1u);
   ASSERT_FALSE(rules->rules[0]->hosts_filter);
   ASSERT_FALSE(rules->rules[0]->schemes_filter);
diff --git a/fuchsia_web/webengine/browser/virtual_keyboard_browsertest.cc b/fuchsia_web/webengine/browser/virtual_keyboard_browsertest.cc
index bbc770b..9386bbf 100644
--- a/fuchsia_web/webengine/browser/virtual_keyboard_browsertest.cc
+++ b/fuchsia_web/webengine/browser/virtual_keyboard_browsertest.cc
@@ -118,7 +118,7 @@
     // Distance to click from the top/left extents of an input field.
     constexpr int kInputFieldClickInset = 8;
 
-    absl::optional<base::Value> result = ExecuteJavaScript(
+    std::optional<base::Value> result = ExecuteJavaScript(
         frame_for_test_.ptr().get(),
         base::StringPrintf("getPointInsideText('%.*s')",
                            base::saturated_cast<int>(id.length()), id.data()));
@@ -140,12 +140,12 @@
   ScenicTestHelper scenic_test_helper_;
   base::test::ScopedFeatureList scoped_feature_list_;
 
-  absl::optional<EnsureConnectedChecker<fuchsia_ui_input3::Keyboard>>
+  std::optional<EnsureConnectedChecker<fuchsia_ui_input3::Keyboard>>
       keyboard_input_checker_;
 
   // Fake virtual keyboard services for the InputMethod to use.
-  absl::optional<base::TestComponentContextForProcess> component_context_;
-  absl::optional<MockVirtualKeyboardControllerCreator> controller_creator_;
+  std::optional<base::TestComponentContextForProcess> component_context_;
+  std::optional<MockVirtualKeyboardControllerCreator> controller_creator_;
   std::unique_ptr<MockVirtualKeyboardController> controller_;
 
   content::WebContents* web_contents_ = nullptr;
diff --git a/fuchsia_web/webengine/browser/web_engine_browser_main_parts.cc b/fuchsia_web/webengine/browser/web_engine_browser_main_parts.cc
index 69388fd..98ca4c0 100644
--- a/fuchsia_web/webengine/browser/web_engine_browser_main_parts.cc
+++ b/fuchsia_web/webengine/browser/web_engine_browser_main_parts.cc
@@ -139,7 +139,7 @@
   std::string cdm_data_directory =
       command_line->GetSwitchValueASCII(switches::kCdmDataDirectory);
 
-  absl::optional<uint64_t> cdm_data_quota_bytes;
+  std::optional<uint64_t> cdm_data_quota_bytes;
   if (command_line->HasSwitch(switches::kCdmDataQuotaBytes)) {
     uint64_t value = 0;
     CHECK(base::StringToUint64(
diff --git a/fuchsia_web/webengine/browser/web_engine_content_browser_client.cc b/fuchsia_web/webengine/browser/web_engine_content_browser_client.cc
index 5da496b..ccbc05b 100644
--- a/fuchsia_web/webengine/browser/web_engine_content_browser_client.cc
+++ b/fuchsia_web/webengine/browser/web_engine_content_browser_client.cc
@@ -237,7 +237,7 @@
     RegisterNonNetworkSubresourceURLLoaderFactories(
         int render_process_id,
         int render_frame_id,
-        const absl::optional<url::Origin>& request_initiator_origin,
+        const std::optional<url::Origin>& request_initiator_origin,
         NonNetworkURLLoaderFactoryMap* factories) {
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kEnableContentDirectories)) {
@@ -319,7 +319,7 @@
         navigation_handle, frame_impl->navigation_policy_handler()));
   }
 
-  const absl::optional<std::string>& explicit_sites_filter_error_page =
+  const std::optional<std::string>& explicit_sites_filter_error_page =
       frame_impl->explicit_sites_filter_error_page();
 
   if (explicit_sites_filter_error_page) {
diff --git a/fuchsia_web/webengine/browser/web_engine_content_browser_client.h b/fuchsia_web/webengine/browser/web_engine_content_browser_client.h
index f9b382a..716441d 100644
--- a/fuchsia_web/webengine/browser/web_engine_content_browser_client.h
+++ b/fuchsia_web/webengine/browser/web_engine_content_browser_client.h
@@ -44,7 +44,7 @@
   void RegisterNonNetworkSubresourceURLLoaderFactories(
       int render_process_id,
       int render_frame_id,
-      const absl::optional<url::Origin>& request_initiator_origin,
+      const std::optional<url::Origin>& request_initiator_origin,
       NonNetworkURLLoaderFactoryMap* factories) override;
   bool ShouldEnableStrictSiteIsolation() override;
   void AppendExtraCommandLineSwitches(base::CommandLine* command_line,
diff --git a/fuchsia_web/webengine/browser/web_engine_devtools_controller.cc b/fuchsia_web/webengine/browser/web_engine_devtools_controller.cc
index d08768eb..daa8883 100644
--- a/fuchsia_web/webengine/browser/web_engine_devtools_controller.cc
+++ b/fuchsia_web/webengine/browser/web_engine_devtools_controller.cc
@@ -9,6 +9,7 @@
 #include <lib/sys/cpp/component_context.h>
 #include <vector>
 
+#include <optional>
 #include "base/command_line.h"
 #include "base/containers/flat_set.h"
 #include "base/fuchsia/process_context.h"
@@ -22,7 +23,6 @@
 #include "net/base/net_errors.h"
 #include "net/base/port_util.h"
 #include "net/socket/tcp_server_socket.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -45,7 +45,7 @@
     auto socket =
         std::make_unique<net::TCPServerSocket>(nullptr, net::NetLogSource());
     int error = socket->Listen(ip_end_point_, kTcpListenBackLog,
-                               /*ipv6_only=*/absl::nullopt);
+                               /*ipv6_only=*/std::nullopt);
     if (error != net::OK) {
       LOG(WARNING) << "Failed to start the HTTP debugger service. "
                    << net::ErrorToString(error);
@@ -186,7 +186,7 @@
   bool is_remote_debugging_started_ = false;
 
   // Currently active DevTools port. Set to 0 on service startup error.
-  absl::optional<uint16_t> devtools_port_;
+  std::optional<uint16_t> devtools_port_;
 
   // Set of Frames' content::WebContents which are remotely debuggable.
   base::flat_set<content::WebContents*> debuggable_contents_;
@@ -247,7 +247,7 @@
   }
 
   // Currently active DevTools port. Set to 0 on service startup error.
-  absl::optional<uint16_t> devtools_port_;
+  std::optional<uint16_t> devtools_port_;
 
  private:
   // fuchsia::web::Debug implementation.
@@ -335,7 +335,7 @@
 std::unique_ptr<WebEngineDevToolsController>
 WebEngineDevToolsController::CreateFromCommandLine(
     const base::CommandLine& command_line) {
-  absl::optional<uint16_t> devtools_port;
+  std::optional<uint16_t> devtools_port;
   if (command_line.HasSwitch(switches::kRemoteDebuggingPort)) {
     // Set up DevTools to listen on all network routes on the command-line
     // provided port.
diff --git a/fuchsia_web/webengine/browser/web_engine_memory_inspector.cc b/fuchsia_web/webengine/browser/web_engine_memory_inspector.cc
index 3a2be26..2b7919d 100644
--- a/fuchsia_web/webengine/browser/web_engine_memory_inspector.cc
+++ b/fuchsia_web/webengine/browser/web_engine_memory_inspector.cc
@@ -17,7 +17,7 @@
 namespace {
 
 std::vector<std::string> GetAllocatorDumpNamesFromConfig() {
-  const absl::optional<base::Value::Dict>& config =
+  const std::optional<base::Value::Dict>& config =
       fuchsia_component_support::LoadPackageConfig();
   if (!config)
     return {};
diff --git a/fuchsia_web/webengine/context_provider_impl_unittest.cc b/fuchsia_web/webengine/context_provider_impl_unittest.cc
index a5dbe14..4bf2448 100644
--- a/fuchsia_web/webengine/context_provider_impl_unittest.cc
+++ b/fuchsia_web/webengine/context_provider_impl_unittest.cc
@@ -20,6 +20,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/base_switches.h"
 #include "base/command_line.h"
 #include "base/containers/contains.h"
@@ -42,7 +43,6 @@
 #include "services/network/public/cpp/network_switches.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -445,7 +445,7 @@
   // A mock fuchsia::component/Realm used to bridge to `fake_realm_`.
   ::testing::StrictMock<fuchsia_component_support::MockRealm> mock_realm_;
   fidl::BindingSet<fuchsia::web::ContextProvider> bindings_;
-  absl::optional<ContextProviderImpl> provider_;
+  std::optional<ContextProviderImpl> provider_;
   fuchsia::web::ContextProviderPtr provider_ptr_;
 };
 
diff --git a/fuchsia_web/webengine/renderer/web_engine_audio_renderer.cc b/fuchsia_web/webengine/renderer/web_engine_audio_renderer.cc
index 3da5717d..d0941d2 100644
--- a/fuchsia_web/webengine/renderer/web_engine_audio_renderer.cc
+++ b/fuchsia_web/webengine/renderer/web_engine_audio_renderer.cc
@@ -23,7 +23,7 @@
 
 // nullopt is returned in case the codec is not supported. nullptr is returned
 // for uncompressed PCM streams.
-absl::optional<std::unique_ptr<fuchsia::media::Compression>>
+std::optional<std::unique_ptr<fuchsia::media::Compression>>
 GetFuchsiaCompressionFromDecoderConfig(media::AudioDecoderConfig config) {
   auto compression = std::make_unique<fuchsia::media::Compression>();
   switch (config.codec()) {
@@ -49,7 +49,7 @@
       break;
 
     default:
-      return absl::nullopt;
+      return std::nullopt;
   }
 
   if (!config.extra_data().empty()) {
@@ -59,7 +59,7 @@
   return std::move(compression);
 }
 
-absl::optional<fuchsia::media::AudioSampleFormat>
+std::optional<fuchsia::media::AudioSampleFormat>
 GetFuchsiaSampleFormatFromSampleFormat(media::SampleFormat sample_format) {
   switch (sample_format) {
     case media::kSampleFormatU8:
@@ -72,7 +72,7 @@
       return fuchsia::media::AudioSampleFormat::FLOAT;
 
     default:
-      return absl::nullopt;
+      return std::nullopt;
   }
 }
 
@@ -253,7 +253,7 @@
 
   // Set sample_format for uncompressed streams.
   if (!compression.value()) {
-    absl::optional<fuchsia::media::AudioSampleFormat> sample_format =
+    std::optional<fuchsia::media::AudioSampleFormat> sample_format =
         GetFuchsiaSampleFormatFromSampleFormat(config.sample_format());
     if (!sample_format) {
       LOG(ERROR) << "Unsupported sample format: "
@@ -330,7 +330,7 @@
 }
 
 void WebEngineAudioRenderer::SetLatencyHint(
-    absl::optional<base::TimeDelta> latency_hint) {
+    std::optional<base::TimeDelta> latency_hint) {
   // TODO(crbug.com/1131116): Implement at some later date after we've vetted
   // the API shape and usefulness outside of fuchsia.
   NOTIMPLEMENTED();
diff --git a/fuchsia_web/webengine/renderer/web_engine_audio_renderer.h b/fuchsia_web/webengine/renderer/web_engine_audio_renderer.h
index 9a2a649..79d89a7 100644
--- a/fuchsia_web/webengine/renderer/web_engine_audio_renderer.h
+++ b/fuchsia_web/webengine/renderer/web_engine_audio_renderer.h
@@ -50,7 +50,7 @@
   void Flush(base::OnceClosure callback) override;
   void StartPlaying() override;
   void SetVolume(float volume) override;
-  void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) override;
+  void SetLatencyHint(std::optional<base::TimeDelta> latency_hint) override;
   void SetPreservesPitch(bool preserves_pitch) override;
   void SetWasPlayedWithUserActivation(
       bool was_played_with_user_activation) override;
diff --git a/fuchsia_web/webengine/renderer/web_engine_audio_renderer_test.cc b/fuchsia_web/webengine/renderer/web_engine_audio_renderer_test.cc
index aab78436..22bc603d 100644
--- a/fuchsia_web/webengine/renderer/web_engine_audio_renderer_test.cc
+++ b/fuchsia_web/webengine/renderer/web_engine_audio_renderer_test.cc
@@ -8,6 +8,7 @@
 #include <fuchsia/media/cpp/fidl_test_base.h>
 #include <lib/fidl/cpp/binding.h>
 
+#include <optional>
 #include "base/containers/queue.h"
 #include "base/fuchsia/fuchsia_logging.h"
 #include "base/logging.h"
@@ -23,7 +24,6 @@
 #include "media/fuchsia/common/passthrough_sysmem_buffer_stream.h"
 #include "media/fuchsia/common/sysmem_client.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -41,7 +41,7 @@
     explicit ReadResult(const media::AudioDecoderConfig& config)
         : config(config) {}
 
-    absl::optional<media::AudioDecoderConfig> config;
+    std::optional<media::AudioDecoderConfig> config;
     scoped_refptr<media::DecoderBuffer> buffer;
   };
 
@@ -211,8 +211,8 @@
     EXPECT_TRUE(started_);
   }
 
-  void UpdateStatus(absl::optional<base::TimeTicks> reference_time,
-                    absl::optional<base::TimeDelta> media_time) {
+  void UpdateStatus(std::optional<base::TimeTicks> reference_time,
+                    std::optional<base::TimeDelta> media_time) {
     fuchsia::media::AudioConsumerStatus status;
     if (reference_time) {
       CHECK(media_time);
@@ -305,7 +305,7 @@
 
     std::move(status_callback_)(std::move(status_update_.value()));
     status_callback_ = {};
-    status_update_ = absl::nullopt;
+    status_update_ = std::nullopt;
   }
 
   fidl::Binding<fuchsia::media::AudioConsumer> binding_;
@@ -318,7 +318,7 @@
   bool create_stream_sink_called_ = false;
 
   WatchStatusCallback status_callback_;
-  absl::optional<fuchsia::media::AudioConsumerStatus> status_update_;
+  std::optional<fuchsia::media::AudioConsumerStatus> status_update_;
 
   bool started_ = false;
   base::TimeDelta start_media_time_;
@@ -348,7 +348,7 @@
 
   media::BufferingState buffering_state() const { return buffering_state_; }
 
-  absl::optional<media::AudioDecoderConfig> last_config_change() const {
+  std::optional<media::AudioDecoderConfig> last_config_change() const {
     return last_config_change_;
   }
 
@@ -386,7 +386,7 @@
   }
   void OnVideoNaturalSizeChange(const gfx::Size& size) override { FAIL(); }
   void OnVideoOpacityChange(bool opaque) override { FAIL(); }
-  void OnVideoFrameRateChange(absl::optional<int> fps) override { FAIL(); }
+  void OnVideoFrameRateChange(std::optional<int> fps) override { FAIL(); }
 
  private:
   media::PipelineStatus expected_error_ = media::PIPELINE_OK;
@@ -394,7 +394,7 @@
   bool expect_eos_ = false;
   media::BufferingState buffering_state_ = media::BUFFERING_HAVE_NOTHING;
   size_t bytes_decoded_ = 0;
-  absl::optional<media::AudioDecoderConfig> last_config_change_;
+  std::optional<media::AudioDecoderConfig> last_config_change_;
 };
 
 // media::SysmemBufferStream that asynchronously decouples buffer production
@@ -501,7 +501,7 @@
   void FillDemuxerStream(base::TimeDelta end_pos);
   void FillBuffer();
   void StartPlayback(base::TimeDelta start_time = base::TimeDelta());
-  void CheckGetWallClockTimes(absl::optional<base::TimeDelta> media_timestamp,
+  void CheckGetWallClockTimes(std::optional<base::TimeDelta> media_timestamp,
                               base::TimeTicks expected_wall_clock,
                               bool is_time_moving);
 
@@ -561,7 +561,7 @@
 
   ASSERT_EQ(pipeline_status, media::PIPELINE_OK);
 
-  audio_consumer_->UpdateStatus(absl::nullopt, absl::nullopt);
+  audio_consumer_->UpdateStatus(std::nullopt, std::nullopt);
 
   task_environment_.RunUntilIdle();
 }
@@ -633,7 +633,7 @@
 }
 
 void WebEngineAudioRendererTestBase::CheckGetWallClockTimes(
-    absl::optional<base::TimeDelta> media_timestamp,
+    std::optional<base::TimeDelta> media_timestamp,
     base::TimeTicks expected_wall_clock,
     bool is_time_moving) {
   std::vector<base::TimeDelta> media_timestamps;
@@ -664,7 +664,7 @@
   task_environment_.FastForwardBy(kTimeStep);
   EXPECT_EQ(time_source_->CurrentMediaTime(), start_time);
 
-  CheckGetWallClockTimes(absl::nullopt, base::TimeTicks(), false);
+  CheckGetWallClockTimes(std::nullopt, base::TimeTicks(), false);
   CheckGetWallClockTimes(start_time + kTimeStep,
                          base::TimeTicks::Now() + kTimeStep, false);
 
@@ -680,7 +680,7 @@
   EXPECT_EQ(time_source_->CurrentMediaTime(),
             start_time + (-kStartDelay + kTimeStep) * playback_rate);
 
-  CheckGetWallClockTimes(absl::nullopt, base::TimeTicks::Now(), true);
+  CheckGetWallClockTimes(std::nullopt, base::TimeTicks::Now(), true);
   CheckGetWallClockTimes(start_time + kTimeStep,
                          start_wall_clock + kTimeStep / playback_rate, true);
   CheckGetWallClockTimes(start_time + 2 * kTimeStep,
diff --git a/fuchsia_web/webengine/renderer/web_engine_content_renderer_client.cc b/fuchsia_web/webengine/renderer/web_engine_content_renderer_client.cc
index d56cb1c..80c7c01 100644
--- a/fuchsia_web/webengine/renderer/web_engine_content_renderer_client.cc
+++ b/fuchsia_web/webengine/renderer/web_engine_content_renderer_client.cc
@@ -6,6 +6,7 @@
 
 #include <tuple>
 
+#include <optional>
 #include "base/command_line.h"
 #include "base/feature_list.h"
 #include "build/chromecast_buildflags.h"
@@ -24,7 +25,6 @@
 #include "media/base/video_codecs.h"
 #include "services/network/public/cpp/features.h"
 #include "services/service_manager/public/cpp/binder_registry.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
 #include "third_party/blink/public/common/browser_interface_broker_proxy.h"
 #include "third_party/blink/public/web/web_view.h"
diff --git a/fuchsia_web/webengine/test/isolated_archivist.h b/fuchsia_web/webengine/test/isolated_archivist.h
index 7237a68..75f6543 100644
--- a/fuchsia_web/webengine/test/isolated_archivist.h
+++ b/fuchsia_web/webengine/test/isolated_archivist.h
@@ -8,8 +8,8 @@
 #include <fidl/fuchsia.logger/cpp/fidl.h>
 #include <lib/sys/cpp/outgoing_directory.h>
 
+#include <optional>
 #include "base/fuchsia/scoped_service_publisher.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // Runs an isolated archivist-for-embedding, publishing its
 // fuchsia_logger::LogSink into a given OutgoingDirectory, and providing access
@@ -26,7 +26,7 @@
   fidl::Client<fuchsia_logger::Log>& log() { return log_; }
 
  private:
-  absl::optional<base::ScopedNaturalServicePublisher<fuchsia_logger::LogSink>>
+  std::optional<base::ScopedNaturalServicePublisher<fuchsia_logger::LogSink>>
       log_sink_publisher_;
   fidl::Client<fuchsia_logger::Log> log_;
 };
diff --git a/fuchsia_web/webengine/web_engine_integration_logging_test.cc b/fuchsia_web/webengine/web_engine_integration_logging_test.cc
index b1d861f..0e75d27e 100644
--- a/fuchsia_web/webengine/web_engine_integration_logging_test.cc
+++ b/fuchsia_web/webengine/web_engine_integration_logging_test.cc
@@ -6,6 +6,7 @@
 
 #include <cstring>
 
+#include <optional>
 #include "base/containers/contains.h"
 #include "base/fuchsia/test_log_listener_safe.h"
 #include "base/strings/string_piece.h"
@@ -14,7 +15,6 @@
 #include "fuchsia_web/webengine/test/context_provider_for_test.h"
 #include "fuchsia_web/webengine/test/isolated_archivist.h"
 #include "fuchsia_web/webengine/web_engine_integration_test_base.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -67,7 +67,7 @@
   fidl::Client<fuchsia_logger::Log>& log() { return isolated_archivist_.log(); }
 
   IsolatedArchivist isolated_archivist_;
-  absl::optional<ContextProviderForTest> context_provider_;
+  std::optional<ContextProviderForTest> context_provider_;
 };
 
 // Verifies that calling messages from console.debug() calls go to the Fuchsia
@@ -91,7 +91,7 @@
   navigation_listener()->RunUntilTitleEquals("ended");
 
   // Run until the message passed to console.debug() is received.
-  absl::optional<fuchsia_logger::LogMessage> logged_message =
+  std::optional<fuchsia_logger::LogMessage> logged_message =
       log_listener.RunUntilMessageReceived(kLogTestPageDebugMessage);
 
   ASSERT_TRUE(logged_message.has_value());
diff --git a/fuchsia_web/webengine/web_engine_integration_test.cc b/fuchsia_web/webengine/web_engine_integration_test.cc
index ded1373..e4c2f8891 100644
--- a/fuchsia_web/webengine/web_engine_integration_test.cc
+++ b/fuchsia_web/webengine/web_engine_integration_test.cc
@@ -10,6 +10,7 @@
 
 #include <string>
 
+#include <optional>
 #include "base/containers/contains.h"
 #include "base/fuchsia/fuchsia_logging.h"
 #include "base/fuchsia/mem_buffer_util.h"
@@ -29,7 +30,6 @@
 #include "media/fuchsia/camera/fake_fuchsia_camera.h"
 #include "net/http/http_request_headers.h"
 #include "testing/gmock/include/gmock/gmock.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -74,7 +74,7 @@
   void RunPermissionTest(bool grant);
 
  private:
-  absl::optional<ContextProviderForTest> context_provider_;
+  std::optional<ContextProviderForTest> context_provider_;
 };
 
 class WebEngineIntegrationUserAgentTest : public WebEngineIntegrationTest {
@@ -361,7 +361,7 @@
     binding_.AddBinding(this, std::move(request));
   }
 
-  const absl::optional<fuchsia::media::AudioRenderUsage>& usage() const {
+  const std::optional<fuchsia::media::AudioRenderUsage>& usage() const {
     return usage_;
   }
 
@@ -376,7 +376,7 @@
  private:
   fidl::BindingSet<fuchsia::media::AudioRenderer> binding_;
   base::OnceClosure on_set_usage_callback_;
-  absl::optional<fuchsia::media::AudioRenderUsage> usage_;
+  std::optional<fuchsia::media::AudioRenderUsage> usage_;
 };
 
 class FakeAudio : public fuchsia::media::testing::Audio_TestBase {
@@ -448,9 +448,8 @@
   }
 
   media::FakeAudioConsumerService fake_audio_consumer_service_;
-  absl::optional<media::FakeAudioDeviceEnumerator>
-      fake_audio_device_enumerator_;
-  absl::optional<FakeAudio> fake_audio_;
+  std::optional<media::FakeAudioDeviceEnumerator> fake_audio_device_enumerator_;
+  std::optional<FakeAudio> fake_audio_;
 
   size_t num_audio_connections_ = 0;
 };
diff --git a/fuchsia_web/webengine/web_engine_integration_test_base.cc b/fuchsia_web/webengine/web_engine_integration_test_base.cc
index 2af36c1..73af37df 100644
--- a/fuchsia_web/webengine/web_engine_integration_test_base.cc
+++ b/fuchsia_web/webengine/web_engine_integration_test_base.cc
@@ -172,19 +172,19 @@
 
 std::string WebEngineIntegrationTestBase::ExecuteJavaScriptWithStringResult(
     base::StringPiece script) {
-  absl::optional<base::Value> value = ExecuteJavaScript(frame_.get(), script);
+  std::optional<base::Value> value = ExecuteJavaScript(frame_.get(), script);
   return value ? value->GetString() : std::string();
 }
 
 double WebEngineIntegrationTestBase::ExecuteJavaScriptWithDoubleResult(
     base::StringPiece script) {
-  absl::optional<base::Value> value = ExecuteJavaScript(frame_.get(), script);
+  std::optional<base::Value> value = ExecuteJavaScript(frame_.get(), script);
   return value ? value->GetDouble() : 0.0;
 }
 
 bool WebEngineIntegrationTestBase::ExecuteJavaScriptWithBoolResult(
     base::StringPiece script) {
-  absl::optional<base::Value> value = ExecuteJavaScript(frame_.get(), script);
+  std::optional<base::Value> value = ExecuteJavaScript(frame_.get(), script);
   return value ? value->GetBool() : false;
 }
 
diff --git a/fuchsia_web/webengine/web_engine_main_delegate.cc b/fuchsia_web/webengine/web_engine_main_delegate.cc
index 2d6138f8..1b6f23be 100644
--- a/fuchsia_web/webengine/web_engine_main_delegate.cc
+++ b/fuchsia_web/webengine/web_engine_main_delegate.cc
@@ -73,7 +73,7 @@
 
 WebEngineMainDelegate::~WebEngineMainDelegate() = default;
 
-absl::optional<int> WebEngineMainDelegate::BasicStartupComplete() {
+std::optional<int> WebEngineMainDelegate::BasicStartupComplete() {
   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
 
   if (!InitLoggingFromCommandLine(*command_line)) {
@@ -94,7 +94,7 @@
           switches::kCorsExemptHeaders),
       ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY));
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void WebEngineMainDelegate::PreSandboxStartup() {
diff --git a/fuchsia_web/webengine/web_engine_main_delegate.h b/fuchsia_web/webengine/web_engine_main_delegate.h
index 09af735..861c09e 100644
--- a/fuchsia_web/webengine/web_engine_main_delegate.h
+++ b/fuchsia_web/webengine/web_engine_main_delegate.h
@@ -10,9 +10,9 @@
 #include <memory>
 #include <string>
 
+#include <optional>
 #include "content/public/app/content_main_delegate.h"
 #include "fuchsia_web/webengine/web_engine_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace content {
 class ContentClient;
@@ -36,7 +36,7 @@
   }
 
   // ContentMainDelegate implementation.
-  absl::optional<int> BasicStartupComplete() override;
+  std::optional<int> BasicStartupComplete() override;
   void PreSandboxStartup() override;
   absl::variant<int, content::MainFunctionParams> RunProcess(
       const std::string& process_type,
diff --git a/gin/array_buffer.cc b/gin/array_buffer.cc
index 76610a3..5f3cfd8 100644
--- a/gin/array_buffer.cc
+++ b/gin/array_buffer.cc
@@ -151,7 +151,7 @@
 
 class ArrayBufferSharedMemoryMapper : public base::SharedMemoryMapper {
  public:
-  absl::optional<base::span<uint8_t>> Map(
+  std::optional<base::span<uint8_t>> Map(
       base::subtle::PlatformSharedMemoryHandle handle,
       bool write_allowed,
       uint64_t offset,
@@ -186,7 +186,7 @@
     uintptr_t mapping = v8::V8::GetSandboxAddressSpace()->AllocateSharedPages(
         0, mapping_size, permissions, v8_handle, offset);
     if (!mapping)
-      return absl::nullopt;
+      return std::nullopt;
 
     return base::make_span(reinterpret_cast<uint8_t*>(mapping), size);
   }
diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc
index ff9655bf..14aae19 100644
--- a/gin/v8_initializer.cc
+++ b/gin/v8_initializer.cc
@@ -13,6 +13,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/allocator/partition_allocator/src/partition_alloc/page_allocator.h"
 #include "base/allocator/partition_allocator/src/partition_alloc/partition_address_space.h"
 #include "base/bits.h"
@@ -39,7 +40,6 @@
 #include "build/build_config.h"
 #include "gin/array_buffer.h"
 #include "gin/gin_features.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "tools/v8_context_snapshot/buildflags.h"
 #include "v8/include/v8-initialization.h"
 #include "v8/include/v8-snapshot.h"
@@ -60,7 +60,7 @@
 base::MemoryMappedFile* g_mapped_snapshot = nullptr;
 
 #if defined(V8_USE_EXTERNAL_STARTUP_DATA)
-absl::optional<gin::V8SnapshotFileType> g_snapshot_file_type;
+std::optional<gin::V8SnapshotFileType> g_snapshot_file_type;
 #endif
 
 bool GenerateEntropy(unsigned char* buffer, size_t amount) {
diff --git a/google_apis/calendar/calendar_api_response_types.cc b/google_apis/calendar/calendar_api_response_types.cc
index 94225d58..786f58b 100644
--- a/google_apis/calendar/calendar_api_response_types.cc
+++ b/google_apis/calendar/calendar_api_response_types.cc
@@ -10,6 +10,7 @@
 #include <memory>
 #include <string>
 
+#include <optional>
 #include "base/containers/fixed_flat_map.h"
 #include "base/json/json_value_converter.h"
 #include "base/ranges/algorithm.h"
@@ -20,7 +21,6 @@
 #include "base/values.h"
 #include "google_apis/common/parser_util.h"
 #include "google_apis/common/time_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace google_apis {
 
@@ -92,13 +92,13 @@
   return true;
 }
 
-// Returns user's self response status on the event, or `absl::nullopt` in case
+// Returns user's self response status on the event, or `std::nullopt` in case
 // the passed value is structurally different from expected.
-absl::optional<CalendarEvent::ResponseStatus> CalculateSelfResponseStatus(
+std::optional<CalendarEvent::ResponseStatus> CalculateSelfResponseStatus(
     const base::Value& value) {
   const auto* event = value.GetIfDict();
   if (!event)
-    return absl::nullopt;
+    return std::nullopt;
 
   const auto* attendees_raw_value = event->Find(kAttendees);
   if (!attendees_raw_value) {
@@ -125,12 +125,12 @@
 
   const auto* attendees = attendees_raw_value->GetIfList();
   if (!attendees)
-    return absl::nullopt;
+    return std::nullopt;
 
   for (const auto& x : *attendees) {
     const auto* attendee = x.GetIfDict();
     if (!attendee)
-      return absl::nullopt;
+      return std::nullopt;
 
     const bool is_self = attendee->FindBool(kAttendeesSelf).value_or(false);
     if (!is_self) {
@@ -143,7 +143,7 @@
 
     const auto* responseStatus = attendee->FindString(kAttendeesResponseStatus);
     if (!responseStatus)
-      return absl::nullopt;
+      return std::nullopt;
 
     const auto* it = kAttendeesResponseStatuses.find(*responseStatus);
     if (it != kAttendeesResponseStatuses.end()) {
diff --git a/google_apis/calendar/calendar_api_url_generator.cc b/google_apis/calendar/calendar_api_url_generator.cc
index 51af894..20a78cb 100644
--- a/google_apis/calendar/calendar_api_url_generator.cc
+++ b/google_apis/calendar/calendar_api_url_generator.cc
@@ -4,10 +4,10 @@
 
 #include "google_apis/calendar/calendar_api_url_generator.h"
 
+#include <optional>
 #include "base/strings/string_number_conversions.h"
 #include "google_apis/common/time_util.h"
 #include "net/base/url_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace google_apis {
 
@@ -40,8 +40,8 @@
     const base::Time& start_time,
     const base::Time& end_time,
     bool single_events,
-    absl::optional<int> max_attendees,
-    absl::optional<int> max_results) const {
+    std::optional<int> max_attendees,
+    std::optional<int> max_results) const {
   GURL url = base_url_.Resolve(kCalendarV3EventsUrl);
   std::string start_time_string = util::FormatTimeAsString(start_time);
   std::string end_time_string = util::FormatTimeAsString(end_time);
diff --git a/google_apis/calendar/calendar_api_url_generator.h b/google_apis/calendar/calendar_api_url_generator.h
index 1372df5..70666f5 100644
--- a/google_apis/calendar/calendar_api_url_generator.h
+++ b/google_apis/calendar/calendar_api_url_generator.h
@@ -7,9 +7,9 @@
 
 #include <string>
 
+#include <optional>
 #include "base/time/time.h"
 #include "google_apis/gaia/gaia_urls.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace google_apis {
@@ -40,8 +40,8 @@
   GURL GetCalendarEventListUrl(const base::Time& start_time,
                                const base::Time& end_time,
                                bool single_events,
-                               absl::optional<int> max_attendees,
-                               absl::optional<int> max_results) const;
+                               std::optional<int> max_attendees,
+                               std::optional<int> max_results) const;
 
   // Returns a URL to fetch a map of calendar color id to color code.
   GURL GetCalendarColorListUrl() const;
diff --git a/google_apis/calendar/calendar_api_url_generator_unittest.cc b/google_apis/calendar/calendar_api_url_generator_unittest.cc
index d163ba3..0e1f3d7 100644
--- a/google_apis/calendar/calendar_api_url_generator_unittest.cc
+++ b/google_apis/calendar/calendar_api_url_generator_unittest.cc
@@ -52,8 +52,8 @@
       "&singleEvents=true",
       url_generator_
           .GetCalendarEventListUrl(start, end, /*single_events=*/true,
-                                   /*max_attendees=*/absl::nullopt,
-                                   /*max_results=*/absl::nullopt)
+                                   /*max_attendees=*/std::nullopt,
+                                   /*max_results=*/std::nullopt)
           .spec());
 }
 
diff --git a/google_apis/classroom/classroom_api_course_work_response_types.cc b/google_apis/classroom/classroom_api_course_work_response_types.cc
index da38542..27ec33c 100644
--- a/google_apis/classroom/classroom_api_course_work_response_types.cc
+++ b/google_apis/classroom/classroom_api_course_work_response_types.cc
@@ -7,13 +7,13 @@
 #include <memory>
 #include <string>
 
+#include <optional>
 #include "base/json/json_value_converter.h"
 #include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "base/values.h"
 #include "google_apis/common/parser_util.h"
 #include "google_apis/common/time_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace google_apis::classroom {
@@ -70,12 +70,12 @@
          base::Nanoseconds(nanos.value_or(0));
 }
 
-absl::optional<CourseWorkItem::DueDateTime> GetCourseWorkItemDueDateTime(
+std::optional<CourseWorkItem::DueDateTime> GetCourseWorkItemDueDateTime(
     const base::Value::Dict& raw_course_work_item) {
   const auto* const date =
       raw_course_work_item.FindDict(kApiResponseCourseWorkItemDueDateKey);
   if (!date) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   const auto year = date->FindInt(kDueDateYearComponent);
@@ -83,7 +83,7 @@
   const auto day = date->FindInt(kDueDateDayComponent);
 
   if (!year.has_value() && !month.has_value() && !day.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return CourseWorkItem::DueDateTime{
diff --git a/google_apis/classroom/classroom_api_course_work_response_types.h b/google_apis/classroom/classroom_api_course_work_response_types.h
index 5f15c2a..866d8a9b 100644
--- a/google_apis/classroom/classroom_api_course_work_response_types.h
+++ b/google_apis/classroom/classroom_api_course_work_response_types.h
@@ -9,8 +9,8 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/time/time.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace base {
@@ -68,7 +68,7 @@
   const std::string& title() const { return title_; }
   State state() const { return state_; }
   const GURL& alternate_link() const { return alternate_link_; }
-  const absl::optional<DueDateTime>& due_date_time() const {
+  const std::optional<DueDateTime>& due_date_time() const {
     return due_date_time_;
   }
   const base::Time& creation_time() const { return creation_time_; }
@@ -93,7 +93,7 @@
   // specifying zeroes in different date components (e.g. a month and day with
   // a zero year means a repeating annual assignment). That is why it was safer,
   // more flexible and forward compatible to use the same approach here.
-  absl::optional<DueDateTime> due_date_time_ = absl::nullopt;
+  std::optional<DueDateTime> due_date_time_ = std::nullopt;
 
   // The timestamp when this course work was created.
   base::Time creation_time_;
diff --git a/google_apis/classroom/classroom_api_student_submissions_response_types.cc b/google_apis/classroom/classroom_api_student_submissions_response_types.cc
index 69c0d316..57ed64d 100644
--- a/google_apis/classroom/classroom_api_student_submissions_response_types.cc
+++ b/google_apis/classroom/classroom_api_student_submissions_response_types.cc
@@ -43,13 +43,13 @@
 }
 
 bool ConvertAssignedGrade(const base::Value* input,
-                          absl::optional<double>* assigned_grade) {
+                          std::optional<double>* assigned_grade) {
   *assigned_grade = input->GetIfDouble();
   return true;
 }
 
 bool ConvertUpdateTime(base::StringPiece input,
-                       absl::optional<base::Time>* output) {
+                       std::optional<base::Time>* output) {
   base::Time update_time;
   if (!util::GetTimeFromString(input, &update_time)) {
     return false;
@@ -71,10 +71,10 @@
   converter->RegisterCustomField<StudentSubmission::State>(
       kApiResponseStudentSubmissionStateKey, &StudentSubmission::state_,
       &ConvertStudentSubmissionState);
-  converter->RegisterCustomValueField<absl::optional<double>>(
+  converter->RegisterCustomValueField<std::optional<double>>(
       kApiResponseStudentSubmissionAssignedGradeKey,
       &StudentSubmission::assigned_grade_, &ConvertAssignedGrade);
-  converter->RegisterCustomField<absl::optional<base::Time>>(
+  converter->RegisterCustomField<std::optional<base::Time>>(
       kApiResponseStudentSubmissionUpdateTimeKey,
       &StudentSubmission::last_update_, &ConvertUpdateTime);
 }
diff --git a/google_apis/classroom/classroom_api_student_submissions_response_types.h b/google_apis/classroom/classroom_api_student_submissions_response_types.h
index abadf7fa..0089bbb 100644
--- a/google_apis/classroom/classroom_api_student_submissions_response_types.h
+++ b/google_apis/classroom/classroom_api_student_submissions_response_types.h
@@ -9,8 +9,8 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/time/time.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 template <class StructType>
@@ -45,8 +45,8 @@
 
   const std::string& course_work_id() const { return course_work_id_; }
   const std::string& id() const { return id_; }
-  absl::optional<double> assigned_grade() const { return assigned_grade_; }
-  const absl::optional<base::Time>& last_update() const { return last_update_; }
+  std::optional<double> assigned_grade() const { return assigned_grade_; }
+  const std::optional<base::Time>& last_update() const { return last_update_; }
   State state() const { return state_; }
 
  private:
@@ -58,11 +58,11 @@
 
   // Optional grade. If unset, no grade was set. This value is a
   // non-negative decimal rounded to two decimal places.
-  absl::optional<double> assigned_grade_ = absl::nullopt;
+  std::optional<double> assigned_grade_ = std::nullopt;
 
   // The last update time of this submission. May be unset if student has not
   // accessed this item.
-  absl::optional<base::Time> last_update_ = absl::nullopt;
+  std::optional<base::Time> last_update_ = std::nullopt;
 
   // State of the student submission.
   State state_ = State::kOther;
diff --git a/google_apis/common/base_requests.cc b/google_apis/common/base_requests.cc
index 92b9219..de746d6 100644
--- a/google_apis/common/base_requests.cc
+++ b/google_apis/common/base_requests.cc
@@ -54,8 +54,7 @@
 
 namespace google_apis {
 
-absl::optional<std::string> MapJsonErrorToReason(
-    const std::string& error_body) {
+std::optional<std::string> MapJsonErrorToReason(const std::string& error_body) {
   DVLOG(1) << error_body;
   const char kErrorKey[] = "error";
   const char kErrorErrorsKey[] = "errors";
@@ -70,7 +69,7 @@
   if (error) {
     // Get error message and code.
     const std::string* message = error->FindString(kErrorMessageKey);
-    absl::optional<int> code = error->FindInt(kErrorCodeKey);
+    std::optional<int> code = error->FindInt(kErrorCodeKey);
     DLOG(ERROR) << "code: " << (code ? code.value() : OTHER_ERROR)
                 << ", message: " << (message ? *message : "");
 
@@ -85,7 +84,7 @@
       }
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 std::unique_ptr<base::Value> ParseJson(const std::string& json) {
@@ -378,7 +377,7 @@
     }
     if (!download_data_->response_body.empty()) {
       if (!IsSuccessfulErrorCode(error_code_.value())) {
-        absl::optional<std::string> reason =
+        std::optional<std::string> reason =
             MapJsonErrorToReason(download_data_->response_body);
         if (reason.has_value())
           error_code_ = MapReasonToError(error_code_.value(), reason.value());
diff --git a/google_apis/common/base_requests.h b/google_apis/common/base_requests.h
index 51f7792..a05d97f 100644
--- a/google_apis/common/base_requests.h
+++ b/google_apis/common/base_requests.h
@@ -57,7 +57,7 @@
 std::unique_ptr<base::Value> ParseJson(const std::string& json);
 
 // Maps the error body to reason and logs the error code.
-absl::optional<std::string> MapJsonErrorToReason(const std::string& error_body);
+std::optional<std::string> MapJsonErrorToReason(const std::string& error_body);
 
 // Stringifies `HttpRequestMethod` enum value.
 std::string HttpRequestMethodToString(HttpRequestMethod method);
@@ -268,7 +268,7 @@
   int re_authenticate_count_;
   std::unique_ptr<network::SimpleURLLoader> url_loader_;
   raw_ptr<RequestSender> sender_;
-  absl::optional<ApiErrorCode> error_code_;
+  std::optional<ApiErrorCode> error_code_;
   const ProgressCallback upload_progress_callback_;
   const ProgressCallback download_progress_callback_;
   std::unique_ptr<DownloadData> download_data_;
diff --git a/google_apis/common/base_requests_unittest.cc b/google_apis/common/base_requests_unittest.cc
index e7aa530..ef3af81 100644
--- a/google_apis/common/base_requests_unittest.cc
+++ b/google_apis/common/base_requests_unittest.cc
@@ -160,7 +160,7 @@
   base::Value::Dict* root_dict = json->GetIfDict();
   ASSERT_TRUE(root_dict);
 
-  absl::optional<int> int_value = root_dict->FindInt("test");
+  std::optional<int> int_value = root_dict->FindInt("test");
   ASSERT_TRUE(int_value.has_value());
   EXPECT_EQ(123, *int_value);
 }
diff --git a/google_apis/drive/drive_base_requests.cc b/google_apis/drive/drive_base_requests.cc
index 865057b..e9a6822 100644
--- a/google_apis/drive/drive_base_requests.cc
+++ b/google_apis/drive/drive_base_requests.cc
@@ -531,7 +531,7 @@
                        weak_ptr_factory_.GetWeakPtr(), code,
                        std::move(notify_complete_callback)));
   } else {
-    absl::optional<std::string> reason = MapJsonErrorToReason(body);
+    std::optional<std::string> reason = MapJsonErrorToReason(body);
     NotifyError(reason.has_value() ? MapDriveReasonToError(code, reason.value())
                                    : code);
     std::move(notify_complete_callback).Run();
diff --git a/google_apis/gaia/fake_gaia.cc b/google_apis/gaia/fake_gaia.cc
index 0ea731f..28357902 100644
--- a/google_apis/gaia/fake_gaia.cc
+++ b/google_apis/gaia/fake_gaia.cc
@@ -817,7 +817,7 @@
                                   BasicHttpResponse* http_response) {
   GURL request_url = GURL("http://localhost").Resolve(request.relative_url);
 
-  absl::optional<GURL> redirect_url = GetSamlRedirectUrl(request_url);
+  std::optional<GURL> redirect_url = GetSamlRedirectUrl(request_url);
   if (!redirect_url) {
     http_response->set_code(net::HTTP_BAD_REQUEST);
     return;
@@ -951,7 +951,7 @@
   return response_with_iframe;
 }
 
-absl::optional<GURL> FakeGaia::GetSamlRedirectUrl(
+std::optional<GURL> FakeGaia::GetSamlRedirectUrl(
     const GURL& request_url) const {
   // When deciding on saml redirection, gaia is expected to prioritize sso
   // profile over the domain.
@@ -972,5 +972,5 @@
     return itr_domain->second;
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
diff --git a/google_apis/gaia/fake_gaia.h b/google_apis/gaia/fake_gaia.h
index deb113a..f9cc6fd 100644
--- a/google_apis/gaia/fake_gaia.h
+++ b/google_apis/gaia/fake_gaia.h
@@ -9,11 +9,11 @@
 #include <set>
 #include <string>
 
+#include <optional>
 #include "base/containers/flat_map.h"
 #include "base/functional/callback.h"
 #include "google_apis/gaia/gaia_auth_consumer.h"
 #include "net/http/http_status_code.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace base {
@@ -339,7 +339,7 @@
 
   // Returns saml redirect based on given `request_url`. Returns empty object if
   // it fails to determine appropriate redirect url.
-  absl::optional<GURL> GetSamlRedirectUrl(const GURL& request_url) const;
+  std::optional<GURL> GetSamlRedirectUrl(const GURL& request_url) const;
 
   Configuration configuration_;
   EmailToGaiaIdMap email_to_gaia_id_map_;
diff --git a/google_apis/gaia/gaia_auth_fetcher.cc b/google_apis/gaia/gaia_auth_fetcher.cc
index 702edab..0a38ef9 100644
--- a/google_apis/gaia/gaia_auth_fetcher.cc
+++ b/google_apis/gaia/gaia_auth_fetcher.cc
@@ -8,6 +8,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/functional/bind.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
@@ -37,7 +38,6 @@
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/cpp/simple_url_loader.h"
 #include "services/network/public/mojom/url_response_head.mojom.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -52,14 +52,14 @@
 
 std::unique_ptr<const GaiaAuthConsumer::ClientOAuthResult>
 ExtractOAuth2TokenPairResponse(const std::string& data) {
-  absl::optional<base::Value> value = base::JSONReader::Read(data);
+  std::optional<base::Value> value = base::JSONReader::Read(data);
   if (!value || !value->is_dict())
     return nullptr;
   base::Value::Dict& dict = value->GetDict();
 
   std::string* refresh_token = dict.FindString("refresh_token");
   std::string* access_token = dict.FindString("access_token");
-  absl::optional<int> expires_in_secs = dict.FindInt("expires_in");
+  std::optional<int> expires_in_secs = dict.FindInt("expires_in");
   if (!refresh_token || !access_token || !expires_in_secs.has_value())
     return nullptr;
 
@@ -95,7 +95,7 @@
   if (response_code == net::HTTP_INTERNAL_SERVER_ERROR)
     return GaiaAuthConsumer::TokenRevocationStatus::kServerError;
 
-  absl::optional<base::Value> value = base::JSONReader::Read(data);
+  std::optional<base::Value> value = base::JSONReader::Read(data);
   if (!value || !value->is_dict())
     return GaiaAuthConsumer::TokenRevocationStatus::kUnknownError;
   base::Value::Dict& dict = value->GetDict();
@@ -114,7 +114,7 @@
 
 base::Value::Dict ParseJSONDict(const std::string& data) {
   base::Value::Dict response_dict;
-  absl::optional<base::Value> message_value = base::JSONReader::Read(data);
+  std::optional<base::Value> message_value = base::JSONReader::Read(data);
   if (message_value && message_value->is_dict()) {
     response_dict.Merge(std::move(message_value->GetDict()));
   }
diff --git a/google_apis/gaia/gaia_auth_test_util.cc b/google_apis/gaia/gaia_auth_test_util.cc
index 08e764d..bcc0f76 100644
--- a/google_apis/gaia/gaia_auth_test_util.cc
+++ b/google_apis/gaia/gaia_auth_test_util.cc
@@ -9,9 +9,9 @@
 namespace gaia {
 
 std::string GenerateOAuth2MintTokenConsentResult(
-    absl::optional<bool> approved,
-    const absl::optional<std::string>& encrypted_approval_data,
-    const absl::optional<std::string>& obfuscated_id,
+    std::optional<bool> approved,
+    const std::optional<std::string>& encrypted_approval_data,
+    const std::optional<std::string>& obfuscated_id,
     base::Base64UrlEncodePolicy encode_policy) {
   OAuth2MintTokenConsentResult consent_result;
   if (approved.has_value())
diff --git a/google_apis/gaia/gaia_auth_test_util.h b/google_apis/gaia/gaia_auth_test_util.h
index 5904d3b9b..10a865f 100644
--- a/google_apis/gaia/gaia_auth_test_util.h
+++ b/google_apis/gaia/gaia_auth_test_util.h
@@ -5,17 +5,17 @@
 #ifndef GOOGLE_APIS_GAIA_GAIA_AUTH_TEST_UTIL_H_
 #define GOOGLE_APIS_GAIA_GAIA_AUTH_TEST_UTIL_H_
 
+#include <optional>
 #include "base/base64url.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #include <string>
 
 namespace gaia {
 
 std::string GenerateOAuth2MintTokenConsentResult(
-    absl::optional<bool> approved,
-    const absl::optional<std::string>& encrypted_approval_data,
-    const absl::optional<std::string>& obfuscated_id,
+    std::optional<bool> approved,
+    const std::optional<std::string>& encrypted_approval_data,
+    const std::optional<std::string>& obfuscated_id,
     base::Base64UrlEncodePolicy encode_policy =
         base::Base64UrlEncodePolicy::OMIT_PADDING);
 
diff --git a/google_apis/gaia/gaia_auth_util.cc b/google_apis/gaia/gaia_auth_util.cc
index ae6e2c464..ded245e 100644
--- a/google_apis/gaia/gaia_auth_util.cc
+++ b/google_apis/gaia/gaia_auth_util.cc
@@ -134,7 +134,7 @@
     signed_out_accounts->clear();
 
   // Parse returned data and make sure we have data.
-  absl::optional<base::Value> value = base::JSONReader::Read(data);
+  std::optional<base::Value> value = base::JSONReader::Read(data);
   if (!value)
     return false;
 
diff --git a/google_apis/gaia/gaia_auth_util_unittest.cc b/google_apis/gaia/gaia_auth_util_unittest.cc
index 890d858..57203ce 100644
--- a/google_apis/gaia/gaia_auth_util_unittest.cc
+++ b/google_apis/gaia/gaia_auth_util_unittest.cc
@@ -374,7 +374,7 @@
 TEST(GaiaAuthUtilTest, ParseConsentResultApprovedEmptyData) {
   const char kApprovedConsent[] = "CAEaDGZha2VfZ2FpYV9pZA";
   EXPECT_EQ(kApprovedConsent,
-            GenerateOAuth2MintTokenConsentResult(true, absl::nullopt, kGaiaId));
+            GenerateOAuth2MintTokenConsentResult(true, std::nullopt, kGaiaId));
   bool approved = false;
   std::string gaia_id;
   ASSERT_TRUE(
@@ -386,7 +386,7 @@
 TEST(GaiaAuthUtilTest, ParseConsentResultApprovedEmptyGaiaId) {
   const char kApprovedConsent[] = "CAESCUVOQ1JZUFRFRA";
   EXPECT_EQ(kApprovedConsent, GenerateOAuth2MintTokenConsentResult(
-                                  true, "ENCRYPTED", absl::nullopt));
+                                  true, "ENCRYPTED", std::nullopt));
   bool approved = false;
   std::string gaia_id;
   ASSERT_TRUE(
@@ -397,8 +397,8 @@
 
 TEST(GaiaAuthUtilTest, ParseConsentResultNotApproved) {
   const char kNoGrantConsent[] = "CAAaDGZha2VfZ2FpYV9pZA";
-  EXPECT_EQ(kNoGrantConsent, GenerateOAuth2MintTokenConsentResult(
-                                 false, absl::nullopt, kGaiaId));
+  EXPECT_EQ(kNoGrantConsent,
+            GenerateOAuth2MintTokenConsentResult(false, std::nullopt, kGaiaId));
   bool approved = false;
   std::string gaia_id;
   ASSERT_TRUE(
@@ -408,8 +408,8 @@
 }
 
 TEST(GaiaAuthUtilTest, ParseConsentResultEmpty) {
-  EXPECT_EQ("", GenerateOAuth2MintTokenConsentResult(
-                    absl::nullopt, absl::nullopt, absl::nullopt));
+  EXPECT_EQ("", GenerateOAuth2MintTokenConsentResult(std::nullopt, std::nullopt,
+                                                     std::nullopt));
   bool approved = false;
   std::string gaia_id;
   ASSERT_TRUE(ParseOAuth2MintTokenConsentResult("", &approved, &gaia_id));
@@ -423,7 +423,7 @@
   const char kApprovedConsentWithPadding[] = "CAE=";
   EXPECT_EQ(kApprovedConsentWithPadding,
             GenerateOAuth2MintTokenConsentResult(
-                true, absl::nullopt, absl::nullopt,
+                true, std::nullopt, std::nullopt,
                 base::Base64UrlEncodePolicy::INCLUDE_PADDING));
   bool approved = false;
   std::string gaia_id;
diff --git a/google_apis/gaia/gaia_config.cc b/google_apis/gaia/gaia_config.cc
index 64a14535..d5aacff 100644
--- a/google_apis/gaia/gaia_config.cc
+++ b/google_apis/gaia/gaia_config.cc
@@ -4,6 +4,7 @@
 
 #include "google_apis/gaia/gaia_config.h"
 
+#include <optional>
 #include "base/command_line.h"
 #include "base/files/file_util.h"
 #include "base/json/json_reader.h"
@@ -15,7 +16,6 @@
 #include "base/threading/thread_restrictions.h"
 #include "google_apis/gaia/gaia_switches.h"
 #include "google_apis/google_api_keys.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 // static
@@ -100,7 +100,7 @@
 // static
 std::unique_ptr<GaiaConfig> GaiaConfig::ReadConfigFromString(
     const std::string& config_contents) {
-  absl::optional<base::Value> dict = base::JSONReader::Read(config_contents);
+  std::optional<base::Value> dict = base::JSONReader::Read(config_contents);
   if (!dict || !dict->is_dict()) {
     LOG(FATAL) << "Couldn't parse Gaia config file";
     return nullptr;
diff --git a/google_apis/gaia/gaia_config_unittest.cc b/google_apis/gaia/gaia_config_unittest.cc
index 4939f59..785d1e9 100644
--- a/google_apis/gaia/gaia_config_unittest.cc
+++ b/google_apis/gaia/gaia_config_unittest.cc
@@ -4,12 +4,12 @@
 
 #include "google_apis/gaia/gaia_config.h"
 
+#include <optional>
 #include "base/command_line.h"
 #include "base/json/json_reader.h"
 #include "google_apis/gaia/gaia_switches.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace {
@@ -30,8 +30,7 @@
 })";
 
 TEST(GaiaConfigTest, ShouldGetURLIfExists) {
-  absl::optional<base::Value> dict =
-      base::JSONReader::Read(kTestConfigContents);
+  std::optional<base::Value> dict = base::JSONReader::Read(kTestConfigContents);
   ASSERT_TRUE(dict.has_value());
 
   GaiaConfig config(std::move(dict->GetDict()));
@@ -41,8 +40,7 @@
 }
 
 TEST(GaiaConfigTest, ShouldReturnNullIfURLDoesNotExists) {
-  absl::optional<base::Value> dict =
-      base::JSONReader::Read(kTestConfigContents);
+  std::optional<base::Value> dict = base::JSONReader::Read(kTestConfigContents);
   ASSERT_TRUE(dict.has_value());
 
   GaiaConfig config(std::move(dict->GetDict()));
@@ -51,8 +49,7 @@
 }
 
 TEST(GaiaConfigTest, ShouldGetAPIKeyIfExists) {
-  absl::optional<base::Value> dict =
-      base::JSONReader::Read(kTestConfigContents);
+  std::optional<base::Value> dict = base::JSONReader::Read(kTestConfigContents);
   ASSERT_TRUE(dict.has_value());
 
   GaiaConfig config(std::move(dict->GetDict()));
@@ -62,8 +59,7 @@
 }
 
 TEST(GaiaConfigTest, ShouldReturnNullIfAPIKeyDoesNotExists) {
-  absl::optional<base::Value> dict =
-      base::JSONReader::Read(kTestConfigContents);
+  std::optional<base::Value> dict = base::JSONReader::Read(kTestConfigContents);
   ASSERT_TRUE(dict.has_value());
 
   GaiaConfig config(std::move(dict->GetDict()));
@@ -72,8 +68,7 @@
 }
 
 TEST(GaiaConfigTest, ShouldSerializeContentsToCommandLineSwitch) {
-  absl::optional<base::Value> dict =
-      base::JSONReader::Read(kTestConfigContents);
+  std::optional<base::Value> dict = base::JSONReader::Read(kTestConfigContents);
   ASSERT_TRUE(dict.has_value());
 
   GaiaConfig config(std::move(dict->GetDict()));
diff --git a/google_apis/gaia/gaia_oauth_client.cc b/google_apis/gaia/gaia_oauth_client.cc
index 0b595496..cb3e81e0 100644
--- a/google_apis/gaia/gaia_oauth_client.cc
+++ b/google_apis/gaia/gaia_oauth_client.cc
@@ -127,7 +127,7 @@
       std::string post_body /* may be empty if not needed*/,
       std::string authorization_header /* empty if not needed */,
       std::string http_method_override_header /* empty if not needed */,
-      absl::optional<net::RequestPriority> priority,
+      std::optional<net::RequestPriority> priority,
       int max_retries,
       GaiaOAuthClient::Delegate* delegate,
       const net::MutableNetworkTrafficAnnotationTag& traffic_annotation);
@@ -147,7 +147,7 @@
   net::BackoffEntry backoff_entry_;
 
   int num_retries_;
-  absl::optional<net::RequestPriority> priority_;
+  std::optional<net::RequestPriority> priority_;
   int max_retries_;
   GURL url_;
   net::MutableNetworkTrafficAnnotationTag traffic_annotation_;
@@ -210,7 +210,7 @@
               GURL(GaiaUrls::GetInstance()->oauth2_token_url()), post_body,
               /* authorization_header = */ std::string(),
               /* http_method_override_header = */ std::string(),
-              /* priority = */ absl::nullopt, max_retries, delegate,
+              /* priority = */ std::nullopt, max_retries, delegate,
               traffic_annotation);
 }
 
@@ -265,7 +265,7 @@
               post_body,
               /* authorization_header = */ std::string(),
               /* http_method_override_header = */ std::string(),
-              /* priority = */ absl::nullopt, max_retries, delegate,
+              /* priority = */ std::nullopt, max_retries, delegate,
               traffic_annotation);
 }
 
@@ -323,7 +323,7 @@
   MakeRequest(type, GaiaUrls::GetInstance()->oauth_user_info_url(),
               /* post_body = */ std::string(), auth,
               /* http_method_override_header = */ std::string(),
-              /* priority = */ absl::nullopt, max_retries, delegate,
+              /* priority = */ std::nullopt, max_retries, delegate,
               traffic_annotation);
 }
 
@@ -370,7 +370,7 @@
               GURL(GaiaUrls::GetInstance()->oauth2_token_info_url()), post_body,
               /* authorization_header = */ std::string(),
               /* http_method_override_header = */ std::string(),
-              /* priority = */ absl::nullopt, max_retries, delegate,
+              /* priority = */ std::nullopt, max_retries, delegate,
               traffic_annotation);
 }
 
@@ -436,7 +436,7 @@
     std::string post_body,
     std::string authorization_header,
     std::string http_method_override_header,
-    absl::optional<net::RequestPriority> priority,
+    std::optional<net::RequestPriority> priority,
     int max_retries,
     GaiaOAuthClient::Delegate* delegate,
     const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
@@ -541,7 +541,7 @@
     return;
   }
 
-  absl::optional<base::Value> message_value;
+  std::optional<base::Value> message_value;
   if (response_code == net::HTTP_OK && body) {
     std::string data = std::move(*body);
     message_value = base::JSONReader::Read(data);
@@ -605,7 +605,7 @@
         refresh_token = *dict_value;
       }
       int expires_in_seconds = 0;
-      if (const absl::optional<int> dict_value =
+      if (const std::optional<int> dict_value =
               response_dict.FindInt(kExpiresInValue)) {
         expires_in_seconds = *dict_value;
       }
diff --git a/google_apis/gaia/gaia_oauth_client_unittest.cc b/google_apis/gaia/gaia_oauth_client_unittest.cc
index 62f3c5fa..7677cc3 100644
--- a/google_apis/gaia/gaia_oauth_client_unittest.cc
+++ b/google_apis/gaia/gaia_oauth_client_unittest.cc
@@ -463,7 +463,7 @@
   auth.GetUserInfo("access_token", 1, &delegate);
   FlushNetwork();
 
-  absl::optional<base::Value> expected_value =
+  std::optional<base::Value> expected_value =
       base::JSONReader::Read(kDummyFullUserInfoResult);
   DCHECK(expected_value);
   ASSERT_TRUE(expected_value->is_dict());
diff --git a/google_apis/gaia/oauth2_access_token_fetcher_impl.cc b/google_apis/gaia/oauth2_access_token_fetcher_impl.cc
index f8d66cd..abba8e35c 100644
--- a/google_apis/gaia/oauth2_access_token_fetcher_impl.cc
+++ b/google_apis/gaia/oauth2_access_token_fetcher_impl.cc
@@ -244,7 +244,7 @@
                                      &error_subtype, &error_description);
   OAuth2Response response = OAuth2ResponseErrorToOAuth2Response(oauth2_error);
   RecordOAuth2Response(response);
-  absl::optional<GoogleServiceAuthError> error;
+  std::optional<GoogleServiceAuthError> error;
 
   switch (response) {
     case kOk:
@@ -396,7 +396,7 @@
   if (access_token)
     token_response->access_token = *access_token;
 
-  absl::optional<int> expires_in = dict->FindInt(kExpiresInKey);
+  std::optional<int> expires_in = dict->FindInt(kExpiresInKey);
   bool ok = access_token && expires_in.has_value();
   if (ok) {
     // The token will expire in |expires_in| seconds. Take a 10% error margin to
diff --git a/google_apis/gaia/oauth2_id_token_decoder.cc b/google_apis/gaia/oauth2_id_token_decoder.cc
index 008482a..c2111d2 100644
--- a/google_apis/gaia/oauth2_id_token_decoder.cc
+++ b/google_apis/gaia/oauth2_id_token_decoder.cc
@@ -6,13 +6,13 @@
 
 #include <memory>
 
+#include <optional>
 #include "base/base64url.h"
 #include "base/containers/contains.h"
 #include "base/json/json_reader.h"
 #include "base/logging.h"
 #include "base/strings/string_split.h"
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -28,13 +28,13 @@
 
 // Decodes the JWT ID token to a dictionary. Returns whether the decoding was
 // successful.
-absl::optional<base::Value::Dict> DecodeIdToken(const std::string id_token) {
+std::optional<base::Value::Dict> DecodeIdToken(const std::string id_token) {
   const std::vector<base::StringPiece> token_pieces =
       base::SplitStringPiece(base::StringPiece(id_token), ".",
                              base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
   if (token_pieces.size() != 3) {
     VLOG(1) << "Invalid id_token: not in JWT format";
-    return absl::nullopt;
+    return std::nullopt;
   }
   // Only the payload is used. The header is ignored, and signature
   // verification is not needed since the token was obtained directly from LSO.
@@ -43,13 +43,13 @@
                              base::Base64UrlDecodePolicy::IGNORE_PADDING,
                              &payload)) {
     VLOG(1) << "Invalid id_token: not in Base64Url encoding";
-    return absl::nullopt;
+    return std::nullopt;
   }
-  absl::optional<base::Value> decoded_payload = base::JSONReader::Read(payload);
+  std::optional<base::Value> decoded_payload = base::JSONReader::Read(payload);
   if (!decoded_payload.has_value() ||
       decoded_payload->type() != base::Value::Type::DICT) {
     VLOG(1) << "Invalid id_token: paylod is not a well-formed JSON";
-    return absl::nullopt;
+    return std::nullopt;
   }
   return std::move(decoded_payload->GetDict());
 }
@@ -61,7 +61,7 @@
                      std::vector<std::string>* out_service_flags) {
   DCHECK(out_service_flags->empty());
 
-  absl::optional<base::Value::Dict> decoded_payload = DecodeIdToken(id_token);
+  std::optional<base::Value::Dict> decoded_payload = DecodeIdToken(id_token);
   if (!decoded_payload.has_value()) {
     VLOG(1) << "Failed to decode the id_token";
     return false;
diff --git a/google_apis/gaia/oauth2_mint_token_flow.cc b/google_apis/gaia/oauth2_mint_token_flow.cc
index 1c97493..7d3b0b0 100644
--- a/google_apis/gaia/oauth2_mint_token_flow.cc
+++ b/google_apis/gaia/oauth2_mint_token_flow.cc
@@ -10,6 +10,7 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/command_line.h"
 #include "base/containers/span.h"
 #include "base/functional/bind.h"
@@ -28,7 +29,6 @@
 #include "net/base/net_errors.h"
 #include "net/cookies/cookie_constants.h"
 #include "services/network/public/mojom/url_response_head.mojom.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -80,7 +80,7 @@
   if (body)
     response_body = std::move(*body);
 
-  absl::optional<base::Value> value = base::JSONReader::Read(response_body);
+  std::optional<base::Value> value = base::JSONReader::Read(response_body);
   if (!value || !value->is_dict()) {
     int http_response_code = -1;
     if (head && head->headers)
@@ -296,7 +296,7 @@
   if (body)
     response_body = std::move(*body);
 
-  absl::optional<base::Value> value = base::JSONReader::Read(response_body);
+  std::optional<base::Value> value = base::JSONReader::Read(response_body);
   if (!value || !value->is_dict()) {
     RecordApiCallResult(OAuth2MintTokenApiCallResult::kParseJsonFailure);
     ReportFailure(GoogleServiceAuthError::FromUnexpectedServiceResponse(
@@ -452,8 +452,8 @@
       const std::string* path = cookie_dict->FindString("path");
       const std::string* max_age_seconds =
           cookie_dict->FindString("maxAgeSeconds");
-      absl::optional<bool> is_secure = cookie_dict->FindBool("isSecure");
-      absl::optional<bool> is_http_only = cookie_dict->FindBool("isHttpOnly");
+      std::optional<bool> is_secure = cookie_dict->FindBool("isSecure");
+      std::optional<bool> is_http_only = cookie_dict->FindBool("isHttpOnly");
       const std::string* same_site = cookie_dict->FindString("sameSite");
 
       int64_t max_age = -1;
@@ -474,7 +474,7 @@
               is_http_only ? *is_http_only : false,
               net::StringToCookieSameSite(same_site ? *same_site : ""),
               net::COOKIE_PRIORITY_DEFAULT, /* same_party */ false,
-              /* partition_key */ absl::nullopt);
+              /* partition_key */ std::nullopt);
       cookies.push_back(*cookie);
     }
   }
diff --git a/google_apis/gaia/oauth2_mint_token_flow_unittest.cc b/google_apis/gaia/oauth2_mint_token_flow_unittest.cc
index 7bb88d6..35b4673 100644
--- a/google_apis/gaia/oauth2_mint_token_flow_unittest.cc
+++ b/google_apis/gaia/oauth2_mint_token_flow_unittest.cc
@@ -11,6 +11,7 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/json/json_reader.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/utf_string_conversions.h"
@@ -25,7 +26,6 @@
 #include "services/network/test/test_utils.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using testing::_;
 using testing::ByRef;
@@ -119,13 +119,13 @@
           resolution_data.url, "test_name", "test_value", "test.com", "/",
           base::Time(), base::Time(), base::Time(), false, true,
           net::CookieSameSite::LAX_MODE, net::COOKIE_PRIORITY_DEFAULT, false,
-          absl::nullopt));
+          std::nullopt));
   resolution_data.cookies.push_back(
       *net::CanonicalCookie::CreateSanitizedCookie(
           resolution_data.url, "test_name2", "test_value2", "test.com", "/",
           base::Time(), base::Time(), base::Time(), false, false,
           net::CookieSameSite::UNSPECIFIED, net::COOKIE_PRIORITY_DEFAULT, false,
-          absl::nullopt));
+          std::nullopt));
   return resolution_data;
 }
 
diff --git a/google_apis/gaia/oauth_multilogin_result.cc b/google_apis/gaia/oauth_multilogin_result.cc
index 15f0e692..41c6694 100644
--- a/google_apis/gaia/oauth_multilogin_result.cc
+++ b/google_apis/gaia/oauth_multilogin_result.cc
@@ -6,13 +6,13 @@
 
 #include <algorithm>
 
+#include <optional>
 #include "base/compiler_specific.h"
 #include "base/json/json_reader.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_piece.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -99,10 +99,10 @@
     const std::string* domain = cookie_dict.FindString("domain");
     const std::string* host = cookie_dict.FindString("host");
     const std::string* path = cookie_dict.FindString("path");
-    absl::optional<bool> is_secure = cookie_dict.FindBool("isSecure");
-    absl::optional<bool> is_http_only = cookie_dict.FindBool("isHttpOnly");
+    std::optional<bool> is_secure = cookie_dict.FindBool("isSecure");
+    std::optional<bool> is_http_only = cookie_dict.FindBool("isHttpOnly");
     const std::string* priority = cookie_dict.FindString("priority");
-    absl::optional<double> expiration_delta = cookie_dict.FindDouble("maxAge");
+    std::optional<double> expiration_delta = cookie_dict.FindDouble("maxAge");
     const std::string* same_site = cookie_dict.FindString("sameSite");
     const std::string* same_party = cookie_dict.FindString("sameParty");
 
@@ -138,7 +138,7 @@
             /*last_access=*/now, /*last_update=*/now, is_secure.value_or(true),
             is_http_only.value_or(true), samesite_mode,
             net::StringToCookiePriority(priority ? *priority : "medium"),
-            same_party_bool, /*partition_key=*/absl::nullopt,
+            same_party_bool, /*partition_key=*/std::nullopt,
             net::CookieSourceScheme::kUnset, url::PORT_UNSPECIFIED);
     // If the unique_ptr is null, it means the cookie was not canonical.
     // FromStorage() also uses a less strict version of IsCanonical(), we need
@@ -154,7 +154,7 @@
 OAuthMultiloginResult::OAuthMultiloginResult(const std::string& raw_data) {
   base::StringPiece data = StripXSSICharacters(raw_data);
   status_ = OAuthMultiloginResponseStatus::kUnknownStatus;
-  absl::optional<base::Value> json_data = base::JSONReader::Read(data);
+  std::optional<base::Value> json_data = base::JSONReader::Read(data);
   if (!json_data) {
     RecordMultiloginResponseStatus(status_);
     return;
diff --git a/google_apis/gcm/base/socket_stream_unittest.cc b/google_apis/gcm/base/socket_stream_unittest.cc
index eadd92a..2c37173 100644
--- a/google_apis/gcm/base/socket_stream_unittest.cc
+++ b/google_apis/gcm/base/socket_stream_unittest.cc
@@ -243,8 +243,8 @@
       mojo_socket_remote_.BindNewPipeAndPassReceiver(),
       mojo::NullRemote() /* observer */,
       base::BindLambdaForTesting(
-          [&](int result, const absl::optional<net::IPEndPoint>& local_addr,
-              const absl::optional<net::IPEndPoint>& peer_addr,
+          [&](int result, const std::optional<net::IPEndPoint>& local_addr,
+              const std::optional<net::IPEndPoint>& peer_addr,
               mojo::ScopedDataPipeConsumerHandle receive_pipe_handle,
               mojo::ScopedDataPipeProducerHandle send_pipe_handle) {
             net_error = result;
diff --git a/google_apis/gcm/engine/connection_factory_impl.cc b/google_apis/gcm/engine/connection_factory_impl.cc
index a6404ee..b010f25 100644
--- a/google_apis/gcm/engine/connection_factory_impl.cc
+++ b/google_apis/gcm/engine/connection_factory_impl.cc
@@ -412,8 +412,8 @@
 
 void ConnectionFactoryImpl::OnConnectDone(
     int result,
-    const absl::optional<net::IPEndPoint>& local_addr,
-    const absl::optional<net::IPEndPoint>& peer_addr,
+    const std::optional<net::IPEndPoint>& local_addr,
+    const std::optional<net::IPEndPoint>& peer_addr,
     mojo::ScopedDataPipeConsumerHandle receive_stream,
     mojo::ScopedDataPipeProducerHandle send_stream) {
   DCHECK_NE(net::ERR_IO_PENDING, result);
diff --git a/google_apis/gcm/engine/connection_factory_impl.h b/google_apis/gcm/engine/connection_factory_impl.h
index dd45984..284aa3f 100644
--- a/google_apis/gcm/engine/connection_factory_impl.h
+++ b/google_apis/gcm/engine/connection_factory_impl.h
@@ -96,8 +96,8 @@
 
   // Callback for Socket connection completion. This is public for testing.
   void OnConnectDone(int result,
-                     const absl::optional<net::IPEndPoint>& local_addr,
-                     const absl::optional<net::IPEndPoint>& peer_addr,
+                     const std::optional<net::IPEndPoint>& local_addr,
+                     const std::optional<net::IPEndPoint>& peer_addr,
                      mojo::ScopedDataPipeConsumerHandle receive_stream,
                      mojo::ScopedDataPipeProducerHandle send_stream);
 
diff --git a/google_apis/gcm/engine/connection_factory_impl_unittest.cc b/google_apis/gcm/engine/connection_factory_impl_unittest.cc
index dc9c35a..5081aa63 100644
--- a/google_apis/gcm/engine/connection_factory_impl_unittest.cc
+++ b/google_apis/gcm/engine/connection_factory_impl_unittest.cc
@@ -8,6 +8,7 @@
 #include <memory>
 #include <utility>
 
+#include <optional>
 #include "base/functional/bind.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
@@ -27,7 +28,6 @@
 #include "services/network/test/fake_test_cert_verifier_params_factory.h"
 #include "services/network/test/test_network_connection_tracker.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class Policy;
 
diff --git a/google_apis/gcm/engine/connection_handler_impl_unittest.cc b/google_apis/gcm/engine/connection_handler_impl_unittest.cc
index 1c0dea2..25880b5 100644
--- a/google_apis/gcm/engine/connection_handler_impl_unittest.cc
+++ b/google_apis/gcm/engine/connection_handler_impl_unittest.cc
@@ -262,8 +262,8 @@
       mojo_socket_remote_.BindNewPipeAndPassReceiver(),
       mojo::NullRemote() /* observer */,
       base::BindLambdaForTesting(
-          [&](int result, const absl::optional<net::IPEndPoint>& local_addr,
-              const absl::optional<net::IPEndPoint>& peer_addr,
+          [&](int result, const std::optional<net::IPEndPoint>& local_addr,
+              const std::optional<net::IPEndPoint>& peer_addr,
               mojo::ScopedDataPipeConsumerHandle receive_pipe_handle,
               mojo::ScopedDataPipeProducerHandle send_pipe_handle) {
             net_error = result;
diff --git a/google_apis/tasks/tasks_api_response_types.cc b/google_apis/tasks/tasks_api_response_types.cc
index 11338e7..a158c75 100644
--- a/google_apis/tasks/tasks_api_response_types.cc
+++ b/google_apis/tasks/tasks_api_response_types.cc
@@ -7,6 +7,7 @@
 #include <memory>
 #include <string>
 
+#include <optional>
 #include "base/json/json_value_converter.h"
 #include "base/logging.h"
 #include "base/time/time.h"
@@ -14,7 +15,6 @@
 #include "google_apis/common/parser_util.h"
 #include "google_apis/common/time_util.h"
 #include "google_apis/tasks/tasks_api_task_status.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace google_apis::tasks {
 namespace {
@@ -43,7 +43,7 @@
 }
 
 bool ConvertTaskDueDate(base::StringPiece input,
-                        absl::optional<base::Time>* output) {
+                        std::optional<base::Time>* output) {
   base::Time due;
   if (!util::GetTimeFromString(input, &due)) {
     return false;
@@ -120,7 +120,7 @@
       kApiResponseStatusKey, &Task::status_, &ConvertTaskStatus);
   converter->RegisterStringField(kApiResponseParentKey, &Task::parent_id_);
   converter->RegisterStringField(kApiResponsePositionKey, &Task::position_);
-  converter->RegisterCustomField<absl::optional<base::Time>>(
+  converter->RegisterCustomField<std::optional<base::Time>>(
       kApiResponseDueKey, &Task::due_, &ConvertTaskDueDate);
   converter->RegisterRepeatedMessage<TaskLink>(kApiResponseLinksKey,
                                                &Task::links_);
diff --git a/google_apis/tasks/tasks_api_response_types.h b/google_apis/tasks/tasks_api_response_types.h
index 8821b50..61f810c 100644
--- a/google_apis/tasks/tasks_api_response_types.h
+++ b/google_apis/tasks/tasks_api_response_types.h
@@ -9,9 +9,9 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/time/time.h"
 #include "google_apis/tasks/tasks_api_task_status.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 template <class StructType>
@@ -123,7 +123,7 @@
   TaskStatus status() const { return status_; }
   const std::string& parent_id() const { return parent_id_; }
   const std::string& position() const { return position_; }
-  const absl::optional<base::Time>& due() const { return due_; }
+  const std::optional<base::Time>& due() const { return due_; }
   const std::vector<std::unique_ptr<TaskLink>>& links() const { return links_; }
   const std::string& notes() const { return notes_; }
 
@@ -146,7 +146,7 @@
   // Due date of the task (comes as a RFC 3339 timestamp and converted to
   // `base::Time`). The due date only records date information. Not all tasks
   // have a due date.
-  absl::optional<base::Time> due_ = absl::nullopt;
+  std::optional<base::Time> due_ = std::nullopt;
 
   // Collection of links related to this task.
   std::vector<std::unique_ptr<TaskLink>> links_;
diff --git a/google_apis/tasks/tasks_api_url_generator_utils.cc b/google_apis/tasks/tasks_api_url_generator_utils.cc
index 37e7dbd..862bc9e 100644
--- a/google_apis/tasks/tasks_api_url_generator_utils.cc
+++ b/google_apis/tasks/tasks_api_url_generator_utils.cc
@@ -6,12 +6,12 @@
 
 #include <string>
 
+#include <optional>
 #include "base/check.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "google_apis/gaia/gaia_urls.h"
 #include "net/base/url_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace google_apis::tasks {
@@ -40,7 +40,7 @@
 
 }  // namespace
 
-GURL GetListTaskListsUrl(absl::optional<int> max_results,
+GURL GetListTaskListsUrl(std::optional<int> max_results,
                          const std::string& page_token) {
   GURL url = GetBaseUrl().Resolve(kTaskListsListUrl);
   url = net::AppendOrReplaceQueryParameter(url, kFieldsParameterName,
@@ -59,7 +59,7 @@
 
 GURL GetListTasksUrl(const std::string& task_list_id,
                      bool include_completed,
-                     absl::optional<int> max_results,
+                     std::optional<int> max_results,
                      const std::string& page_token) {
   CHECK(!task_list_id.empty());
   GURL url = GetBaseUrl().Resolve(base::ReplaceStringPlaceholders(
diff --git a/google_apis/tasks/tasks_api_url_generator_utils.h b/google_apis/tasks/tasks_api_url_generator_utils.h
index cf75800b..f16ed74 100644
--- a/google_apis/tasks/tasks_api_url_generator_utils.h
+++ b/google_apis/tasks/tasks_api_url_generator_utils.h
@@ -7,7 +7,7 @@
 
 #include <string>
 
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include <optional>
 
 class GURL;
 
@@ -15,11 +15,11 @@
 
 // Returns a URL to fetch all the authenticated user's task lists.
 // `max_results` - maximum number of task lists returned on one page.
-//                 Adds `maxResults` query parameter if not `absl::nullopt`.
+//                 Adds `maxResults` query parameter if not `std::nullopt`.
 // `page_token`  - token specifying the result page to return.
 //                 Adds `pageToken` query parameter if not empty.
 // https://developers.google.com/tasks/reference/rest/v1/tasklists/list
-GURL GetListTaskListsUrl(absl::optional<int> max_results,
+GURL GetListTaskListsUrl(std::optional<int> max_results,
                          const std::string& page_token);
 
 // Returns a URL to fetch all tasks in the specified task list.
@@ -27,13 +27,13 @@
 // `include_completed` - flag indicating whether completed tasks are returned
 //                       in the result.
 // `max_results`       - maximum number of tasks returned on one page. Adds
-//                       `maxResults` query parameter if not `absl::nullopt`.
+//                       `maxResults` query parameter if not `std::nullopt`.
 // `page_token`        - token specifying the result page to return. Adds
 //                       `pageToken` query parameter if not empty.
 // https://developers.google.com/tasks/reference/rest/v1/tasks/list
 GURL GetListTasksUrl(const std::string& task_list_id,
                      bool include_completed,
-                     absl::optional<int> max_results,
+                     std::optional<int> max_results,
                      const std::string& page_token);
 
 // Returns a URL to partially update the specified task.
diff --git a/google_apis/tasks/tasks_api_url_generator_utils_unittest.cc b/google_apis/tasks/tasks_api_url_generator_utils_unittest.cc
index 6d7e3b8..991f377 100644
--- a/google_apis/tasks/tasks_api_url_generator_utils_unittest.cc
+++ b/google_apis/tasks/tasks_api_url_generator_utils_unittest.cc
@@ -4,14 +4,14 @@
 
 #include "google_apis/tasks/tasks_api_url_generator_utils.h"
 
+#include <optional>
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 namespace google_apis::tasks {
 
 TEST(TasksApiUrlGeneratorUtilsTest, ReturnsListTaskListsUrl) {
-  EXPECT_EQ(GetListTaskListsUrl(/*max_results=*/absl::nullopt,
+  EXPECT_EQ(GetListTaskListsUrl(/*max_results=*/std::nullopt,
                                 /*page_token=*/""),
             "https://tasks.googleapis.com/tasks/v1/users/@me/lists"
             "?fields=kind%2Citems(id%2Ctitle%2Cupdated)%2CnextPageToken");
@@ -28,7 +28,7 @@
 
 TEST(TasksApiUrlGeneratorUtilsTest, ReturnsListTasksUrl) {
   EXPECT_EQ(GetListTasksUrl("task-list-id", /*include_completed=*/false,
-                            /*max_results=*/absl::nullopt,
+                            /*max_results=*/std::nullopt,
                             /*page_token=*/""),
             "https://tasks.googleapis.com/tasks/v1/lists/task-list-id/tasks"
             "?fields=kind%2Citems(id%2Ctitle%2Cstatus%2Cparent%2Cposition"
diff --git a/gpu/command_buffer/client/client_transfer_cache.cc b/gpu/command_buffer/client/client_transfer_cache.cc
index fa3b59f..e45e08d 100644
--- a/gpu/command_buffer/client/client_transfer_cache.cc
+++ b/gpu/command_buffer/client/client_transfer_cache.cc
@@ -16,7 +16,7 @@
   DCHECK(!transfer_buffer_ptr_);
   mapped_ptr_.emplace(size, client_->cmd_buffer_helper(), mapped_memory);
   if (!mapped_ptr_->valid()) {
-    mapped_ptr_ = absl::nullopt;
+    mapped_ptr_ = std::nullopt;
     return nullptr;
   }
   return mapped_ptr_->address();
@@ -30,7 +30,7 @@
   transfer_buffer_ptr_.emplace(size, client_->cmd_buffer_helper(),
                                transfer_buffer);
   if (!transfer_buffer_ptr_->valid()) {
-    transfer_buffer_ptr_ = absl::nullopt;
+    transfer_buffer_ptr_ = std::nullopt;
     return nullptr;
   }
   return transfer_buffer_ptr_->address();
@@ -44,8 +44,8 @@
   if (!handle.IsValid()) {
     // Release any data pointers. Keeping these alive longer can lead to issues
     // with transfer buffer reallocation.
-    mapped_ptr_ = absl::nullopt;
-    transfer_buffer_ptr_ = absl::nullopt;
+    mapped_ptr_ = std::nullopt;
+    transfer_buffer_ptr_ = std::nullopt;
     return;
   }
 
@@ -54,14 +54,14 @@
     client_->IssueCreateTransferCacheEntry(
         type, id, handle.shm_id(), handle.byte_offset(), mapped_ptr_->shm_id(),
         mapped_ptr_->offset(), mapped_ptr_->size());
-    mapped_ptr_ = absl::nullopt;
+    mapped_ptr_ = std::nullopt;
   } else {
     DCHECK(!mapped_ptr_);
     client_->IssueCreateTransferCacheEntry(
         type, id, handle.shm_id(), handle.byte_offset(),
         transfer_buffer_ptr_->shm_id(), transfer_buffer_ptr_->offset(),
         transfer_buffer_ptr_->size());
-    transfer_buffer_ptr_ = absl::nullopt;
+    transfer_buffer_ptr_ = std::nullopt;
   }
 }
 
diff --git a/gpu/command_buffer/client/client_transfer_cache.h b/gpu/command_buffer/client/client_transfer_cache.h
index d13297f..a03f273 100644
--- a/gpu/command_buffer/client/client_transfer_cache.h
+++ b/gpu/command_buffer/client/client_transfer_cache.h
@@ -7,6 +7,7 @@
 
 #include <map>
 
+#include <optional>
 #include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/synchronization/lock.h"
@@ -15,7 +16,6 @@
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "gpu/command_buffer/client/mapped_memory.h"
 #include "gpu/command_buffer/client/transfer_buffer.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace gpu {
 class MappedMemoryManager;
@@ -119,8 +119,8 @@
 
   const raw_ptr<Client> client_;  // not owned --- client_ outlives this
 
-  absl::optional<ScopedMappedMemoryPtr> mapped_ptr_;
-  absl::optional<ScopedTransferBufferPtr> transfer_buffer_ptr_;
+  std::optional<ScopedMappedMemoryPtr> mapped_ptr_;
+  std::optional<ScopedTransferBufferPtr> transfer_buffer_ptr_;
 
   // Access to other members must always be done with |lock_| held.
   base::Lock lock_;
diff --git a/gpu/command_buffer/client/gl_helper.cc b/gpu/command_buffer/client/gl_helper.cc
index 279a015..872b391 100644
--- a/gpu/command_buffer/client/gl_helper.cc
+++ b/gpu/command_buffer/client/gl_helper.cc
@@ -126,11 +126,11 @@
   const std::unique_ptr<GLHelper::ScalerInterface> v_planerizer_;
 
   // Intermediate texture, holding the scaler's output.
-  absl::optional<TextureHolder> intermediate_;
+  std::optional<TextureHolder> intermediate_;
 
   // Intermediate texture, holding the UV interim output (if the MRT shader
   // is being used).
-  absl::optional<ScopedTexture> uv_;
+  std::optional<ScopedTexture> uv_;
 };
 
 }  // namespace
@@ -696,7 +696,7 @@
     if (!intermediate_ || intermediate_->size() != scaler_output_size)
       intermediate_.emplace(gl_, scaler_output_size);
   } else {
-    intermediate_ = absl::nullopt;
+    intermediate_ = std::nullopt;
   }
 
   // Size the interim UV plane and the three output planes.
diff --git a/gpu/command_buffer/client/gl_helper_scaling.cc b/gpu/command_buffer/client/gl_helper_scaling.cc
index fc254d3..c4600b3 100644
--- a/gpu/command_buffer/client/gl_helper_scaling.cc
+++ b/gpu/command_buffer/client/gl_helper_scaling.cc
@@ -11,6 +11,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/containers/circular_deque.h"
 #include "base/functional/bind.h"
 #include "base/lazy_instance.h"
@@ -21,7 +22,6 @@
 #include "base/trace_event/trace_event.h"
 #include "gpu/GLES2/gl2extchromium.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/geometry/rect_f.h"
@@ -581,7 +581,7 @@
     gfx::Vector2d scale_to;
     GLenum readback_format;
   };
-  absl::optional<ChainProperties> chain_properties_;
+  std::optional<ChainProperties> chain_properties_;
 };
 
 // The important inputs for this function is |x_ops| and |y_ops|. They represent
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h
index 750bfd0..326fc96 100644
--- a/gpu/command_buffer/client/gles2_implementation.h
+++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -16,6 +16,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/compiler_specific.h"
 #include "base/containers/queue.h"
 #include "base/memory/raw_ptr.h"
@@ -39,7 +40,6 @@
 #include "gpu/command_buffer/common/context_creation_attribs.h"
 #include "gpu/command_buffer/common/context_result.h"
 #include "gpu/command_buffer/common/debug_marker_manager.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace gpu {
 
@@ -814,8 +814,8 @@
   std::unique_ptr<BufferTracker> buffer_tracker_;
   std::unique_ptr<ReadbackBufferShadowTracker> readback_buffer_shadow_tracker_;
 
-  absl::optional<ScopedMappedMemoryPtr> font_mapped_buffer_;
-  absl::optional<ScopedTransferBufferPtr> raster_mapped_buffer_;
+  std::optional<ScopedMappedMemoryPtr> font_mapped_buffer_;
+  std::optional<ScopedTransferBufferPtr> raster_mapped_buffer_;
 
   base::RepeatingCallback<void(const char*, int32_t)> error_message_callback_;
   bool deferring_error_callbacks_ = false;
diff --git a/gpu/command_buffer/client/query_tracker.h b/gpu/command_buffer/client/query_tracker.h
index 4d5e74a8..719de63 100644
--- a/gpu/command_buffer/client/query_tracker.h
+++ b/gpu/command_buffer/client/query_tracker.h
@@ -14,6 +14,7 @@
 #include <memory>
 #include <unordered_map>
 
+#include <optional>
 #include "base/atomicops.h"
 #include "base/containers/circular_deque.h"
 #include "base/containers/flat_map.h"
@@ -21,7 +22,6 @@
 #include "base/memory/raw_ptr.h"
 #include "gles2_impl_export.h"
 #include "gpu/command_buffer/common/gles2_cmd_format.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace gpu {
 
@@ -201,7 +201,7 @@
     uint64_t client_begin_time_us_;  // Only used for latency query target.
     uint64_t result_;
 
-    absl::optional<base::OnceClosure> on_completed_callback_;
+    std::optional<base::OnceClosure> on_completed_callback_;
   };
 
   explicit QueryTracker(MappedMemoryManager* manager);
diff --git a/gpu/command_buffer/client/raster_implementation.cc b/gpu/command_buffer/client/raster_implementation.cc
index c206e05..357b50e 100644
--- a/gpu/command_buffer/client/raster_implementation.cc
+++ b/gpu/command_buffer/client/raster_implementation.cc
@@ -150,8 +150,8 @@
   }
 
  private:
-  absl::optional<ScopedMappedMemoryPtr> scoped_mapped_ptr_;
-  absl::optional<ScopedTransferBufferPtr> scoped_transfer_ptr_;
+  std::optional<ScopedMappedMemoryPtr> scoped_mapped_ptr_;
+  std::optional<ScopedTransferBufferPtr> scoped_transfer_ptr_;
 };
 
 }  // namespace
@@ -1106,7 +1106,7 @@
   raster_mapped_buffer_.emplace(size, helper_, transfer_buffer_);
   if (!raster_mapped_buffer_->valid()) {
     SetGLError(GL_INVALID_OPERATION, "glMapRasterCHROMIUM", "size too big");
-    raster_mapped_buffer_ = absl::nullopt;
+    raster_mapped_buffer_ = std::nullopt;
     return nullptr;
   }
   *size_allocated = raster_mapped_buffer_->size();
@@ -1128,7 +1128,7 @@
   font_mapped_buffer_.emplace(size, helper_, mapped_memory_.get());
   if (!font_mapped_buffer_->valid()) {
     SetGLError(GL_INVALID_OPERATION, "glMapFontBufferCHROMIUM", "size too big");
-    font_mapped_buffer_ = absl::nullopt;
+    font_mapped_buffer_ = std::nullopt;
     return nullptr;
   }
   return font_mapped_buffer_->address();
@@ -1143,7 +1143,7 @@
   DCHECK(raster_mapped_buffer_->valid());
   if (total_written_size == 0) {
     raster_mapped_buffer_->Discard();
-    raster_mapped_buffer_ = absl::nullopt;
+    raster_mapped_buffer_ = std::nullopt;
     return;
   }
   raster_mapped_buffer_->Shrink(total_written_size);
@@ -1163,8 +1163,8 @@
         raster_written_size, font_shm_id, font_shm_offset, font_shm_size);
   }
 
-  raster_mapped_buffer_ = absl::nullopt;
-  font_mapped_buffer_ = absl::nullopt;
+  raster_mapped_buffer_ = std::nullopt;
+  font_mapped_buffer_ = std::nullopt;
   CheckGLError();
 }
 
diff --git a/gpu/command_buffer/client/raster_implementation.h b/gpu/command_buffer/client/raster_implementation.h
index 10890e9..810cfb8 100644
--- a/gpu/command_buffer/client/raster_implementation.h
+++ b/gpu/command_buffer/client/raster_implementation.h
@@ -13,6 +13,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/memory/raw_ptr.h"
 #include "base/trace_event/memory_dump_provider.h"
 #include "cc/paint/paint_cache.h"
@@ -31,7 +32,6 @@
 #include "gpu/command_buffer/common/id_allocator.h"
 #include "gpu/command_buffer/common/raster_cmd_format.h"
 #include "gpu/raster_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace cc {
 class TransferCacheSerializeHelper;
@@ -399,8 +399,8 @@
   // Used to check for single threaded access.
   int use_count_;
 
-  absl::optional<ScopedMappedMemoryPtr> font_mapped_buffer_;
-  absl::optional<ScopedTransferBufferPtr> raster_mapped_buffer_;
+  std::optional<ScopedMappedMemoryPtr> font_mapped_buffer_;
+  std::optional<ScopedTransferBufferPtr> raster_mapped_buffer_;
 
   base::RepeatingCallback<void(const char*, int32_t)> error_message_callback_;
 
@@ -431,7 +431,7 @@
     bool can_use_lcd_text = false;
     sk_sp<SkColorSpace> color_space;
   };
-  absl::optional<RasterProperties> raster_properties_;
+  std::optional<RasterProperties> raster_properties_;
 
   uint32_t max_inlined_entry_size_;
   ClientTransferCache transfer_cache_;
diff --git a/gpu/command_buffer/common/skia_utils.cc b/gpu/command_buffer/common/skia_utils.cc
index 99d368d..1b37f93d1 100644
--- a/gpu/command_buffer/common/skia_utils.cc
+++ b/gpu/command_buffer/common/skia_utils.cc
@@ -26,7 +26,7 @@
   // This should never outlive the provided ProcessMemoryDump, as it should
   // always be scoped to a single OnMemoryDump funciton call.
   SkiaGpuTraceMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
-                         absl::optional<uint64_t> share_group_tracing_guid)
+                         std::optional<uint64_t> share_group_tracing_guid)
       : pmd_(pmd),
         share_group_tracing_guid_(share_group_tracing_guid),
         tracing_process_id_(base::trace_event::MemoryDumpManager::GetInstance()
@@ -131,7 +131,7 @@
   }
 
   raw_ptr<base::trace_event::ProcessMemoryDump> pmd_;
-  absl::optional<uint64_t> share_group_tracing_guid_;
+  std::optional<uint64_t> share_group_tracing_guid_;
   uint64_t tracing_process_id_;
 };
 
@@ -139,7 +139,7 @@
 
 void DumpGrMemoryStatistics(const GrDirectContext* context,
                             base::trace_event::ProcessMemoryDump* pmd,
-                            absl::optional<uint64_t> tracing_guid) {
+                            std::optional<uint64_t> tracing_guid) {
   SkiaGpuTraceMemoryDump trace_memory_dump(pmd, tracing_guid);
   context->dumpMemoryStatistics(&trace_memory_dump);
 }
diff --git a/gpu/command_buffer/common/skia_utils.h b/gpu/command_buffer/common/skia_utils.h
index 04720d2..d9e106c 100644
--- a/gpu/command_buffer/common/skia_utils.h
+++ b/gpu/command_buffer/common/skia_utils.h
@@ -6,8 +6,8 @@
 #define GPU_COMMAND_BUFFER_COMMON_SKIA_UTILS_H_
 
 #include <cstdint>
+#include <optional>
 #include "gpu/raster_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class GrDirectContext;
 
@@ -25,7 +25,7 @@
 RASTER_EXPORT void DumpGrMemoryStatistics(
     const GrDirectContext* context,
     base::trace_event::ProcessMemoryDump* pmd,
-    absl::optional<uint64_t> tracing_guid);
+    std::optional<uint64_t> tracing_guid);
 
 // Dumps a single"skia/grpu_resources/context_0x{&context}" entry with total
 // cache usage. Designed for background dumps.
diff --git a/gpu/command_buffer/common/swap_buffers_complete_params.h b/gpu/command_buffer/common/swap_buffers_complete_params.h
index a14a3fc..59ee7523 100644
--- a/gpu/command_buffer/common/swap_buffers_complete_params.h
+++ b/gpu/command_buffer/common/swap_buffers_complete_params.h
@@ -7,9 +7,9 @@
 
 #include <vector>
 
+#include <optional>
 #include "gpu/command_buffer/common/mailbox.h"
 #include "gpu/gpu_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/ca_layer_params.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/swap_result.h"
@@ -29,7 +29,7 @@
   // Damage area of the current backing buffer compare to the previous swapped
   // buffer. The renderer can use it as hint for minimizing drawing area for the
   // next frame.
-  absl::optional<gfx::Rect> frame_buffer_damage_area;
+  std::optional<gfx::Rect> frame_buffer_damage_area;
 
   // The mailbox corresponding to the primary plane that was just swapped to
   // the front buffer. The overlay processor can use it to extract the buffer
diff --git a/gpu/command_buffer/service/context_state.cc b/gpu/command_buffer/service/context_state.cc
index 126e09d5..4a875af 100644
--- a/gpu/command_buffer/service/context_state.cc
+++ b/gpu/command_buffer/service/context_state.cc
@@ -9,13 +9,13 @@
 #include <algorithm>
 #include <cmath>
 
+#include <optional>
 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
 #include "gpu/command_buffer/service/buffer_manager.h"
 #include "gpu/command_buffer/service/framebuffer_manager.h"
 #include "gpu/command_buffer/service/program_manager.h"
 #include "gpu/command_buffer/service/renderbuffer_manager.h"
 #include "gpu/command_buffer/service/transform_feedback_manager.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_implementation.h"
 #include "ui/gl/gl_version_info.h"
@@ -339,7 +339,7 @@
   if (const auto& cur_sampler = sampler_units[unit])
     cur_id = cur_sampler->service_id();
 
-  absl::optional<GLuint> prev_id;
+  std::optional<GLuint> prev_id;
   if (prev_state) {
     const auto& prev_sampler = prev_state->sampler_units[unit];
     prev_id.emplace(prev_sampler ? prev_sampler->service_id() : 0);
diff --git a/gpu/command_buffer/service/dawn_context_provider.cc b/gpu/command_buffer/service/dawn_context_provider.cc
index 6de2d30d..d652dbd 100644
--- a/gpu/command_buffer/service/dawn_context_provider.cc
+++ b/gpu/command_buffer/service/dawn_context_provider.cc
@@ -439,7 +439,7 @@
   return device_.HasFeature(feature);
 }
 
-absl::optional<error::ContextLostReason> DawnContextProvider::GetResetStatus()
+std::optional<error::ContextLostReason> DawnContextProvider::GetResetStatus()
     const {
   base::AutoLock auto_lock(context_lost_lock_);
   return context_lost_reason_;
diff --git a/gpu/command_buffer/service/dawn_context_provider.h b/gpu/command_buffer/service/dawn_context_provider.h
index 75380b7..2c37d59 100644
--- a/gpu/command_buffer/service/dawn_context_provider.h
+++ b/gpu/command_buffer/service/dawn_context_provider.h
@@ -9,6 +9,7 @@
 
 #include <memory>
 
+#include <optional>
 #include "base/memory/raw_ptr.h"
 #include "base/synchronization/lock.h"
 #include "base/thread_annotations.h"
@@ -18,7 +19,6 @@
 #include "gpu/config/gpu_driver_bug_workarounds.h"
 #include "gpu/config/gpu_preferences.h"
 #include "gpu/gpu_gles2_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/dawn/include/dawn/native/DawnNative.h"
 #include "third_party/skia/include/gpu/graphite/ContextOptions.h"
 #include "third_party/skia/include/gpu/graphite/dawn/DawnTypes.h"
@@ -87,7 +87,7 @@
 
   bool SupportsFeature(wgpu::FeatureName feature);
 
-  absl::optional<error::ContextLostReason> GetResetStatus() const;
+  std::optional<error::ContextLostReason> GetResetStatus() const;
 
   void OnError(WGPUErrorType error_type, const char* message);
 
@@ -110,7 +110,7 @@
   std::unique_ptr<skgpu::graphite::Context> graphite_context_;
 
   mutable base::Lock context_lost_lock_;
-  absl::optional<error::ContextLostReason> context_lost_reason_
+  std::optional<error::ContextLostReason> context_lost_reason_
       GUARDED_BY(context_lost_lock_);
 };
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index e29e6553..d1b38d3 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -19,6 +19,7 @@
 #include <unordered_map>
 #include <utility>
 
+#include <optional>
 #include "base/containers/contains.h"
 #include "base/containers/cxx20_erase.h"
 #include "base/containers/flat_set.h"
@@ -85,7 +86,6 @@
 #include "gpu/command_buffer/service/vertex_attrib_manager.h"
 #include "gpu/config/gpu_finch_features.h"
 #include "gpu/config/gpu_preferences.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/buffer_types.h"
 #include "ui/gfx/color_space.h"
 #include "ui/gfx/geometry/point.h"
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
index 3532ff0..51a3214 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
@@ -11,6 +11,7 @@
 #include <memory>
 #include <vector>
 
+#include <optional>
 #include "base/containers/circular_deque.h"
 #include "base/containers/flat_map.h"
 #include "base/containers/flat_set.h"
@@ -31,7 +32,6 @@
 #include "gpu/command_buffer/service/shared_context_state.h"
 #include "gpu/command_buffer/service/shared_image/shared_image_representation.h"
 #include "gpu/command_buffer/service/texture_manager.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_context.h"
 #include "ui/gl/gl_fence.h"
@@ -143,7 +143,7 @@
     std::unique_ptr<GLTexturePassthroughImageRepresentation> representation_;
     std::unique_ptr<GLTexturePassthroughImageRepresentation::ScopedAccess>
         scoped_access_;
-    absl::optional<GLenum> access_mode_;
+    std::optional<GLenum> access_mode_;
   };
   // Mapping of client texture IDs to GLTexturePassthroughImageRepresentations.
   // TODO(ericrk): Remove this once TexturePassthrough holds a reference to
diff --git a/gpu/command_buffer/service/gles2_external_framebuffer.cc b/gpu/command_buffer/service/gles2_external_framebuffer.cc
index 063e8f6c..bef7411 100644
--- a/gpu/command_buffer/service/gles2_external_framebuffer.cc
+++ b/gpu/command_buffer/service/gles2_external_framebuffer.cc
@@ -428,7 +428,7 @@
   if (clear_flags) {
     gl::ScopedCapability scoped_scissor(GL_SCISSOR_TEST, GL_FALSE);
 
-    absl::optional<ScopedRestoreWindowRectangles> window_rectangles_restore;
+    std::optional<ScopedRestoreWindowRectangles> window_rectangles_restore;
     if (supports_window_rectangles_) {
       window_rectangles_restore.emplace(api);
       api->glWindowRectanglesEXTFn(GL_EXCLUSIVE_EXT, 0, nullptr);
@@ -513,7 +513,7 @@
       ScopedRestoreWriteMasks write_mask_restore(api);
       api->glColorMaskFn(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
 
-      absl::optional<ScopedRestoreWindowRectangles> window_rectangles_restore;
+      std::optional<ScopedRestoreWindowRectangles> window_rectangles_restore;
       if (supports_window_rectangles_) {
         window_rectangles_restore.emplace(api);
         api->glWindowRectanglesEXTFn(GL_EXCLUSIVE_EXT, 0, nullptr);
diff --git a/gpu/command_buffer/service/gr_cache_controller.cc b/gpu/command_buffer/service/gr_cache_controller.cc
index e45da1ae..cab1a1d 100644
--- a/gpu/command_buffer/service/gr_cache_controller.cc
+++ b/gpu/command_buffer/service/gr_cache_controller.cc
@@ -106,7 +106,7 @@
   // Force Skia to check fences to determine what can be freed.
   context_state_->gr_context()->checkAsyncWorkCompletion();
   {
-    absl::optional<gpu::raster::GrShaderCache::ScopedCacheUse> cache_use;
+    std::optional<gpu::raster::GrShaderCache::ScopedCacheUse> cache_use;
     // ScopedCacheUse is to avoid the empty/invalid client id DCHECKS caused
     // while accessing GrShaderCache. Note that since the actual client_id here
     // does not matter, we are using gpu::kDisplayCompositorClientId.
diff --git a/gpu/command_buffer/service/image_reader_gl_owner.h b/gpu/command_buffer/service/image_reader_gl_owner.h
index 0c20c3c6..9d87325 100644
--- a/gpu/command_buffer/service/image_reader_gl_owner.h
+++ b/gpu/command_buffer/service/image_reader_gl_owner.h
@@ -120,7 +120,7 @@
 
   // Most recently acquired image using image reader. This works like a cached
   // image until next new image is acquired which overwrites this.
-  absl::optional<ScopedCurrentImageRef> current_image_ref_ GUARDED_BY(lock_);
+  std::optional<ScopedCurrentImageRef> current_image_ref_ GUARDED_BY(lock_);
   std::unique_ptr<AImageReader_ImageListener> listener_;
 
   // A map consisting of pending refs on an AImage. If an image has any refs, it
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc
index 011e435..e81aa8a5 100644
--- a/gpu/command_buffer/service/raster_decoder.cc
+++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -364,7 +364,7 @@
   }
 
   const scoped_refptr<SharedContextState> shared_context_state_;
-  absl::optional<base::TimeTicks> begin_time_;
+  std::optional<base::TimeTicks> begin_time_;
   bool finished_ = false;
   base::WeakPtrFactory<RasterCommandsCompletedQuery> weak_ptr_factory_{this};
 };
@@ -3018,7 +3018,7 @@
 
   SkColor4f sk_color_4f = {r, g, b, a};
   if (shared_image_raster_) {
-    absl::optional<SkColor4f> clear_color;
+    std::optional<SkColor4f> clear_color;
     if (needs_clear)
       clear_color.emplace(sk_color_4f);
     scoped_shared_image_raster_write_ =
diff --git a/gpu/command_buffer/service/service_transfer_cache.cc b/gpu/command_buffer/service/service_transfer_cache.cc
index d70f20b..737dc31c 100644
--- a/gpu/command_buffer/service/service_transfer_cache.cc
+++ b/gpu/command_buffer/service/service_transfer_cache.cc
@@ -127,7 +127,7 @@
 }  // namespace
 
 ServiceTransferCache::CacheEntryInternal::CacheEntryInternal(
-    absl::optional<ServiceDiscardableHandle> handle,
+    std::optional<ServiceDiscardableHandle> handle,
     std::unique_ptr<cc::ServiceTransferCacheEntry> entry)
     : handle(handle), entry(std::move(entry)) {}
 
@@ -212,7 +212,7 @@
     total_image_size_ += entry->CachedSize();
   }
 
-  entries_.Put(key, CacheEntryInternal(absl::nullopt, std::move(entry)));
+  entries_.Put(key, CacheEntryInternal(std::nullopt, std::move(entry)));
   EnforceLimits();
 }
 
diff --git a/gpu/command_buffer/service/service_transfer_cache.h b/gpu/command_buffer/service/service_transfer_cache.h
index f185630..19159e48 100644
--- a/gpu/command_buffer/service/service_transfer_cache.h
+++ b/gpu/command_buffer/service/service_transfer_cache.h
@@ -108,12 +108,12 @@
 
  private:
   struct CacheEntryInternal {
-    CacheEntryInternal(absl::optional<ServiceDiscardableHandle> handle,
+    CacheEntryInternal(std::optional<ServiceDiscardableHandle> handle,
                        std::unique_ptr<cc::ServiceTransferCacheEntry> entry);
     CacheEntryInternal(CacheEntryInternal&& other);
     CacheEntryInternal& operator=(CacheEntryInternal&& other);
     ~CacheEntryInternal();
-    absl::optional<ServiceDiscardableHandle> handle;
+    std::optional<ServiceDiscardableHandle> handle;
     std::unique_ptr<cc::ServiceTransferCacheEntry> entry;
 
     // For metrics.
diff --git a/gpu/command_buffer/service/shared_context_state.cc b/gpu/command_buffer/service/shared_context_state.cc
index 338769f..758863b 100644
--- a/gpu/command_buffer/service/shared_context_state.cc
+++ b/gpu/command_buffer/service/shared_context_state.cc
@@ -703,7 +703,7 @@
       base::trace_event::MemoryDumpLevelOfDetail::kBackground) {
     raster::DumpBackgroundGrMemoryStatistics(gr_context_, pmd);
   } else {
-    raster::DumpGrMemoryStatistics(gr_context_, pmd, absl::nullopt);
+    raster::DumpGrMemoryStatistics(gr_context_, pmd, std::nullopt);
   }
 
   return true;
@@ -743,7 +743,7 @@
       // With critical pressure, purge as much as possible.
       sk_surface_cache_.Clear();
       {
-        absl::optional<raster::GrShaderCache::ScopedCacheUse> cache_use;
+        std::optional<raster::GrShaderCache::ScopedCacheUse> cache_use;
         // ScopedCacheUse is to avoid the empty/invalid client id DCHECKS caused
         // while accessing GrShaderCache. Note that since the actual client_id
         // here does not matter, we are using gpu::kDisplayCompositorClientId.
@@ -804,7 +804,7 @@
 }
 
 void SharedContextState::UseShaderCache(
-    absl::optional<gpu::raster::GrShaderCache::ScopedCacheUse>& cache_use,
+    std::optional<gpu::raster::GrShaderCache::ScopedCacheUse>& cache_use,
     int32_t client_id) const {
   if (gr_shader_cache_) {
     cache_use.emplace(gr_shader_cache_, client_id);
@@ -902,7 +902,7 @@
   return nullptr;
 }
 
-absl::optional<error::ContextLostReason> SharedContextState::GetResetStatus(
+std::optional<error::ContextLostReason> SharedContextState::GetResetStatus(
     bool needs_gl) {
   DCHECK(!context_lost());
 
@@ -928,11 +928,11 @@
 
   // Not using GL.
   if (!GrContextIsGL() && !needs_gl)
-    return absl::nullopt;
+    return std::nullopt;
 
   // GL is not initialized.
   if (!context_state_)
-    return absl::nullopt;
+    return std::nullopt;
 
   GLenum error;
   while ((error = context_state_->api()->glGetErrorFn()) != GL_NO_ERROR) {
@@ -949,13 +949,13 @@
   base::Time now = base::Time::Now();
   if (!disable_check_reset_status_throttling_for_test_ &&
       now < last_gl_check_graphics_reset_status_ + kMinCheckDelay) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   last_gl_check_graphics_reset_status_ = now;
 
   GLenum driver_status = context()->CheckStickyGraphicsResetStatus();
   if (driver_status == GL_NO_ERROR)
-    return absl::nullopt;
+    return std::nullopt;
   LOG(ERROR) << "SharedContextState context lost via ARB/EXT_robustness. Reset "
                 "status = "
              << gles2::GLES2Util::GetStringEnum(driver_status);
@@ -971,7 +971,7 @@
       NOTREACHED();
       break;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool SharedContextState::CheckResetStatus(bool need_gl) {
diff --git a/gpu/command_buffer/service/shared_context_state.h b/gpu/command_buffer/service/shared_context_state.h
index 7c21a810..680d2bd 100644
--- a/gpu/command_buffer/service/shared_context_state.h
+++ b/gpu/command_buffer/service/shared_context_state.h
@@ -8,6 +8,7 @@
 #include <memory>
 #include <vector>
 
+#include <optional>
 #include "base/containers/lru_cache.h"
 #include "base/memory/memory_pressure_listener.h"
 #include "base/memory/raw_ptr.h"
@@ -30,7 +31,6 @@
 #include "gpu/ipc/common/gpu_peak_memory.h"
 #include "gpu/vulkan/buildflags.h"
 #include "skia/buildflags.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkSurface.h"
 #include "third_party/skia/include/gpu/GrDirectContext.h"
 #include "ui/gl/progress_reporter.h"
@@ -137,7 +137,7 @@
   void StoreVkPipelineCacheIfNeeded();
 
   void UseShaderCache(
-      absl::optional<gpu::raster::GrShaderCache::ScopedCacheUse>& cache_use,
+      std::optional<gpu::raster::GrShaderCache::ScopedCacheUse>& cache_use,
       int32_t client_id) const;
 
   gl::GLShareGroup* share_group() const { return share_group_.get(); }
@@ -175,7 +175,7 @@
   gles2::FeatureInfo* feature_info() { return feature_info_.get(); }
   gles2::ContextState* context_state() const { return context_state_.get(); }
   bool context_lost() const { return !!context_lost_reason_; }
-  absl::optional<error::ContextLostReason> context_lost_reason() {
+  std::optional<error::ContextLostReason> context_lost_reason() {
     return context_lost_reason_;
   }
   bool need_context_state_reset() const { return need_context_state_reset_; }
@@ -330,7 +330,7 @@
   bool InitializeGraphite(const GpuPreferences& gpu_preferences,
                           const GpuDriverBugWorkarounds& workarounds);
 
-  absl::optional<error::ContextLostReason> GetResetStatus(bool needs_gl);
+  std::optional<error::ContextLostReason> GetResetStatus(bool needs_gl);
 
   // gpu::GLContextVirtualDelegate implementation.
   bool initialized() const override;
@@ -399,7 +399,7 @@
   // driver's GL state.
   bool need_context_state_reset_ = false;
 
-  absl::optional<error::ContextLostReason> context_lost_reason_;
+  std::optional<error::ContextLostReason> context_lost_reason_;
   base::ObserverList<ContextLostObserver>::Unchecked context_lost_observers_;
 
   base::LRUCache<void*, sk_sp<SkSurface>> sk_surface_cache_;
diff --git a/gpu/command_buffer/service/shared_image/android_video_image_backing.cc b/gpu/command_buffer/service/shared_image/android_video_image_backing.cc
index 830e1e8..a0ca401 100644
--- a/gpu/command_buffer/service/shared_image/android_video_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/android_video_image_backing.cc
@@ -67,16 +67,16 @@
 }
 
 // Static.
-absl::optional<VulkanYCbCrInfo> AndroidVideoImageBacking::GetYcbcrInfo(
+std::optional<VulkanYCbCrInfo> AndroidVideoImageBacking::GetYcbcrInfo(
     TextureOwner* texture_owner,
     viz::VulkanContextProvider* vulkan_context_provider) {
   if (!vulkan_context_provider)
-    return absl::nullopt;
+    return std::nullopt;
 
   // Get AHardwareBuffer from the latest frame.
   auto scoped_hardware_buffer = texture_owner->GetAHardwareBuffer();
   if (!scoped_hardware_buffer)
-    return absl::nullopt;
+    return std::nullopt;
 
   DCHECK(scoped_hardware_buffer->buffer());
   VulkanImplementation* vk_implementation =
@@ -88,9 +88,9 @@
   if (!vk_implementation->GetSamplerYcbcrConversionInfo(
           vk_device, scoped_hardware_buffer->TakeBuffer(), &ycbcr_info)) {
     LOG(ERROR) << "Failed to get the ycbcr info.";
-    return absl::nullopt;
+    return std::nullopt;
   }
-  return absl::optional<VulkanYCbCrInfo>(ycbcr_info);
+  return std::optional<VulkanYCbCrInfo>(ycbcr_info);
 }
 
 std::unique_ptr<AbstractTextureAndroid>
diff --git a/gpu/command_buffer/service/shared_image/android_video_image_backing.h b/gpu/command_buffer/service/shared_image/android_video_image_backing.h
index a27bde0..091cd66d 100644
--- a/gpu/command_buffer/service/shared_image/android_video_image_backing.h
+++ b/gpu/command_buffer/service/shared_image/android_video_image_backing.h
@@ -7,10 +7,10 @@
 
 #include <memory>
 
+#include <optional>
 #include "gpu/command_buffer/service/shared_image/android_image_backing.h"
 #include "gpu/gpu_gles2_export.h"
 #include "gpu/ipc/common/vulkan_ycbcr_info.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace viz {
 class VulkanContextProvider;
@@ -41,7 +41,7 @@
 
   // Returns ycbcr information. This is only valid in vulkan context and
   // nullopt for other context.
-  static absl::optional<VulkanYCbCrInfo> GetYcbcrInfo(
+  static std::optional<VulkanYCbCrInfo> GetYcbcrInfo(
       TextureOwner* texture_owner,
       viz::VulkanContextProvider* vulkan_context_provider);
 
diff --git a/gpu/command_buffer/service/shared_image/compound_image_backing.cc b/gpu/command_buffer/service/shared_image/compound_image_backing.cc
index 87ba17c..92ccf5b9 100644
--- a/gpu/command_buffer/service/shared_image/compound_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/compound_image_backing.cc
@@ -329,7 +329,7 @@
     return wrapped_->EndReadAccess(std::move(release_fence));
   }
 #if BUILDFLAG(IS_WIN)
-  absl::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage() final {
+  std::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage() final {
     return wrapped_->GetDCLayerOverlayImage();
   }
 #endif
@@ -495,7 +495,7 @@
     bool allow_shm_overlays,
     std::unique_ptr<SharedMemoryImageBacking> shm_backing,
     base::WeakPtr<SharedImageBackingFactory> gpu_backing_factory,
-    absl::optional<gfx::BufferUsage> buffer_usage)
+    std::optional<gfx::BufferUsage> buffer_usage)
     : SharedImageBacking(mailbox,
                          format,
                          size,
diff --git a/gpu/command_buffer/service/shared_image/compound_image_backing.h b/gpu/command_buffer/service/shared_image/compound_image_backing.h
index aba24e5..34ae8ff 100644
--- a/gpu/command_buffer/service/shared_image/compound_image_backing.h
+++ b/gpu/command_buffer/service/shared_image/compound_image_backing.h
@@ -185,7 +185,7 @@
       bool allow_shm_overlays,
       std::unique_ptr<SharedMemoryImageBacking> shm_backing,
       base::WeakPtr<SharedImageBackingFactory> gpu_backing_factory,
-      absl::optional<gfx::BufferUsage> buffer_usage = absl::nullopt);
+      std::optional<gfx::BufferUsage> buffer_usage = std::nullopt);
 
   base::trace_event::MemoryAllocatorDump* OnMemoryDump(
       const std::string& dump_name,
diff --git a/gpu/command_buffer/service/shared_image/compound_image_backing_unittest.cc b/gpu/command_buffer/service/shared_image/compound_image_backing_unittest.cc
index 2d30e88b..6c56db4 100644
--- a/gpu/command_buffer/service/shared_image/compound_image_backing_unittest.cc
+++ b/gpu/command_buffer/service/shared_image/compound_image_backing_unittest.cc
@@ -353,7 +353,7 @@
   auto access = overlay_rep->BeginScopedReadAccess();
 
 #if BUILDFLAG(IS_WIN)
-  absl::optional<gl::DCLayerOverlayImage> overlay_image =
+  std::optional<gl::DCLayerOverlayImage> overlay_image =
       access->GetDCLayerOverlayImage();
   ASSERT_TRUE(overlay_image);
   EXPECT_EQ(overlay_image->type(), gl::DCLayerOverlayType::kNV12Pixmap);
diff --git a/gpu/command_buffer/service/shared_image/d3d_image_backing.cc b/gpu/command_buffer/service/shared_image/d3d_image_backing.cc
index bbfb04de..27ca2ea 100644
--- a/gpu/command_buffer/service/shared_image/d3d_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/d3d_image_backing.cc
@@ -1054,13 +1054,13 @@
                                                          texture_d3d11_device_);
 }
 
-absl::optional<gl::DCLayerOverlayImage>
+std::optional<gl::DCLayerOverlayImage>
 D3DImageBacking::GetDCLayerOverlayImage() {
   if (swap_chain_) {
-    return absl::make_optional<gl::DCLayerOverlayImage>(size(), swap_chain_);
+    return std::make_optional<gl::DCLayerOverlayImage>(size(), swap_chain_);
   }
-  return absl::make_optional<gl::DCLayerOverlayImage>(size(), d3d11_texture_,
-                                                      array_slice_);
+  return std::make_optional<gl::DCLayerOverlayImage>(size(), d3d11_texture_,
+                                                     array_slice_);
 }
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image/d3d_image_backing.h b/gpu/command_buffer/service/shared_image/d3d_image_backing.h
index 0ee2117..7503bda 100644
--- a/gpu/command_buffer/service/shared_image/d3d_image_backing.h
+++ b/gpu/command_buffer/service/shared_image/d3d_image_backing.h
@@ -117,7 +117,7 @@
   void EndAccessDawn(const wgpu::Device& device, wgpu::Texture texture);
 #endif
 
-  absl::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage();
+  std::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage();
 
   bool has_keyed_mutex() const {
     return dxgi_shared_handle_state_ &&
diff --git a/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.h b/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.h
index 12eacf2e..ef7bef3 100644
--- a/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.h
+++ b/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.h
@@ -12,9 +12,9 @@
 
 #include <memory>
 
+#include <optional>
 #include "gpu/command_buffer/service/shared_image/shared_image_backing_factory.h"
 #include "gpu/gpu_gles2_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkColor.h"
 
 namespace gfx {
@@ -153,8 +153,8 @@
   // D3D11 device used for creating textures. This is also Skia's D3D11 device.
   // Can be different from |angle_d3d11_device_| when using Graphite.
   Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device_;
-  absl::optional<bool> map_on_default_textures_;
-  absl::optional<bool> supports_bgra8unorm_storage_;
+  std::optional<bool> map_on_default_textures_;
+  std::optional<bool> supports_bgra8unorm_storage_;
 
   scoped_refptr<DXGISharedHandleManager> dxgi_shared_handle_manager_;
 
diff --git a/gpu/command_buffer/service/shared_image/d3d_image_backing_factory_unittest.cc b/gpu/command_buffer/service/shared_image/d3d_image_backing_factory_unittest.cc
index 77a21e2..bf7cf01b 100644
--- a/gpu/command_buffer/service/shared_image/d3d_image_backing_factory_unittest.cc
+++ b/gpu/command_buffer/service/shared_image/d3d_image_backing_factory_unittest.cc
@@ -1902,7 +1902,7 @@
   auto scoped_read_access = overlay_representation->BeginScopedReadAccess();
   ASSERT_TRUE(scoped_read_access);
 
-  absl::optional<gl::DCLayerOverlayImage> overlay_image =
+  std::optional<gl::DCLayerOverlayImage> overlay_image =
       scoped_read_access->GetDCLayerOverlayImage();
   ASSERT_TRUE(overlay_image);
   EXPECT_EQ(overlay_image->type(), gl::DCLayerOverlayType::kNV12Texture);
@@ -2122,7 +2122,7 @@
     auto scoped_read_access = overlay_representation->BeginScopedReadAccess();
     ASSERT_TRUE(scoped_read_access);
 
-    absl::optional<gl::DCLayerOverlayImage> overlay_image =
+    std::optional<gl::DCLayerOverlayImage> overlay_image =
         scoped_read_access->GetDCLayerOverlayImage();
     ASSERT_TRUE(overlay_image);
     EXPECT_EQ(overlay_image->type(), gl::DCLayerOverlayType::kNV12Pixmap);
diff --git a/gpu/command_buffer/service/shared_image/d3d_image_representation.cc b/gpu/command_buffer/service/shared_image/d3d_image_representation.cc
index a58044f1..66751d3 100644
--- a/gpu/command_buffer/service/shared_image/d3d_image_representation.cc
+++ b/gpu/command_buffer/service/shared_image/d3d_image_representation.cc
@@ -126,7 +126,7 @@
   static_cast<D3DImageBacking*>(backing())->EndAccessD3D11(d3d11_device_);
 }
 
-absl::optional<gl::DCLayerOverlayImage>
+std::optional<gl::DCLayerOverlayImage>
 OverlayD3DImageRepresentation::GetDCLayerOverlayImage() {
   return static_cast<D3DImageBacking*>(backing())->GetDCLayerOverlayImage();
 }
diff --git a/gpu/command_buffer/service/shared_image/d3d_image_representation.h b/gpu/command_buffer/service/shared_image/d3d_image_representation.h
index 11377814d..ee570a8 100644
--- a/gpu/command_buffer/service/shared_image/d3d_image_representation.h
+++ b/gpu/command_buffer/service/shared_image/d3d_image_representation.h
@@ -82,7 +82,7 @@
   bool BeginReadAccess(gfx::GpuFenceHandle& acquire_fence) override;
   void EndReadAccess(gfx::GpuFenceHandle release_fence) override;
 
-  absl::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage() override;
+  std::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage() override;
 
   Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device_;
 };
diff --git a/gpu/command_buffer/service/shared_image/dawn_fallback_image_representation.cc b/gpu/command_buffer/service/shared_image/dawn_fallback_image_representation.cc
index fc126b9..91b19ae 100644
--- a/gpu/command_buffer/service/shared_image/dawn_fallback_image_representation.cc
+++ b/gpu/command_buffer/service/shared_image/dawn_fallback_image_representation.cc
@@ -39,9 +39,8 @@
 
   const viz::SharedImageFormat format = this->format();
 
-  absl::optional<size_t> min_bytes_per_row(
-      format.MaybeEstimatedPlaneSizeInBytes(plane_index,
-                                            gfx::Size(size().width(), 1)));
+  std::optional<size_t> min_bytes_per_row(format.MaybeEstimatedPlaneSizeInBytes(
+      plane_index, gfx::Size(size().width(), 1)));
 
   if (!min_bytes_per_row.has_value()) {
     return false;
diff --git a/gpu/command_buffer/service/shared_image/dcomp_image_backing_factory_unittest.cc b/gpu/command_buffer/service/shared_image/dcomp_image_backing_factory_unittest.cc
index d097a14b..2761dee 100644
--- a/gpu/command_buffer/service/shared_image/dcomp_image_backing_factory_unittest.cc
+++ b/gpu/command_buffer/service/shared_image/dcomp_image_backing_factory_unittest.cc
@@ -672,7 +672,7 @@
   };
 
   gfx::Size window_size_;
-  absl::optional<SkColor4f> background_fill_override_;
+  std::optional<SkColor4f> background_fill_override_;
 
   TestPlatformDelegate platform_delegate_;
   ui::WinWindow window_;
diff --git a/gpu/command_buffer/service/shared_image/dcomp_surface_image_backing.h b/gpu/command_buffer/service/shared_image/dcomp_surface_image_backing.h
index 7763fd8..c90be4b0 100644
--- a/gpu/command_buffer/service/shared_image/dcomp_surface_image_backing.h
+++ b/gpu/command_buffer/service/shared_image/dcomp_surface_image_backing.h
@@ -88,9 +88,9 @@
 
   // For DCompSurfaceOverlayImageRepresentation implementation.
   friend class DCompSurfaceOverlayImageRepresentation;
-  absl::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage() {
-    return absl::make_optional<gl::DCLayerOverlayImage>(size(), dcomp_surface_,
-                                                        dcomp_surface_serial_);
+  std::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage() {
+    return std::make_optional<gl::DCLayerOverlayImage>(size(), dcomp_surface_,
+                                                       dcomp_surface_serial_);
   }
 
   Microsoft::WRL::ComPtr<ID3D11Texture2D> BeginDraw(
@@ -114,7 +114,7 @@
   void EndDrawDawn(const wgpu::Device& device, wgpu::Texture texture);
 
   // Used to restore the surface that was current before BeginDraw at EndDraw.
-  absl::optional<ui::ScopedMakeCurrent> scoped_make_current_;
+  std::optional<ui::ScopedMakeCurrent> scoped_make_current_;
 
   // GLSurface that binds |dcomp_surface_|'s draw texture to GL FB0 between
   // |BeginDrawGanesh| and |EndDrawGanesh|.
diff --git a/gpu/command_buffer/service/shared_image/dcomp_surface_image_representation.cc b/gpu/command_buffer/service/shared_image/dcomp_surface_image_representation.cc
index fc28e4a8..a9b2007a 100644
--- a/gpu/command_buffer/service/shared_image/dcomp_surface_image_representation.cc
+++ b/gpu/command_buffer/service/shared_image/dcomp_surface_image_representation.cc
@@ -27,7 +27,7 @@
 DCompSurfaceOverlayImageRepresentation::
     ~DCompSurfaceOverlayImageRepresentation() = default;
 
-absl::optional<gl::DCLayerOverlayImage>
+std::optional<gl::DCLayerOverlayImage>
 DCompSurfaceOverlayImageRepresentation::GetDCLayerOverlayImage() {
   return static_cast<DCompSurfaceImageBacking*>(backing())
       ->GetDCLayerOverlayImage();
diff --git a/gpu/command_buffer/service/shared_image/dcomp_surface_image_representation.h b/gpu/command_buffer/service/shared_image/dcomp_surface_image_representation.h
index ce17310d..e5876cf 100644
--- a/gpu/command_buffer/service/shared_image/dcomp_surface_image_representation.h
+++ b/gpu/command_buffer/service/shared_image/dcomp_surface_image_representation.h
@@ -19,7 +19,7 @@
   ~DCompSurfaceOverlayImageRepresentation() override;
 
  protected:
-  absl::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage() override;
+  std::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage() override;
 
  private:
   bool BeginReadAccess(gfx::GpuFenceHandle& acquire_fence) override;
diff --git a/gpu/command_buffer/service/shared_image/dxgi_swap_chain_image_backing.cc b/gpu/command_buffer/service/shared_image/dxgi_swap_chain_image_backing.cc
index b25c575..1a456fe 100644
--- a/gpu/command_buffer/service/shared_image/dxgi_swap_chain_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/dxgi_swap_chain_image_backing.cc
@@ -197,7 +197,7 @@
 
   gfx::Rect pending_swap_rect = swap_rect;
 
-  absl::optional<SkColor4f> initialize_color;
+  std::optional<SkColor4f> initialize_color;
 
   // SharedImage allows an incomplete first draw so long as we only read from
   // the part that we've previously drawn to. However, IDXGISwapChain requires a
diff --git a/gpu/command_buffer/service/shared_image/dxgi_swap_chain_image_backing.h b/gpu/command_buffer/service/shared_image/dxgi_swap_chain_image_backing.h
index 26de401..41c10c8 100644
--- a/gpu/command_buffer/service/shared_image/dxgi_swap_chain_image_backing.h
+++ b/gpu/command_buffer/service/shared_image/dxgi_swap_chain_image_backing.h
@@ -84,9 +84,9 @@
 
   friend class DXGISwapChainOverlayImageRepresentation;
   bool Present(bool should_synchronize_present_with_vblank);
-  absl::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage() {
-    return absl::make_optional<gl::DCLayerOverlayImage>(size(),
-                                                        dxgi_swap_chain_);
+  std::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage() {
+    return std::make_optional<gl::DCLayerOverlayImage>(size(),
+                                                       dxgi_swap_chain_);
   }
 
   friend class SkiaGLImageRepresentationDXGISwapChain;
@@ -99,7 +99,7 @@
                                 const gfx::Rect& update_rect);
   void EndAccessDawn(const wgpu::Device& device, wgpu::Texture texture);
 
-  absl::optional<gfx::Rect> pending_swap_rect_;
+  std::optional<gfx::Rect> pending_swap_rect_;
 
   Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device_;
   Microsoft::WRL::ComPtr<IDXGISwapChain1> dxgi_swap_chain_;
diff --git a/gpu/command_buffer/service/shared_image/dxgi_swap_chain_image_representation.cc b/gpu/command_buffer/service/shared_image/dxgi_swap_chain_image_representation.cc
index 47956aa2..1086001 100644
--- a/gpu/command_buffer/service/shared_image/dxgi_swap_chain_image_representation.cc
+++ b/gpu/command_buffer/service/shared_image/dxgi_swap_chain_image_representation.cc
@@ -29,7 +29,7 @@
 DXGISwapChainOverlayImageRepresentation::
     ~DXGISwapChainOverlayImageRepresentation() = default;
 
-absl::optional<gl::DCLayerOverlayImage>
+std::optional<gl::DCLayerOverlayImage>
 DXGISwapChainOverlayImageRepresentation::GetDCLayerOverlayImage() {
   return static_cast<DXGISwapChainImageBacking*>(backing())
       ->GetDCLayerOverlayImage();
diff --git a/gpu/command_buffer/service/shared_image/dxgi_swap_chain_image_representation.h b/gpu/command_buffer/service/shared_image/dxgi_swap_chain_image_representation.h
index 94617ce..6327209d 100644
--- a/gpu/command_buffer/service/shared_image/dxgi_swap_chain_image_representation.h
+++ b/gpu/command_buffer/service/shared_image/dxgi_swap_chain_image_representation.h
@@ -24,7 +24,7 @@
   ~DXGISwapChainOverlayImageRepresentation() override;
 
  protected:
-  absl::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage() override;
+  std::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage() override;
 
  private:
   bool BeginReadAccess(gfx::GpuFenceHandle& acquire_fence) override;
diff --git a/gpu/command_buffer/service/shared_image/egl_image_backing_factory_unittest.cc b/gpu/command_buffer/service/shared_image/egl_image_backing_factory_unittest.cc
index 7879b67..a8f2ea5 100644
--- a/gpu/command_buffer/service/shared_image/egl_image_backing_factory_unittest.cc
+++ b/gpu/command_buffer/service/shared_image/egl_image_backing_factory_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <thread>
 
+#include <optional>
 #include "base/bits.h"
 #include "base/functional/callback_helpers.h"
 #include "base/memory/raw_ptr.h"
@@ -32,7 +33,6 @@
 #include "gpu/config/gpu_test_config.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkImage.h"
 #include "third_party/skia/include/gpu/GrBackendSemaphore.h"
 #include "third_party/skia/include/gpu/GrBackendSurface.h"
diff --git a/gpu/command_buffer/service/shared_image/external_vk_image_backing.cc b/gpu/command_buffer/service/shared_image/external_vk_image_backing.cc
index 89ee0d3..9447f31 100644
--- a/gpu/command_buffer/service/shared_image/external_vk_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/external_vk_image_backing.cc
@@ -267,7 +267,7 @@
     GrSurfaceOrigin surface_origin,
     SkAlphaType alpha_type,
     uint32_t usage,
-    absl::optional<gfx::BufferUsage> buffer_usage) {
+    std::optional<gfx::BufferUsage> buffer_usage) {
   if (!gpu::IsImageSizeValidForGpuMemoryBufferFormat(size,
                                                      ToBufferFormat(format))) {
     DLOG(ERROR) << "Invalid image size for format.";
@@ -368,7 +368,7 @@
     VulkanCommandPool* command_pool,
     bool use_separate_gl_texture,
     gfx::GpuMemoryBufferHandle handle,
-    absl::optional<gfx::BufferUsage> buffer_usage)
+    std::optional<gfx::BufferUsage> buffer_usage)
     : ClearTrackingSharedImageBacking(mailbox,
                                       format,
                                       size,
@@ -754,7 +754,7 @@
   auto& gl_texture = gl_textures_.emplace_back(plane_format, plane_size,
                                                is_passthrough, nullptr);
 
-  absl::optional<ScopedDedicatedMemoryObject> memory_object;
+  std::optional<ScopedDedicatedMemoryObject> memory_object;
   if (!use_separate_gl_texture()) {
     GrVkImageInfo image_info = vk_texture.GetGrVkImageInfo();
 
diff --git a/gpu/command_buffer/service/shared_image/external_vk_image_backing.h b/gpu/command_buffer/service/shared_image/external_vk_image_backing.h
index 549fb86..a282356 100644
--- a/gpu/command_buffer/service/shared_image/external_vk_image_backing.h
+++ b/gpu/command_buffer/service/shared_image/external_vk_image_backing.h
@@ -58,7 +58,7 @@
       GrSurfaceOrigin surface_origin,
       SkAlphaType alpha_type,
       uint32_t usage,
-      absl::optional<gfx::BufferUsage> buffer_usage = absl::nullopt);
+      std::optional<gfx::BufferUsage> buffer_usage = std::nullopt);
 
   static std::unique_ptr<ExternalVkImageBacking> CreateWithPixmap(
       scoped_refptr<SharedContextState> context_state,
@@ -88,7 +88,7 @@
       VulkanCommandPool* command_pool,
       bool use_separate_gl_texture,
       gfx::GpuMemoryBufferHandle handle = gfx::GpuMemoryBufferHandle(),
-      absl::optional<gfx::BufferUsage> buffer_usage = absl::nullopt);
+      std::optional<gfx::BufferUsage> buffer_usage = std::nullopt);
 
   ExternalVkImageBacking(const ExternalVkImageBacking&) = delete;
   ExternalVkImageBacking& operator=(const ExternalVkImageBacking&) = delete;
diff --git a/gpu/command_buffer/service/shared_image/iosurface_image_backing.h b/gpu/command_buffer/service/shared_image/iosurface_image_backing.h
index 466b769..419a6e38 100644
--- a/gpu/command_buffer/service/shared_image/iosurface_image_backing.h
+++ b/gpu/command_buffer/service/shared_image/iosurface_image_backing.h
@@ -252,7 +252,7 @@
       bool framebuffer_attachment_angle,
       bool is_cleared,
       bool retain_gl_texture,
-      absl::optional<gfx::BufferUsage> buffer_usage = absl::nullopt);
+      std::optional<gfx::BufferUsage> buffer_usage = std::nullopt);
   IOSurfaceImageBacking(const IOSurfaceImageBacking& other) = delete;
   IOSurfaceImageBacking& operator=(const IOSurfaceImageBacking& other) = delete;
   ~IOSurfaceImageBacking() override;
diff --git a/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm b/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm
index e616904..c625ce3 100644
--- a/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm
+++ b/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm
@@ -721,7 +721,7 @@
     bool framebuffer_attachment_angle,
     bool is_cleared,
     bool retain_gl_texture,
-    absl::optional<gfx::BufferUsage> buffer_usage)
+    std::optional<gfx::BufferUsage> buffer_usage)
     : SharedImageBacking(mailbox,
                          format,
                          size,
diff --git a/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.h b/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.h
index 6575101..6ab0975 100644
--- a/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.h
+++ b/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.h
@@ -128,7 +128,7 @@
       uint32_t io_surface_plane,
       gfx::BufferPlane buffer_plane,
       bool is_plane_format,
-      absl::optional<gfx::BufferUsage> buffer_usage = absl::nullopt);
+      std::optional<gfx::BufferUsage> buffer_usage = std::nullopt);
 
   const GrContextType gr_context_type_;
   const int32_t max_texture_size_;
diff --git a/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.mm b/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.mm
index f07a34e0..0547883 100644
--- a/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.mm
+++ b/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.mm
@@ -4,6 +4,7 @@
 
 #include "gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.h"
 
+#include <optional>
 #include "base/memory/scoped_refptr.h"
 #include "build/build_config.h"
 #include "components/viz/common/resources/resource_sizes.h"
@@ -18,7 +19,6 @@
 #include "gpu/command_buffer/service/shared_image/shared_image_representation.h"
 #include "gpu/command_buffer/service/skia_utils.h"
 #include "gpu/command_buffer/service/texture_manager.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/buffer_format_util.h"
 #include "ui/gfx/gpu_memory_buffer.h"
 #include "ui/gfx/mac/io_surface.h"
@@ -413,7 +413,7 @@
     uint32_t io_surface_plane,
     gfx::BufferPlane buffer_plane,
     bool is_plane_format,
-    absl::optional<gfx::BufferUsage> buffer_usage) {
+    std::optional<gfx::BufferUsage> buffer_usage) {
   if (handle.type != gfx::IO_SURFACE_BUFFER || !handle.io_surface) {
     LOG(ERROR) << "Invalid IOSurface GpuMemoryBufferHandle.";
     return nullptr;
diff --git a/gpu/command_buffer/service/shared_image/ozone_image_backing.cc b/gpu/command_buffer/service/shared_image/ozone_image_backing.cc
index e82c9f5..e83a1d12 100644
--- a/gpu/command_buffer/service/shared_image/ozone_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/ozone_image_backing.cc
@@ -386,7 +386,7 @@
     scoped_refptr<gfx::NativePixmap> pixmap,
     const GpuDriverBugWorkarounds& workarounds,
     bool use_passthrough,
-    absl::optional<gfx::BufferUsage> buffer_usage)
+    std::optional<gfx::BufferUsage> buffer_usage)
     : ClearTrackingSharedImageBacking(mailbox,
                                       format,
                                       size,
diff --git a/gpu/command_buffer/service/shared_image/ozone_image_backing.h b/gpu/command_buffer/service/shared_image/ozone_image_backing.h
index 73b481b..32b4544 100644
--- a/gpu/command_buffer/service/shared_image/ozone_image_backing.h
+++ b/gpu/command_buffer/service/shared_image/ozone_image_backing.h
@@ -52,7 +52,7 @@
       scoped_refptr<gfx::NativePixmap> pixmap,
       const GpuDriverBugWorkarounds& workarounds,
       bool use_passthrough,
-      absl::optional<gfx::BufferUsage> buffer_usage = absl::nullopt);
+      std::optional<gfx::BufferUsage> buffer_usage = std::nullopt);
 
   OzoneImageBacking(const OzoneImageBacking&) = delete;
   OzoneImageBacking& operator=(const OzoneImageBacking&) = delete;
diff --git a/gpu/command_buffer/service/shared_image/ozone_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/ozone_image_backing_factory.cc
index 17f7b99a..9e611db3 100644
--- a/gpu/command_buffer/service/shared_image/ozone_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/ozone_image_backing_factory.cc
@@ -91,7 +91,7 @@
     GrSurfaceOrigin surface_origin,
     SkAlphaType alpha_type,
     uint32_t usage,
-    absl::optional<gfx::BufferUsage> buffer_usage) {
+    std::optional<gfx::BufferUsage> buffer_usage) {
   gfx::BufferFormat buffer_format = ToBufferFormat(format);
   VulkanDeviceQueue* device_queue = nullptr;
 #if BUILDFLAG(ENABLE_VULKAN)
diff --git a/gpu/command_buffer/service/shared_image/ozone_image_backing_factory.h b/gpu/command_buffer/service/shared_image/ozone_image_backing_factory.h
index cb2f8f0..48da266 100644
--- a/gpu/command_buffer/service/shared_image/ozone_image_backing_factory.h
+++ b/gpu/command_buffer/service/shared_image/ozone_image_backing_factory.h
@@ -5,6 +5,7 @@
 #ifndef GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_OZONE_IMAGE_BACKING_FACTORY_H_
 #define GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_OZONE_IMAGE_BACKING_FACTORY_H_
 
+#include <optional>
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_refptr.h"
@@ -13,7 +14,6 @@
 #include "gpu/config/gpu_driver_bug_workarounds.h"
 #include "gpu/config/gpu_preferences.h"
 #include "gpu/gpu_gles2_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace gpu {
 class SharedContextState;
@@ -119,7 +119,7 @@
       GrSurfaceOrigin surface_origin,
       SkAlphaType alpha_type,
       uint32_t usage,
-      absl::optional<gfx::BufferUsage> buffer_usage = absl::nullopt);
+      std::optional<gfx::BufferUsage> buffer_usage = std::nullopt);
 };
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image/raw_draw_image_backing.cc b/gpu/command_buffer/service/shared_image/raw_draw_image_backing.cc
index 6550806..ec7ec89 100644
--- a/gpu/command_buffer/service/shared_image/raw_draw_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/raw_draw_image_backing.cc
@@ -35,7 +35,7 @@
       scoped_refptr<SharedContextState> context_state,
       int final_msaa_count,
       const SkSurfaceProps& surface_props,
-      const absl::optional<SkColor4f>& clear_color,
+      const std::optional<SkColor4f>& clear_color,
       bool visible) override {
     return raw_draw_backing()->BeginRasterWriteAccess(
         std::move(context_state), final_msaa_count, surface_props, clear_color,
@@ -47,7 +47,7 @@
   }
 
   cc::PaintOpBuffer* BeginReadAccess(
-      absl::optional<SkColor4f>& clear_color) override {
+      std::optional<SkColor4f>& clear_color) override {
     return raw_draw_backing()->BeginRasterReadAccess(clear_color);
   }
 
@@ -252,7 +252,7 @@
     scoped_refptr<SharedContextState> context_state,
     int final_msaa_count,
     const SkSurfaceProps& surface_props,
-    const absl::optional<SkColor4f>& clear_color,
+    const std::optional<SkColor4f>& clear_color,
     bool visible) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   AutoLock auto_lock(this);
@@ -317,7 +317,7 @@
 }
 
 cc::PaintOpBuffer* RawDrawImageBacking::BeginRasterReadAccess(
-    absl::optional<SkColor4f>& clear_color) {
+    std::optional<SkColor4f>& clear_color) {
   // paint ops will be read on compositor thread, so do not check thread with
   // DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   AutoLock auto_lock(this);
diff --git a/gpu/command_buffer/service/shared_image/raw_draw_image_backing.h b/gpu/command_buffer/service/shared_image/raw_draw_image_backing.h
index 0196e70..25e1dda8 100644
--- a/gpu/command_buffer/service/shared_image/raw_draw_image_backing.h
+++ b/gpu/command_buffer/service/shared_image/raw_draw_image_backing.h
@@ -5,12 +5,12 @@
 #ifndef GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_RAW_DRAW_IMAGE_BACKING_H_
 #define GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_RAW_DRAW_IMAGE_BACKING_H_
 
+#include <optional>
 #include "base/functional/callback.h"
 #include "base/thread_annotations.h"
 #include "base/threading/thread_checker.h"
 #include "cc/paint/paint_op_buffer.h"
 #include "gpu/command_buffer/service/shared_image/shared_image_backing.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "third_party/skia/include/core/SkSurfaceProps.h"
 #include "third_party/skia/include/gpu/GrBackendSurface.h"
@@ -56,19 +56,19 @@
       scoped_refptr<SharedContextState> context_state,
       int final_msaa_count,
       const SkSurfaceProps& surface_props,
-      const absl::optional<SkColor4f>& clear_color,
+      const std::optional<SkColor4f>& clear_color,
       bool visible);
   void EndRasterWriteAccess(base::OnceClosure callback);
   cc::PaintOpBuffer* BeginRasterReadAccess(
-      absl::optional<SkColor4f>& clear_color);
+      std::optional<SkColor4f>& clear_color);
   sk_sp<GrPromiseImageTexture> BeginSkiaReadAccess();
   void EndReadAccess();
 
   int32_t final_msaa_count_ GUARDED_BY_CONTEXT(thread_checker_) = 0;
   SkSurfaceProps surface_props_ GUARDED_BY_CONTEXT(thread_checker_){};
-  absl::optional<SkColor4f> clear_color_ GUARDED_BY(lock_);
+  std::optional<SkColor4f> clear_color_ GUARDED_BY(lock_);
   bool visible_ GUARDED_BY(lock_) = false;
-  absl::optional<cc::PaintOpBuffer> paint_op_buffer_ GUARDED_BY(lock_);
+  std::optional<cc::PaintOpBuffer> paint_op_buffer_ GUARDED_BY(lock_);
   base::OnceClosure paint_op_release_callback_
       GUARDED_BY_CONTEXT(thread_checker_);
   scoped_refptr<SharedContextState> context_state_
diff --git a/gpu/command_buffer/service/shared_image/shared_image_backing.cc b/gpu/command_buffer/service/shared_image/shared_image_backing.cc
index acc664a..bb24504 100644
--- a/gpu/command_buffer/service/shared_image/shared_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/shared_image_backing.cc
@@ -79,7 +79,7 @@
     uint32_t usage,
     size_t estimated_size,
     bool is_thread_safe,
-    absl::optional<gfx::BufferUsage> buffer_usage)
+    std::optional<gfx::BufferUsage> buffer_usage)
     : mailbox_(mailbox),
       format_(format),
       size_(size),
@@ -395,7 +395,7 @@
     uint32_t usage,
     size_t estimated_size,
     bool is_thread_safe,
-    absl::optional<gfx::BufferUsage> buffer_usage)
+    std::optional<gfx::BufferUsage> buffer_usage)
     : SharedImageBacking(mailbox,
                          format,
                          size,
diff --git a/gpu/command_buffer/service/shared_image/shared_image_backing.h b/gpu/command_buffer/service/shared_image/shared_image_backing.h
index cd31d5e..5c89c5c 100644
--- a/gpu/command_buffer/service/shared_image/shared_image_backing.h
+++ b/gpu/command_buffer/service/shared_image/shared_image_backing.h
@@ -9,6 +9,7 @@
 
 #include <memory>
 
+#include <optional>
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/metrics/histogram_macros.h"
@@ -20,7 +21,6 @@
 #include "components/viz/common/resources/shared_image_format.h"
 #include "gpu/command_buffer/common/mailbox.h"
 #include "gpu/gpu_gles2_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkImageInfo.h"
 #include "third_party/skia/include/core/SkPixmap.h"
 #include "third_party/skia/include/gpu/GrTypes.h"
@@ -114,7 +114,7 @@
       uint32_t usage,
       size_t estimated_size,
       bool is_thread_safe,
-      absl::optional<gfx::BufferUsage> buffer_usage = absl::nullopt);
+      std::optional<gfx::BufferUsage> buffer_usage = std::nullopt);
 
   virtual ~SharedImageBacking();
 
@@ -339,7 +339,7 @@
   // Protects non-const members here and in derived classes. Protected access
   // to allow GUARDED_BY macros in derived classes. Should not be used
   // directly. Use AutoLock instead.
-  mutable absl::optional<base::Lock> lock_;
+  mutable std::optional<base::Lock> lock_;
 
  private:
   class ScopedWriteUMA {
@@ -371,7 +371,7 @@
   size_t estimated_size_ GUARDED_BY(lock_);
 
   // Note that this will be eventually removed and merged into SharedImageUsage.
-  const absl::optional<gfx::BufferUsage> buffer_usage_;
+  const std::optional<gfx::BufferUsage> buffer_usage_;
 
   bool is_ref_counted_ = true;
 
@@ -384,7 +384,7 @@
   bool have_context_ GUARDED_BY(lock_) = true;
 
   // A scoped object for recording write UMA.
-  absl::optional<ScopedWriteUMA> scoped_write_uma_ GUARDED_BY(lock_);
+  std::optional<ScopedWriteUMA> scoped_write_uma_ GUARDED_BY(lock_);
 
   // A vector of SharedImageRepresentations which hold references to this
   // backing. The first reference is considered the owner, and the vector is
@@ -408,7 +408,7 @@
       uint32_t usage,
       size_t estimated_size,
       bool is_thread_safe,
-      absl::optional<gfx::BufferUsage> buffer_usage = absl::nullopt);
+      std::optional<gfx::BufferUsage> buffer_usage = std::nullopt);
 
   gfx::Rect ClearedRect() const override;
   void SetClearedRect(const gfx::Rect& cleared_rect) override;
diff --git a/gpu/command_buffer/service/shared_image/shared_image_gl_utils.h b/gpu/command_buffer/service/shared_image/shared_image_gl_utils.h
index 12d179c..11234c6 100644
--- a/gpu/command_buffer/service/shared_image/shared_image_gl_utils.h
+++ b/gpu/command_buffer/service/shared_image/shared_image_gl_utils.h
@@ -5,9 +5,9 @@
 #ifndef GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_SHARED_IMAGE_GL_UTILS_H_
 #define GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_SHARED_IMAGE_GL_UTILS_H_
 
+#include <optional>
 #include "base/memory/raw_ptr.h"
 #include "gpu/command_buffer/service/texture_manager.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gl/gl_utils.h"
 
 namespace gpu {
@@ -28,10 +28,10 @@
   const raw_ptr<gl::GLApi> api_;
 
   GLint pack_buffer_ = 0;
-  absl::optional<gl::ScopedPixelStore> pack_alignment_;
-  absl::optional<gl::ScopedPixelStore> pack_row_length_;
-  absl::optional<gl::ScopedPixelStore> pack_skip_pixels_;
-  absl::optional<gl::ScopedPixelStore> pack_skip_rows_;
+  std::optional<gl::ScopedPixelStore> pack_alignment_;
+  std::optional<gl::ScopedPixelStore> pack_row_length_;
+  std::optional<gl::ScopedPixelStore> pack_skip_pixels_;
+  std::optional<gl::ScopedPixelStore> pack_skip_rows_;
 };
 
 // Sets GL state for upload and copy.
@@ -53,21 +53,21 @@
   GLint unpack_buffer_ = 0;
 
   // Always used when |uploading_data|.
-  absl::optional<gl::ScopedPixelStore> unpack_alignment_;
+  std::optional<gl::ScopedPixelStore> unpack_alignment_;
 
   // Used when |uploading_data_| and (|es3_capable| or
   // |supports_unpack_subimage|).
-  absl::optional<gl::ScopedPixelStore> unpack_row_length_;
-  absl::optional<gl::ScopedPixelStore> unpack_skip_pixels_;
-  absl::optional<gl::ScopedPixelStore> unpack_skip_rows_;
+  std::optional<gl::ScopedPixelStore> unpack_row_length_;
+  std::optional<gl::ScopedPixelStore> unpack_skip_pixels_;
+  std::optional<gl::ScopedPixelStore> unpack_skip_rows_;
 
   // Used when |uploading_data| and |es3_capable|.
-  absl::optional<gl::ScopedPixelStore> unpack_skip_images_;
-  absl::optional<gl::ScopedPixelStore> unpack_image_height_;
+  std::optional<gl::ScopedPixelStore> unpack_skip_images_;
+  std::optional<gl::ScopedPixelStore> unpack_image_height_;
 
   // Used when |desktop_gl|.
-  absl::optional<gl::ScopedPixelStore> unpack_swap_bytes_;
-  absl::optional<gl::ScopedPixelStore> unpack_lsb_first_;
+  std::optional<gl::ScopedPixelStore> unpack_swap_bytes_;
+  std::optional<gl::ScopedPixelStore> unpack_lsb_first_;
 };
 
 // Creates a new GL texture and returns GL texture ID.
diff --git a/gpu/command_buffer/service/shared_image/shared_image_manager.h b/gpu/command_buffer/service/shared_image/shared_image_manager.h
index ad24455..9bf8364 100644
--- a/gpu/command_buffer/service/shared_image/shared_image_manager.h
+++ b/gpu/command_buffer/service/shared_image/shared_image_manager.h
@@ -5,6 +5,7 @@
 #ifndef GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_SHARED_IMAGE_MANAGER_H_
 #define GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_SHARED_IMAGE_MANAGER_H_
 
+#include <optional>
 #include "base/containers/flat_set.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/synchronization/lock.h"
@@ -14,7 +15,6 @@
 #include "gpu/command_buffer/common/mailbox.h"
 #include "gpu/command_buffer/service/shared_image/shared_image_backing.h"
 #include "gpu/gpu_gles2_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_WIN)
 namespace gfx {
@@ -145,7 +145,7 @@
  private:
   class AutoLock;
   // The lock for protecting |images_|.
-  absl::optional<base::Lock> lock_;
+  std::optional<base::Lock> lock_;
 
   base::flat_set<std::unique_ptr<SharedImageBacking>> images_ GUARDED_BY(lock_);
 
diff --git a/gpu/command_buffer/service/shared_image/shared_image_representation.cc b/gpu/command_buffer/service/shared_image/shared_image_representation.cc
index 3f5a72f..f437ece6 100644
--- a/gpu/command_buffer/service/shared_image/shared_image_representation.cc
+++ b/gpu/command_buffer/service/shared_image/shared_image_representation.cc
@@ -724,10 +724,10 @@
   return backing()->GetNativePixmap();
 }
 #elif BUILDFLAG(IS_WIN)
-absl::optional<gl::DCLayerOverlayImage>
+std::optional<gl::DCLayerOverlayImage>
 OverlayImageRepresentation::GetDCLayerOverlayImage() {
   NOTREACHED();
-  return absl::nullopt;
+  return std::nullopt;
 }
 #elif BUILDFLAG(IS_APPLE)
 gfx::ScopedIOSurface OverlayImageRepresentation::GetIOSurface() const {
@@ -916,7 +916,7 @@
     base::PassKey<RasterImageRepresentation> pass_key,
     RasterImageRepresentation* representation,
     const cc::PaintOpBuffer* paint_op_buffer,
-    const absl::optional<SkColor4f>& clear_color)
+    const std::optional<SkColor4f>& clear_color)
     : ScopedAccessBase(representation, AccessMode::kRead),
       paint_op_buffer_(paint_op_buffer),
       clear_color_(clear_color) {}
@@ -938,7 +938,7 @@
 
 std::unique_ptr<RasterImageRepresentation::ScopedReadAccess>
 RasterImageRepresentation::BeginScopedReadAccess() {
-  absl::optional<SkColor4f> clear_color;
+  std::optional<SkColor4f> clear_color;
   auto* paint_op_buffer = BeginReadAccess(clear_color);
   if (!paint_op_buffer) {
     return nullptr;
@@ -953,7 +953,7 @@
     scoped_refptr<SharedContextState> context_state,
     int final_msaa_count,
     const SkSurfaceProps& surface_props,
-    const absl::optional<SkColor4f>& clear_color,
+    const std::optional<SkColor4f>& clear_color,
     bool visible) {
   return std::make_unique<ScopedWriteAccess>(
       base::PassKey<RasterImageRepresentation>(), this,
diff --git a/gpu/command_buffer/service/shared_image/shared_image_representation.h b/gpu/command_buffer/service/shared_image/shared_image_representation.h
index 257f37d..78e241f 100644
--- a/gpu/command_buffer/service/shared_image/shared_image_representation.h
+++ b/gpu/command_buffer/service/shared_image/shared_image_representation.h
@@ -813,7 +813,7 @@
       return representation()->GetNativePixmap();
     }
 #elif BUILDFLAG(IS_WIN)
-    absl::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage() {
+    std::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage() {
       return representation()->GetDCLayerOverlayImage();
     }
 #elif BUILDFLAG(IS_APPLE)
@@ -864,7 +864,7 @@
 #elif BUILDFLAG(IS_OZONE)
   scoped_refptr<gfx::NativePixmap> GetNativePixmap();
 #elif BUILDFLAG(IS_WIN)
-  virtual absl::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage();
+  virtual std::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage();
 #elif BUILDFLAG(IS_APPLE)
   virtual gfx::ScopedIOSurface GetIOSurface() const;
   // Return true if the macOS WindowServer is currently using the underlying
@@ -1008,19 +1008,17 @@
     ScopedReadAccess(base::PassKey<RasterImageRepresentation> pass_key,
                      RasterImageRepresentation* representation,
                      const cc::PaintOpBuffer* paint_op_buffer,
-                     const absl::optional<SkColor4f>& clear_color);
+                     const std::optional<SkColor4f>& clear_color);
     ~ScopedReadAccess();
 
     const cc::PaintOpBuffer* paint_op_buffer() const {
       return paint_op_buffer_;
     }
-    const absl::optional<SkColor4f>& clear_color() const {
-      return clear_color_;
-    }
+    const std::optional<SkColor4f>& clear_color() const { return clear_color_; }
 
    private:
     const raw_ptr<const cc::PaintOpBuffer> paint_op_buffer_;
-    absl::optional<SkColor4f> clear_color_;
+    std::optional<SkColor4f> clear_color_;
   };
 
   class GPU_GLES2_EXPORT ScopedWriteAccess
@@ -1056,18 +1054,18 @@
       scoped_refptr<SharedContextState> context_state,
       int final_msaa_count,
       const SkSurfaceProps& surface_props,
-      const absl::optional<SkColor4f>& clear_color,
+      const std::optional<SkColor4f>& clear_color,
       bool visible);
 
  protected:
   virtual cc::PaintOpBuffer* BeginReadAccess(
-      absl::optional<SkColor4f>& clear_color) = 0;
+      std::optional<SkColor4f>& clear_color) = 0;
   virtual void EndReadAccess() = 0;
   virtual cc::PaintOpBuffer* BeginWriteAccess(
       scoped_refptr<SharedContextState> context_state,
       int final_msaa_count,
       const SkSurfaceProps& surface_props,
-      const absl::optional<SkColor4f>& clear_color,
+      const std::optional<SkColor4f>& clear_color,
       bool visible) = 0;
   virtual void EndWriteAccess(base::OnceClosure callback) = 0;
 };
diff --git a/gpu/command_buffer/service/shared_image/shared_memory_image_backing.cc b/gpu/command_buffer/service/shared_image/shared_memory_image_backing.cc
index 7dd6a8a92..3c92a17 100644
--- a/gpu/command_buffer/service/shared_image/shared_memory_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/shared_memory_image_backing.cc
@@ -66,13 +66,13 @@
   void EndReadAccess(gfx::GpuFenceHandle release_fence) override {}
 
 #if BUILDFLAG(IS_WIN)
-  absl::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage() override {
+  std::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage() override {
     // This should only be called for the backing which references the Y plane,
     // eg. plane_index=0, of an NV12 shmem GMB - see allow_shm_overlay in
     // SharedImageFactory. This allows access to both Y and UV planes.
     const auto& shm_wrapper = static_cast<SharedMemoryImageBacking*>(backing())
                                   ->shared_memory_wrapper();
-    return absl::make_optional<gl::DCLayerOverlayImage>(
+    return std::make_optional<gl::DCLayerOverlayImage>(
         size(), shm_wrapper.GetMemory(0), shm_wrapper.GetStride(0));
   }
 #endif
@@ -204,7 +204,7 @@
     uint32_t usage,
     SharedMemoryRegionWrapper wrapper,
     gfx::GpuMemoryBufferHandle handle,
-    absl::optional<gfx::BufferUsage> buffer_usage)
+    std::optional<gfx::BufferUsage> buffer_usage)
     : SharedImageBacking(mailbox,
                          format,
                          size,
diff --git a/gpu/command_buffer/service/shared_image/shared_memory_image_backing.h b/gpu/command_buffer/service/shared_image/shared_memory_image_backing.h
index 9c97cea..07a74cf 100644
--- a/gpu/command_buffer/service/shared_image/shared_memory_image_backing.h
+++ b/gpu/command_buffer/service/shared_image/shared_memory_image_backing.h
@@ -32,7 +32,7 @@
       uint32_t usage,
       SharedMemoryRegionWrapper wrapper,
       gfx::GpuMemoryBufferHandle handle = gfx::GpuMemoryBufferHandle(),
-      absl::optional<gfx::BufferUsage> buffer_usage = absl::nullopt);
+      std::optional<gfx::BufferUsage> buffer_usage = std::nullopt);
 
   ~SharedMemoryImageBacking() override;
 
diff --git a/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing.cc b/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing.cc
index 70e048b0..86053942 100644
--- a/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing.cc
@@ -265,7 +265,7 @@
   textures_.resize(1);
 
   {
-    absl::optional<gpu::raster::GrShaderCache::ScopedCacheUse> cache_use;
+    std::optional<gpu::raster::GrShaderCache::ScopedCacheUse> cache_use;
     // ScopedCacheUse is used to avoid the empty/invalid client id DCHECKS
     // caused while accessing GrShaderCache. Even though other clients can
     // create shared images, the context used to create the backend texture
diff --git a/gpu/command_buffer/service/shared_image_interface_in_process.cc b/gpu/command_buffer/service/shared_image_interface_in_process.cc
index 8ef587a..e56d40b6 100644
--- a/gpu/command_buffer/service/shared_image_interface_in_process.cc
+++ b/gpu/command_buffer/service/shared_image_interface_in_process.cc
@@ -4,6 +4,7 @@
 
 #include "gpu/command_buffer/service/shared_image_interface_in_process.h"
 
+#include <optional>
 #include "base/functional/bind.h"
 #include "base/memory/raw_ptr.h"
 #include "base/synchronization/waitable_event.h"
@@ -23,7 +24,6 @@
 #include "gpu/config/gpu_feature_info.h"
 #include "gpu/config/gpu_preferences.h"
 #include "gpu/ipc/common/gpu_client_ids.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gl/gl_context.h"
 
 namespace gpu {
diff --git a/gpu/command_buffer/service/skia_utils.cc b/gpu/command_buffer/service/skia_utils.cc
index db2b00ee..521cfd3 100644
--- a/gpu/command_buffer/service/skia_utils.cc
+++ b/gpu/command_buffer/service/skia_utils.cc
@@ -364,7 +364,7 @@
     VkImageTiling tiling,
     VkFormat format,
     const gfx::ColorSpace& color_space,
-    const absl::optional<VulkanYCbCrInfo>& ycbcr_info) {
+    const std::optional<VulkanYCbCrInfo>& ycbcr_info) {
   auto valid_ycbcr_info = ycbcr_info;
   if (!valid_ycbcr_info) {
     if (!VkFormatNeedsYcbcrSampler(format)) {
@@ -440,7 +440,7 @@
     viz::VulkanContextProvider* context_provider) {
 #if BUILDFLAG(ENABLE_VULKAN)
   if (context_provider) {
-    const absl::optional<uint32_t>& sync_cpu_memory_limit =
+    const std::optional<uint32_t>& sync_cpu_memory_limit =
         context_provider->GetSyncCpuMemoryLimit();
     if (sync_cpu_memory_limit.has_value()) {
       uint64_t total_allocated_bytes =
diff --git a/gpu/command_buffer/service/skia_utils.h b/gpu/command_buffer/service/skia_utils.h
index d0751e463..7d52d2b 100644
--- a/gpu/command_buffer/service/skia_utils.h
+++ b/gpu/command_buffer/service/skia_utils.h
@@ -5,6 +5,7 @@
 #ifndef GPU_COMMAND_BUFFER_SERVICE_SKIA_UTILS_H_
 #define GPU_COMMAND_BUFFER_SERVICE_SKIA_UTILS_H_
 
+#include <optional>
 #include "base/functional/callback_forward.h"
 #include "gpu/config/gpu_driver_bug_workarounds.h"
 #include "gpu/config/gpu_preferences.h"
@@ -12,7 +13,6 @@
 #include "gpu/ipc/common/vulkan_ycbcr_info.h"
 #include "gpu/vulkan/buildflags.h"
 #include "skia/buildflags.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkSurface.h"
 #include "third_party/skia/include/gpu/GrContextOptions.h"
 #include "third_party/skia/include/gpu/GrTypes.h"
@@ -108,12 +108,12 @@
 GPU_GLES2_EXPORT GrVkImageInfo
 CreateGrVkImageInfo(VulkanImage* image, const gfx::ColorSpace& color_space);
 
-GPU_GLES2_EXPORT GrVkYcbcrConversionInfo CreateGrVkYcbcrConversionInfo(
-    VkPhysicalDevice physical_device,
-    VkImageTiling tiling,
-    VkFormat format,
-    const gfx::ColorSpace& color_space,
-    const absl::optional<VulkanYCbCrInfo>& ycbcr_info);
+GPU_GLES2_EXPORT GrVkYcbcrConversionInfo
+CreateGrVkYcbcrConversionInfo(VkPhysicalDevice physical_device,
+                              VkImageTiling tiling,
+                              VkFormat format,
+                              const gfx::ColorSpace& color_space,
+                              const std::optional<VulkanYCbCrInfo>& ycbcr_info);
 #endif  // BUILDFLAG(ENABLE_VULKAN)
 
 // Helper that returns true when Vulkan memory usage is high enough
diff --git a/gpu/command_buffer/service/texture_owner.cc b/gpu/command_buffer/service/texture_owner.cc
index fa767f8..ccb982d 100644
--- a/gpu/command_buffer/service/texture_owner.cc
+++ b/gpu/command_buffer/service/texture_owner.cc
@@ -58,7 +58,7 @@
 
 TextureOwner::~TextureOwner() {
   bool have_context = true;
-  absl::optional<ui::ScopedMakeCurrent> scoped_make_current;
+  std::optional<ui::ScopedMakeCurrent> scoped_make_current;
   if (!context_state_) {
     have_context = false;
   } else {
diff --git a/gpu/command_buffer/service/webgpu_decoder.h b/gpu/command_buffer/service/webgpu_decoder.h
index 58f7bf2..c292665 100644
--- a/gpu/command_buffer/service/webgpu_decoder.h
+++ b/gpu/command_buffer/service/webgpu_decoder.h
@@ -5,12 +5,12 @@
 #ifndef GPU_COMMAND_BUFFER_SERVICE_WEBGPU_DECODER_H_
 #define GPU_COMMAND_BUFFER_SERVICE_WEBGPU_DECODER_H_
 
+#include <optional>
 #include "base/memory/raw_ptr.h"
 #include "gpu/command_buffer/service/common_decoder.h"
 #include "gpu/command_buffer/service/decoder_context.h"
 #include "gpu/gpu_gles2_export.h"
 #include "gpu/ipc/common/gpu_disk_cache_type.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace gpu {
 
@@ -33,7 +33,7 @@
 // Options specifically passed for Dawn caching;
 struct DawnCacheOptions {
   raw_ptr<DawnCachingInterfaceFactory> caching_interface_factory = nullptr;
-  absl::optional<GpuDiskCacheHandle> handle = {};
+  std::optional<GpuDiskCacheHandle> handle = {};
 };
 
 class GPU_GLES2_EXPORT WebGPUDecoder : public DecoderContext,
diff --git a/gpu/command_buffer/service/webgpu_decoder_impl.cc b/gpu/command_buffer/service/webgpu_decoder_impl.cc
index 3aa4427..cd60ba7 100644
--- a/gpu/command_buffer/service/webgpu_decoder_impl.cc
+++ b/gpu/command_buffer/service/webgpu_decoder_impl.cc
@@ -13,6 +13,7 @@
 #include <memory>
 #include <vector>
 
+#include <optional>
 #include "base/auto_reset.h"
 #include "base/bits.h"
 #include "base/containers/contains.h"
@@ -52,7 +53,6 @@
 #include "gpu/config/webgpu_blocklist.h"
 #include "gpu/webgpu/callback.h"
 #include "third_party/abseil-cpp/absl/base/attributes.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/tokens/tokens.h"
 #include "third_party/skia/include/gpu/GrBackendSemaphore.h"
 #include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h"
@@ -445,7 +445,7 @@
 
   // Isolation key that is necessary for device requests. Optional to
   // differentiate between an empty isolation key, and an unset one.
-  absl::optional<std::string> isolation_key_;
+  std::optional<std::string> isolation_key_;
 
   std::unique_ptr<dawn::wire::WireServer> wire_server_;
   std::unique_ptr<DawnServiceSerializer> wire_serializer_;
@@ -2159,7 +2159,7 @@
   blink::WebGPUExecutionContextToken::Tag type{c.type};
   uint64_t high = uint64_t(c.high_high) << 32 | uint64_t(c.high_low);
   uint64_t low = uint64_t(c.low_high) << 32 | uint64_t(c.low_low);
-  absl::optional<base::UnguessableToken> unguessable_token =
+  std::optional<base::UnguessableToken> unguessable_token =
       base::UnguessableToken::Deserialize(high, low);
   if (!unguessable_token.has_value()) {
     return error::kInvalidArguments;
diff --git a/gpu/config/device_perf_info.cc b/gpu/config/device_perf_info.cc
index 5376ef23..495408cc 100644
--- a/gpu/config/device_perf_info.cc
+++ b/gpu/config/device_perf_info.cc
@@ -11,7 +11,7 @@
 
 namespace {
 // Global instance in browser process.
-absl::optional<DevicePerfInfo> g_device_perf_info;
+std::optional<DevicePerfInfo> g_device_perf_info;
 
 base::Lock& GetLock() {
   static base::NoDestructor<base::Lock> lock;
@@ -19,7 +19,7 @@
 }
 }  // namespace
 
-absl::optional<DevicePerfInfo> GetDevicePerfInfo() {
+std::optional<DevicePerfInfo> GetDevicePerfInfo() {
   base::AutoLock lock(GetLock());
   return g_device_perf_info;
 }
diff --git a/gpu/config/device_perf_info.h b/gpu/config/device_perf_info.h
index bdcdbc4..521d251 100644
--- a/gpu/config/device_perf_info.h
+++ b/gpu/config/device_perf_info.h
@@ -6,9 +6,9 @@
 #define GPU_CONFIG_DEVICE_PERF_INFO_H_
 
 #include <cstdint>
+#include <optional>
 #include "build/build_config.h"
 #include "gpu/gpu_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_WIN)
 #include <d3dcommon.h>
@@ -61,7 +61,7 @@
 };
 
 // Thread-safe getter and setter of global instance of DevicePerfInfo.
-GPU_EXPORT absl::optional<DevicePerfInfo> GetDevicePerfInfo();
+GPU_EXPORT std::optional<DevicePerfInfo> GetDevicePerfInfo();
 GPU_EXPORT void SetDevicePerfInfo(const DevicePerfInfo& device_perf_info);
 
 }  // namespace gpu
diff --git a/gpu/config/gpu_info.cc b/gpu/config/gpu_info.cc
index eb74a1091..2dde12c6 100644
--- a/gpu/config/gpu_info.cc
+++ b/gpu/config/gpu_info.cc
@@ -349,7 +349,7 @@
     uint32_t visibility_callback_call_count;
 
 #if BUILDFLAG(ENABLE_VULKAN)
-    absl::optional<VulkanInfo> vulkan_info;
+    std::optional<VulkanInfo> vulkan_info;
 #endif
   };
 
diff --git a/gpu/config/gpu_info.h b/gpu/config/gpu_info.h
index 72c9521..cc11375 100644
--- a/gpu/config/gpu_info.h
+++ b/gpu/config/gpu_info.h
@@ -13,6 +13,7 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/clang_profiling_buildflags.h"
 #include "base/containers/flat_map.h"
 #include "base/containers/span.h"
@@ -22,7 +23,6 @@
 #include "gpu/config/dx_diag_node.h"
 #include "gpu/gpu_export.h"
 #include "gpu/vulkan/buildflags.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gl/gl_implementation.h"
 #include "ui/gl/gpu_preference.h"
@@ -495,7 +495,7 @@
   uint32_t visibility_callback_call_count = 0;
 
 #if BUILDFLAG(ENABLE_VULKAN)
-  absl::optional<VulkanInfo> vulkan_info;
+  std::optional<VulkanInfo> vulkan_info;
 #endif
 
   // Note: when adding new members, please remember to update EnumerateFields
diff --git a/gpu/config/gpu_info_collector.cc b/gpu/config/gpu_info_collector.cc
index ab8754d..14a5a0e 100644
--- a/gpu/config/gpu_info_collector.cc
+++ b/gpu/config/gpu_info_collector.cc
@@ -11,6 +11,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/base_paths.h"
 #include "base/command_line.h"
 #include "base/files/file_path.h"
@@ -27,7 +28,6 @@
 #include "gpu/config/gpu_switches.h"
 #include "gpu/config/webgpu_blocklist.h"
 #include "skia/buildflags.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/angle/src/gpu_info_util/SystemInfo.h"  // nogncheck
 #include "third_party/skia/include/core/SkGraphics.h"
 #include "ui/gl/buildflags.h"
@@ -528,7 +528,7 @@
       gl::UsePassthroughCommandDecoder(command_line);
 
   bool fallback_to_software = false;
-  absl::optional<gl::GLImplementationParts> implementation =
+  std::optional<gl::GLImplementationParts> implementation =
       gl::GetRequestedGLImplementationFromCommandLine(command_line,
                                                       &fallback_to_software);
 
diff --git a/gpu/config/gpu_util.cc b/gpu/config/gpu_util.cc
index 87e0039..89f88c8 100644
--- a/gpu/config/gpu_util.cc
+++ b/gpu/config/gpu_util.cc
@@ -19,6 +19,7 @@
 #include <thread>
 #include <vector>
 
+#include <optional>
 #include "base/base_paths.h"
 #include "base/command_line.h"
 #include "base/files/file_path.h"
@@ -44,7 +45,6 @@
 #include "gpu/config/gpu_switches.h"
 #include "gpu/vulkan/buildflags.h"
 #include "skia/buildflags.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/extension_set.h"
 #include "ui/gl/buildflags.h"
 #include "ui/gl/gl_display.h"
@@ -534,7 +534,7 @@
   bool use_swift_shader = false;
 
   bool fallback_to_software_gl = false;
-  absl::optional<gl::GLImplementationParts> requested_impl =
+  std::optional<gl::GLImplementationParts> requested_impl =
       gl::GetRequestedGLImplementationFromCommandLine(command_line,
                                                       &fallback_to_software_gl);
   if (requested_impl) {
@@ -1020,7 +1020,7 @@
 }
 
 void RecordDevicePerfInfoHistograms() {
-  absl::optional<DevicePerfInfo> device_perf_info = GetDevicePerfInfo();
+  std::optional<DevicePerfInfo> device_perf_info = GetDevicePerfInfo();
   if (!device_perf_info.has_value())
     return;
   UMA_HISTOGRAM_COUNTS_1000("Hardware.TotalDiskSpace",
diff --git a/gpu/ipc/client/command_buffer_proxy_impl.cc b/gpu/ipc/client/command_buffer_proxy_impl.cc
index 2e255dca..23619f17 100644
--- a/gpu/ipc/client/command_buffer_proxy_impl.cc
+++ b/gpu/ipc/client/command_buffer_proxy_impl.cc
@@ -6,6 +6,7 @@
 
 #include <memory>
 
+#include <optional>
 #include "base/command_line.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
@@ -34,7 +35,6 @@
 #include "mojo/public/cpp/bindings/sync_call_restrictions.h"
 #include "mojo/public/cpp/system/buffer.h"
 #include "mojo/public/cpp/system/platform_handle.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/buffer_format_util.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/gpu_fence.h"
diff --git a/gpu/ipc/client/gpu_channel_host.h b/gpu/ipc/client/gpu_channel_host.h
index a1a5501c..b6ecec0 100644
--- a/gpu/ipc/client/gpu_channel_host.h
+++ b/gpu/ipc/client/gpu_channel_host.h
@@ -257,7 +257,7 @@
   mutable base::Lock context_lock_;
   std::vector<mojom::DeferredRequestPtr> deferred_messages_
       GUARDED_BY(context_lock_);
-  absl::optional<OrderingBarrierInfo> pending_ordering_barrier_
+  std::optional<OrderingBarrierInfo> pending_ordering_barrier_
       GUARDED_BY(context_lock_);
   uint32_t next_deferred_message_id_ GUARDED_BY(context_lock_) = 1;
   // Highest deferred message id in |deferred_messages_|.
diff --git a/gpu/ipc/common/gpu_info_mojom_traits.h b/gpu/ipc/common/gpu_info_mojom_traits.h
index 1697d6fe..33ea2f0 100644
--- a/gpu/ipc/common/gpu_info_mojom_traits.h
+++ b/gpu/ipc/common/gpu_info_mojom_traits.h
@@ -5,13 +5,13 @@
 #ifndef GPU_IPC_COMMON_GPU_INFO_MOJOM_TRAITS_H_
 #define GPU_IPC_COMMON_GPU_INFO_MOJOM_TRAITS_H_
 
+#include <optional>
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "gpu/config/gpu_info.h"
 #include "gpu/gpu_export.h"
 #include "gpu/ipc/common/dx_diag_node_mojom_traits.h"
 #include "gpu/ipc/common/gpu_info.mojom.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/buffer_types.h"
 #include "ui/gfx/geometry/mojom/geometry_mojom_traits.h"
 
@@ -423,7 +423,7 @@
   }
 
 #if BUILDFLAG(ENABLE_VULKAN)
-  static const absl::optional<gpu::VulkanInfo>& vulkan_info(
+  static const std::optional<gpu::VulkanInfo>& vulkan_info(
       const gpu::GPUInfo& input) {
     return input.vulkan_info;
   }
diff --git a/gpu/ipc/in_process_command_buffer.cc b/gpu/ipc/in_process_command_buffer.cc
index 9591f762..160d366 100644
--- a/gpu/ipc/in_process_command_buffer.cc
+++ b/gpu/ipc/in_process_command_buffer.cc
@@ -157,7 +157,7 @@
 }
 
 void InProcessCommandBuffer::CreateCacheUse(
-    absl::optional<gles2::ProgramCache::ScopedCacheUse>& cache_use) {
+    std::optional<gles2::ProgramCache::ScopedCacheUse>& cache_use) {
   if (context_group_->has_program_cache()) {
     cache_use.emplace(
         context_group_->get_program_cache(),
@@ -491,7 +491,7 @@
   gpu_thread_weak_ptr_factory_.InvalidateWeakPtrs();
   // Clean up GL resources if possible.
   bool have_context = context_.get() && context_->MakeCurrent(surface_.get());
-  absl::optional<gles2::ProgramCache::ScopedCacheUse> cache_use;
+  std::optional<gles2::ProgramCache::ScopedCacheUse> cache_use;
   if (have_context)
     CreateCacheUse(cache_use);
 
@@ -613,11 +613,11 @@
 
   if (!MakeCurrent())
     return;
-  absl::optional<gles2::ProgramCache::ScopedCacheUse> cache_use;
+  std::optional<gles2::ProgramCache::ScopedCacheUse> cache_use;
   CreateCacheUse(cache_use);
 
   {
-    absl::optional<raster::GrShaderCache::ScopedCacheUse> gr_cache_use;
+    std::optional<raster::GrShaderCache::ScopedCacheUse> gr_cache_use;
     if (gr_shader_cache_)
       gr_cache_use.emplace(gr_shader_cache_, kDisplayCompositorClientId);
     command_buffer_->Flush(put_offset, decoder_.get());
@@ -646,7 +646,7 @@
   delayed_work_pending_ = false;
 
   if (MakeCurrent()) {
-    absl::optional<gles2::ProgramCache::ScopedCacheUse> cache_use;
+    std::optional<gles2::ProgramCache::ScopedCacheUse> cache_use;
     CreateCacheUse(cache_use);
     decoder_->PerformIdleWork();
     decoder_->ProcessPendingQueries(false);
diff --git a/gpu/ipc/in_process_command_buffer.h b/gpu/ipc/in_process_command_buffer.h
index 91d1ef9..9319dbb 100644
--- a/gpu/ipc/in_process_command_buffer.h
+++ b/gpu/ipc/in_process_command_buffer.h
@@ -13,6 +13,7 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/compiler_specific.h"
 #include "base/functional/callback.h"
 #include "base/functional/callback_helpers.h"
@@ -44,7 +45,6 @@
 #include "gpu/ipc/common/surface_handle.h"
 #include "gpu/ipc/gl_in_process_context_export.h"
 #include "gpu/ipc/service/context_url.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/gpu_memory_buffer.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/gl/gl_surface.h"
@@ -216,7 +216,7 @@
   bool MakeCurrent();
 
   void CreateCacheUse(
-      absl::optional<gles2::ProgramCache::ScopedCacheUse>& cache_use);
+      std::optional<gles2::ProgramCache::ScopedCacheUse>& cache_use);
 
   // Client callbacks are posted back to |origin_task_runner_|, or run
   // synchronously if there's no task runner or message loop.
diff --git a/gpu/ipc/service/command_buffer_stub.cc b/gpu/ipc/service/command_buffer_stub.cc
index 2fc7c68..0f76edfd 100644
--- a/gpu/ipc/service/command_buffer_stub.cc
+++ b/gpu/ipc/service/command_buffer_stub.cc
@@ -189,7 +189,7 @@
                                                                         : "0");
   if (decoder_context_.get() && !MakeCurrent())
     return;
-  absl::optional<gles2::ProgramCache::ScopedCacheUse> cache_use;
+  std::optional<gles2::ProgramCache::ScopedCacheUse> cache_use;
   CreateCacheUse(cache_use);
 
   if (decoder_context_) {
@@ -283,7 +283,7 @@
 }
 
 void CommandBufferStub::CreateCacheUse(
-    absl::optional<gles2::ProgramCache::ScopedCacheUse>& cache_use) {
+    std::optional<gles2::ProgramCache::ScopedCacheUse>& cache_use) {
   cache_use.emplace(
       channel_->gpu_channel_manager()->program_cache(),
       base::BindRepeating(&DecoderClient::CacheBlob, base::Unretained(this),
@@ -330,7 +330,7 @@
         decoder_context_->GetGLContext()->MakeCurrent(surface_.get());
   }
 
-  absl::optional<gles2::ProgramCache::ScopedCacheUse> cache_use;
+  std::optional<gles2::ProgramCache::ScopedCacheUse> cache_use;
   if (have_context)
     CreateCacheUse(cache_use);
 
@@ -346,7 +346,7 @@
 
   if (decoder_context_) {
     auto* gr_shader_cache = channel_->gpu_channel_manager()->gr_shader_cache();
-    absl::optional<raster::GrShaderCache::ScopedCacheUse> gr_cache_use;
+    std::optional<raster::GrShaderCache::ScopedCacheUse> gr_cache_use;
     if (gr_shader_cache)
       gr_cache_use.emplace(gr_shader_cache, channel_->client_id());
 
@@ -501,7 +501,7 @@
 
   {
     auto* gr_shader_cache = channel_->gpu_channel_manager()->gr_shader_cache();
-    absl::optional<raster::GrShaderCache::ScopedCacheUse> cache_use;
+    std::optional<raster::GrShaderCache::ScopedCacheUse> cache_use;
     if (gr_shader_cache)
       cache_use.emplace(gr_shader_cache, channel_->client_id());
     command_buffer_->Flush(put_offset, decoder_context_.get());
diff --git a/gpu/ipc/service/command_buffer_stub.h b/gpu/ipc/service/command_buffer_stub.h
index 5fe890b..68ad357 100644
--- a/gpu/ipc/service/command_buffer_stub.h
+++ b/gpu/ipc/service/command_buffer_stub.h
@@ -12,6 +12,7 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/raw_ref.h"
@@ -38,7 +39,6 @@
 #include "gpu/ipc/service/gpu_ipc_service_export.h"
 #include "mojo/public/cpp/bindings/associated_receiver.h"
 #include "mojo/public/cpp/bindings/shared_associated_remote.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/gpu_memory_buffer.h"
 #include "ui/gfx/swap_result.h"
@@ -209,7 +209,7 @@
    private:
     const raw_ref<CommandBufferStub> stub_;
     bool have_context_ = false;
-    absl::optional<gles2::ProgramCache::ScopedCacheUse> cache_use_;
+    std::optional<gles2::ProgramCache::ScopedCacheUse> cache_use_;
   };
 
   mojom::CommandBufferClient& client() { return *client_.get(); }
@@ -290,7 +290,7 @@
   void Destroy();
 
   void CreateCacheUse(
-      absl::optional<gles2::ProgramCache::ScopedCacheUse>& cache_use);
+      std::optional<gles2::ProgramCache::ScopedCacheUse>& cache_use);
 
   // Message handlers:
   void OnAsyncFlush(int32_t put_offset,
diff --git a/gpu/ipc/service/dcomp_texture_win.cc b/gpu/ipc/service/dcomp_texture_win.cc
index db51373b..88354cb 100644
--- a/gpu/ipc/service/dcomp_texture_win.cc
+++ b/gpu/ipc/service/dcomp_texture_win.cc
@@ -45,9 +45,9 @@
       : OverlayImageRepresentation(manager, backing, tracker),
         dcomp_surface_proxy_(std::move(dcomp_surface_proxy)) {}
 
-  absl::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage() override {
-    return absl::make_optional<gl::DCLayerOverlayImage>(size(),
-                                                        dcomp_surface_proxy_);
+  std::optional<gl::DCLayerOverlayImage> GetDCLayerOverlayImage() override {
+    return std::make_optional<gl::DCLayerOverlayImage>(size(),
+                                                       dcomp_surface_proxy_);
   }
 
   bool BeginReadAccess(gfx::GpuFenceHandle& acquire_fence) override {
diff --git a/gpu/ipc/service/gpu_channel.cc b/gpu/ipc/service/gpu_channel.cc
index 725f8df..c8a70a47a 100644
--- a/gpu/ipc/service/gpu_channel.cc
+++ b/gpu/ipc/service/gpu_channel.cc
@@ -1217,7 +1217,7 @@
 }
 #endif  // BUILDFLAG(IS_FUCHSIA)
 
-absl::optional<gpu::GpuDiskCacheHandle> GpuChannel::GetCacheHandleForType(
+std::optional<gpu::GpuDiskCacheHandle> GpuChannel::GetCacheHandleForType(
     gpu::GpuDiskCacheType type) {
   auto it = caches_.find(type);
   if (it == caches_.end()) {
diff --git a/gpu/ipc/service/gpu_channel.h b/gpu/ipc/service/gpu_channel.h
index 144ff81..be8fbf3a 100644
--- a/gpu/ipc/service/gpu_channel.h
+++ b/gpu/ipc/service/gpu_channel.h
@@ -11,6 +11,7 @@
 #include <memory>
 #include <string>
 
+#include <optional>
 #include "base/containers/flat_map.h"
 #include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
@@ -33,7 +34,6 @@
 #include "ipc/ipc_sync_channel.h"
 #include "mojo/public/cpp/bindings/generic_pending_associated_receiver.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/gpu_extra_info.h"
 #include "ui/gfx/native_widget_types.h"
@@ -139,7 +139,7 @@
   // Called to remove a listener for a particular message routing ID.
   void RemoveRoute(int32_t route_id);
 
-  absl::optional<gpu::GpuDiskCacheHandle> GetCacheHandleForType(
+  std::optional<gpu::GpuDiskCacheHandle> GetCacheHandleForType(
       gpu::GpuDiskCacheType type);
   void RegisterCacheHandle(const gpu::GpuDiskCacheHandle& handle);
   void CacheBlob(gpu::GpuDiskCacheType type,
diff --git a/gpu/ipc/service/gpu_channel_manager.h b/gpu/ipc/service/gpu_channel_manager.h
index 7b9c992..7201816 100644
--- a/gpu/ipc/service/gpu_channel_manager.h
+++ b/gpu/ipc/service/gpu_channel_manager.h
@@ -11,6 +11,7 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/containers/flat_map.h"
 #include "base/memory/memory_pressure_listener.h"
 #include "base/memory/raw_ptr.h"
@@ -39,7 +40,6 @@
 #include "gpu/ipc/common/gpu_disk_cache_type.h"
 #include "gpu/ipc/common/gpu_peak_memory.h"
 #include "gpu/ipc/service/gpu_ipc_service_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/gpu_memory_buffer.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/gl/gl_surface.h"
@@ -387,7 +387,7 @@
   // order to avoid having the GpuChannelManager keep the lost context state
   // alive until all clients have recovered, we use a ref-counted object and
   // allow the decoders to manage its lifetime.
-  absl::optional<raster::GrShaderCache> gr_shader_cache_;
+  std::optional<raster::GrShaderCache> gr_shader_cache_;
   scoped_refptr<SharedContextState> shared_context_state_;
 
   raw_ptr<webgpu::DawnCachingInterfaceFactory> dawn_caching_interface_factory_;
diff --git a/gpu/ipc/service/gpu_init.cc b/gpu/ipc/service/gpu_init.cc
index c5ab7f07..4adc2ec 100644
--- a/gpu/ipc/service/gpu_init.cc
+++ b/gpu/ipc/service/gpu_init.cc
@@ -7,6 +7,7 @@
 #include <cstdlib>
 #include <string>
 
+#include <optional>
 #include "base/base_paths.h"
 #include "base/command_line.h"
 #include "base/files/file_path.h"
@@ -35,7 +36,6 @@
 #include "gpu/config/gpu_switching.h"
 #include "gpu/config/gpu_util.h"
 #include "gpu/ipc/service/gpu_watchdog_thread.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/ui_base_features.h"
 #include "ui/gfx/switches.h"
 #include "ui/gl/buildflags.h"
diff --git a/gpu/ipc/service/gpu_init.h b/gpu/ipc/service/gpu_init.h
index eb23ec15..b65c831 100644
--- a/gpu/ipc/service/gpu_init.h
+++ b/gpu/ipc/service/gpu_init.h
@@ -5,6 +5,7 @@
 #ifndef GPU_IPC_SERVICE_GPU_INIT_H_
 #define GPU_IPC_SERVICE_GPU_INIT_H_
 
+#include <optional>
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "gpu/config/device_perf_info.h"
@@ -14,7 +15,6 @@
 #include "gpu/ipc/service/gpu_ipc_service_export.h"
 #include "gpu/ipc/service/gpu_watchdog_thread.h"
 #include "gpu/vulkan/buildflags.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/gpu_extra_info.h"
 
 namespace base {
@@ -63,14 +63,14 @@
   const GPUInfo& gpu_info() const { return gpu_info_; }
   const GpuFeatureInfo& gpu_feature_info() const { return gpu_feature_info_; }
   const gfx::GpuExtraInfo& gpu_extra_info() const { return gpu_extra_info_; }
-  const absl::optional<GPUInfo>& gpu_info_for_hardware_gpu() const {
+  const std::optional<GPUInfo>& gpu_info_for_hardware_gpu() const {
     return gpu_info_for_hardware_gpu_;
   }
-  const absl::optional<GpuFeatureInfo>& gpu_feature_info_for_hardware_gpu()
+  const std::optional<GpuFeatureInfo>& gpu_feature_info_for_hardware_gpu()
       const {
     return gpu_feature_info_for_hardware_gpu_;
   }
-  const absl::optional<DevicePerfInfo>& device_perf_info() const {
+  const std::optional<DevicePerfInfo>& device_perf_info() const {
     return device_perf_info_;
   }
   const GpuPreferences& gpu_preferences() const { return gpu_preferences_; }
@@ -101,13 +101,13 @@
 
   // The following data are collected from hardware GPU and saved before
   // switching to SwiftShader.
-  absl::optional<GPUInfo> gpu_info_for_hardware_gpu_;
-  absl::optional<GpuFeatureInfo> gpu_feature_info_for_hardware_gpu_;
+  std::optional<GPUInfo> gpu_info_for_hardware_gpu_;
+  std::optional<GpuFeatureInfo> gpu_feature_info_for_hardware_gpu_;
 
   gfx::GpuExtraInfo gpu_extra_info_;
 
   // The following data are collected by the info collection GPU process.
-  absl::optional<DevicePerfInfo> device_perf_info_;
+  std::optional<DevicePerfInfo> device_perf_info_;
 
 #if BUILDFLAG(ENABLE_VULKAN)
   std::unique_ptr<VulkanImplementation> vulkan_implementation_;
diff --git a/gpu/ipc/service/gpu_watchdog_thread_unittest.cc b/gpu/ipc/service/gpu_watchdog_thread_unittest.cc
index f9a861c..08888ce 100644
--- a/gpu/ipc/service/gpu_watchdog_thread_unittest.cc
+++ b/gpu/ipc/service/gpu_watchdog_thread_unittest.cc
@@ -137,7 +137,7 @@
   } else {
     // Check Mac machine model version.
     std::string model_str = base::SysInfo::HardwareModelName();
-    absl::optional<base::SysInfo::HardwareModelNameSplit> split =
+    std::optional<base::SysInfo::HardwareModelNameSplit> split =
         base::SysInfo::SplitHardwareModelNameDoNotUse(model_str);
 
     if (split && split.value().category == "MacBookPro" &&
diff --git a/gpu/ipc/service/image_decode_accelerator_stub.cc b/gpu/ipc/service/image_decode_accelerator_stub.cc
index bc847e8b..d3d70cb0 100644
--- a/gpu/ipc/service/image_decode_accelerator_stub.cc
+++ b/gpu/ipc/service/image_decode_accelerator_stub.cc
@@ -11,6 +11,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/containers/span.h"
 #include "base/feature_list.h"
 #include "base/functional/bind.h"
@@ -44,7 +45,6 @@
 #include "gpu/ipc/service/gpu_channel.h"
 #include "gpu/ipc/service/gpu_channel_manager.h"
 #include "gpu/ipc/service/shared_image_stub.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkColorSpace.h"
 #include "third_party/skia/include/core/SkImage.h"
 #include "third_party/skia/include/core/SkImageInfo.h"
@@ -226,7 +226,7 @@
   }
 
   std::vector<sk_sp<SkImage>> plane_sk_images;
-  absl::optional<base::ScopedClosureRunner> notify_gl_state_changed;
+  std::optional<base::ScopedClosureRunner> notify_gl_state_changed;
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // Right now, we only support YUV 4:2:0 for the output of the decoder (either
   // as YV12 or NV12).
@@ -383,7 +383,7 @@
 
   {
     auto* gr_shader_cache = channel_->gpu_channel_manager()->gr_shader_cache();
-    absl::optional<raster::GrShaderCache::ScopedCacheUse> cache_use;
+    std::optional<raster::GrShaderCache::ScopedCacheUse> cache_use;
     if (gr_shader_cache)
       cache_use.emplace(gr_shader_cache,
                         base::strict_cast<int32_t>(channel_->client_id()));
diff --git a/gpu/vulkan/tests/vulkan_test.cc b/gpu/vulkan/tests/vulkan_test.cc
index 123bc04..b7030cfb 100644
--- a/gpu/vulkan/tests/vulkan_test.cc
+++ b/gpu/vulkan/tests/vulkan_test.cc
@@ -4,6 +4,7 @@
 
 #include <memory>
 
+#include <optional>
 #include "gpu/vulkan/tests/basic_vulkan_test.h"
 #include "gpu/vulkan/vulkan_command_buffer.h"
 #include "gpu/vulkan/vulkan_command_pool.h"
@@ -11,7 +12,6 @@
 #include "gpu/vulkan/vulkan_surface.h"
 #include "gpu/vulkan/vulkan_swap_chain.h"
 #include "gpu/vulkan/vulkan_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // This file tests basic vulkan initialization steps.
 
@@ -45,7 +45,7 @@
 
   constexpr VkSemaphore kNullSemaphore = VK_NULL_HANDLE;
 
-  absl::optional<VulkanSwapChain::ScopedWrite> scoped_write;
+  std::optional<VulkanSwapChain::ScopedWrite> scoped_write;
   scoped_write.emplace(surface->swap_chain());
   EXPECT_TRUE(scoped_write->success());
 
diff --git a/gpu/vulkan/vulkan_image.cc b/gpu/vulkan/vulkan_image.cc
index a0a6dc4..b9a09c5 100644
--- a/gpu/vulkan/vulkan_image.cc
+++ b/gpu/vulkan/vulkan_image.cc
@@ -8,13 +8,13 @@
 
 #include <algorithm>
 
+#include <optional>
 #include "base/logging.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "gpu/vulkan/vulkan_device_queue.h"
 #include "gpu/vulkan/vulkan_function_pointers.h"
 #include "gpu/vulkan/vulkan_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace gpu {
 namespace {
@@ -100,7 +100,7 @@
     VkImageTiling image_tiling,
     VkDeviceSize device_size,
     uint32_t memory_type_index,
-    absl::optional<VulkanYCbCrInfo>& ycbcr_info,
+    std::optional<VulkanYCbCrInfo>& ycbcr_info,
     VkImageUsageFlags usage,
     VkImageCreateFlags flags) {
   auto image = std::make_unique<VulkanImage>(base::PassKey<VulkanImage>());
diff --git a/gpu/vulkan/vulkan_image.h b/gpu/vulkan/vulkan_image.h
index de511af8..631a18691 100644
--- a/gpu/vulkan/vulkan_image.h
+++ b/gpu/vulkan/vulkan_image.h
@@ -10,6 +10,7 @@
 #include <array>
 #include <vector>
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/files/scoped_file.h"
 #include "base/memory/raw_ptr.h"
@@ -17,7 +18,6 @@
 #include "build/build_config.h"
 #include "gpu/ipc/common/vulkan_ycbcr_info.h"
 #include "gpu/vulkan/vulkan_memory.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/gpu_memory_buffer.h"
 #include "ui/gfx/native_pixmap.h"
@@ -83,7 +83,7 @@
       VkImageTiling image_tiling,
       VkDeviceSize device_size,
       uint32_t memory_type_index,
-      absl::optional<VulkanYCbCrInfo>& ycbcr_info,
+      std::optional<VulkanYCbCrInfo>& ycbcr_info,
       VkImageUsageFlags usage,
       VkImageCreateFlags flags);
 
@@ -137,7 +137,7 @@
   VkImageTiling image_tiling() const { return create_info_.tiling; }
   uint32_t queue_family_index() const { return queue_family_index_; }
   void set_queue_family_index(uint32_t index) { queue_family_index_ = index; }
-  const absl::optional<VulkanYCbCrInfo>& ycbcr_info() const {
+  const std::optional<VulkanYCbCrInfo>& ycbcr_info() const {
     return ycbcr_info_;
   }
   VkImage image() const { return image_; }
@@ -213,7 +213,7 @@
   // Image has multi planes and planes are not joint.
   bool disjoint_planes_ = false;
   uint32_t queue_family_index_ = VK_QUEUE_FAMILY_IGNORED;
-  absl::optional<VulkanYCbCrInfo> ycbcr_info_;
+  std::optional<VulkanYCbCrInfo> ycbcr_info_;
   VkImage image_ = VK_NULL_HANDLE;
   // Device memory for each plane.
   std::array<std::unique_ptr<VulkanMemory>, 4> memories_;
diff --git a/gpu/vulkan/vulkan_memory.cc b/gpu/vulkan/vulkan_memory.cc
index 62ed777..785d09da 100644
--- a/gpu/vulkan/vulkan_memory.cc
+++ b/gpu/vulkan/vulkan_memory.cc
@@ -6,16 +6,16 @@
 
 #include <vulkan/vulkan.h>
 
+#include <optional>
 #include "base/logging.h"
 #include "build/build_config.h"
 #include "gpu/vulkan/vulkan_device_queue.h"
 #include "gpu/vulkan/vulkan_function_pointers.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace gpu {
 namespace {
 
-absl::optional<uint32_t> FindMemoryTypeIndex(
+std::optional<uint32_t> FindMemoryTypeIndex(
     VkPhysicalDevice physical_device,
     const VkMemoryRequirements* requirements,
     VkMemoryPropertyFlags flags) {
@@ -32,7 +32,7 @@
     return i;
   }
   NOTREACHED();
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace
diff --git a/gpu/vulkan/vulkan_swap_chain.h b/gpu/vulkan/vulkan_swap_chain.h
index b61d4ca..e957476 100644
--- a/gpu/vulkan/vulkan_swap_chain.h
+++ b/gpu/vulkan/vulkan_swap_chain.h
@@ -10,6 +10,7 @@
 #include <memory>
 #include <vector>
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/containers/circular_deque.h"
 #include "base/functional/callback.h"
@@ -20,7 +21,6 @@
 #include "base/synchronization/lock.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/threading/thread_checker.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/swap_result.h"
@@ -191,7 +191,7 @@
   VkResult state_ GUARDED_BY(lock_) = VK_SUCCESS;
 
   // Acquired images queue.
-  absl::optional<uint32_t> acquired_image_ GUARDED_BY(lock_);
+  std::optional<uint32_t> acquired_image_ GUARDED_BY(lock_);
 
   bool destroy_swapchain_will_hang_ = false;
 
diff --git a/headless/lib/browser/devtools_api/client_api_generator.py b/headless/lib/browser/devtools_api/client_api_generator.py
index 394a96b..f7c91f8 100644
--- a/headless/lib/browser/devtools_api/client_api_generator.py
+++ b/headless/lib/browser/devtools_api/client_api_generator.py
@@ -153,12 +153,12 @@
 
 def CreateObjectTypeDefinition():
   return {
-      'return_type': 'absl::optional<base::Value::Dict>',
-      'pass_type': 'absl::optional<base::Value::Dict>',
+      'return_type': 'std::optional<base::Value::Dict>',
+      'pass_type': 'std::optional<base::Value::Dict>',
       'to_raw_type': '*%s',
       'to_raw_return_type': '*%s',
       'to_pass_type': 'std::move(%s)',
-      'type': 'absl::optional<base::Value::Dict>',
+      'type': 'std::optional<base::Value::Dict>',
       'raw_type': 'base::Value::Dict',
       'raw_pass_type': 'base::Value::Dict*',
       'raw_return_type': 'const base::Value::Dict&',
diff --git a/headless/lib/browser/headless_browser_context_options.cc b/headless/lib/browser/headless_browser_context_options.cc
index 5e4193a..8f56b16 100644
--- a/headless/lib/browser/headless_browser_context_options.cc
+++ b/headless/lib/browser/headless_browser_context_options.cc
@@ -12,7 +12,7 @@
 namespace {
 
 template <class T>
-const T& ReturnOverriddenValue(const absl::optional<T>& value,
+const T& ReturnOverriddenValue(const std::optional<T>& value,
                                const T& default_value) {
   return value ? *value : default_value;
 }
diff --git a/headless/lib/browser/headless_browser_context_options.h b/headless/lib/browser/headless_browser_context_options.h
index 43fbfde3..a9509f04 100644
--- a/headless/lib/browser/headless_browser_context_options.h
+++ b/headless/lib/browser/headless_browser_context_options.h
@@ -7,10 +7,10 @@
 
 #include <string>
 
+#include <optional>
 #include "base/files/file_path.h"
 #include "base/memory/raw_ptr.h"
 #include "headless/public/headless_browser.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/font_render_params.h"
 
 namespace headless {
@@ -61,16 +61,16 @@
 
   raw_ptr<HeadlessBrowser::Options> browser_options_;
 
-  absl::optional<std::string> accept_language_;
-  absl::optional<std::string> user_agent_;
+  std::optional<std::string> accept_language_;
+  std::optional<std::string> user_agent_;
   std::unique_ptr<net::ProxyConfig> proxy_config_;
-  absl::optional<gfx::Size> window_size_;
-  absl::optional<base::FilePath> user_data_dir_;
-  absl::optional<base::FilePath> disk_cache_dir_;
-  absl::optional<bool> incognito_mode_;
-  absl::optional<bool> block_new_web_contents_;
+  std::optional<gfx::Size> window_size_;
+  std::optional<base::FilePath> user_data_dir_;
+  std::optional<base::FilePath> disk_cache_dir_;
+  std::optional<bool> incognito_mode_;
+  std::optional<bool> block_new_web_contents_;
 
-  absl::optional<gfx::FontRenderParams::Hinting> font_render_hinting_;
+  std::optional<gfx::FontRenderParams::Hinting> font_render_hinting_;
 };
 
 }  // namespace headless
diff --git a/headless/lib/browser/headless_browser_impl.cc b/headless/lib/browser/headless_browser_impl.cc
index 2663278..695ef05c 100644
--- a/headless/lib/browser/headless_browser_impl.cc
+++ b/headless/lib/browser/headless_browser_impl.cc
@@ -177,12 +177,12 @@
 
   // Rengenerate the brand version lists with kHeadlessProductName.
   metadata.brand_version_list = embedder_support::GenerateBrandVersionList(
-      seed, kHeadlessProductName, significant_version, absl::nullopt,
-      absl::nullopt, kEnableUpdatedGreaseByPolicy,
+      seed, kHeadlessProductName, significant_version, std::nullopt,
+      std::nullopt, kEnableUpdatedGreaseByPolicy,
       blink::UserAgentBrandVersionType::kMajorVersion);
   metadata.brand_full_version_list = embedder_support::GenerateBrandVersionList(
-      seed, kHeadlessProductName, metadata.full_version, absl::nullopt,
-      absl::nullopt, kEnableUpdatedGreaseByPolicy,
+      seed, kHeadlessProductName, metadata.full_version, std::nullopt,
+      std::nullopt, kEnableUpdatedGreaseByPolicy,
       blink::UserAgentBrandVersionType::kFullVersion);
   return metadata;
 }
diff --git a/headless/lib/browser/headless_browser_impl.h b/headless/lib/browser/headless_browser_impl.h
index 6932f1e5..196933f 100644
--- a/headless/lib/browser/headless_browser_impl.h
+++ b/headless/lib/browser/headless_browser_impl.h
@@ -132,7 +132,7 @@
 #endif
 
   base::OnceCallback<void(HeadlessBrowser*)> on_start_callback_;
-  absl::optional<HeadlessBrowser::Options> options_;
+  std::optional<HeadlessBrowser::Options> options_;
 
   int exit_code_ = 0;
 
diff --git a/headless/lib/browser/headless_content_browser_client.cc b/headless/lib/browser/headless_content_browser_client.cc
index 8d5fc50..db6c42d 100644
--- a/headless/lib/browser/headless_content_browser_client.cc
+++ b/headless/lib/browser/headless_content_browser_client.cc
@@ -345,7 +345,7 @@
 
 #if BUILDFLAG(IS_WIN)
 void HeadlessContentBrowserClient::SessionEnding(
-    absl::optional<DWORD> control_type) {
+    std::optional<DWORD> control_type) {
   DCHECK_LT(control_type.value_or(0), 0x7fu);
   browser_->ShutdownWithExitCode(control_type.value_or(0) + 0x80u);
 }
diff --git a/headless/lib/browser/headless_content_browser_client.h b/headless/lib/browser/headless_content_browser_client.h
index dfdef1b..18f90a11 100644
--- a/headless/lib/browser/headless_content_browser_client.h
+++ b/headless/lib/browser/headless_content_browser_client.h
@@ -95,7 +95,7 @@
   bool CanAcceptUntrustedExchangesIfNeeded() override;
   device::GeolocationManager* GetGeolocationManager() override;
 #if BUILDFLAG(IS_WIN)
-  void SessionEnding(absl::optional<DWORD> control_type) override;
+  void SessionEnding(std::optional<DWORD> control_type) override;
 #endif
 
 #if defined(HEADLESS_USE_POLICY)
diff --git a/headless/lib/browser/headless_window_tree_host.cc b/headless/lib/browser/headless_window_tree_host.cc
index 6ced9c9..fe7614e 100644
--- a/headless/lib/browser/headless_window_tree_host.cc
+++ b/headless/lib/browser/headless_window_tree_host.cc
@@ -79,7 +79,7 @@
 void HeadlessWindowTreeHost::ReleaseCapture() {}
 
 bool HeadlessWindowTreeHost::CaptureSystemKeyEventsImpl(
-    absl::optional<base::flat_set<ui::DomCode>> codes) {
+    std::optional<base::flat_set<ui::DomCode>> codes) {
   return false;
 }
 
diff --git a/headless/lib/browser/headless_window_tree_host.h b/headless/lib/browser/headless_window_tree_host.h
index 6903afc..5096ce6 100644
--- a/headless/lib/browser/headless_window_tree_host.h
+++ b/headless/lib/browser/headless_window_tree_host.h
@@ -53,7 +53,7 @@
   void SetCapture() override;
   void ReleaseCapture() override;
   bool CaptureSystemKeyEventsImpl(
-      absl::optional<base::flat_set<ui::DomCode>> codes) override;
+      std::optional<base::flat_set<ui::DomCode>> codes) override;
   void ReleaseSystemKeyEventCapture() override;
   bool IsKeyLocked(ui::DomCode dom_code) override;
   base::flat_map<std::string, std::string> GetKeyboardLayoutMap() override;
diff --git a/headless/lib/browser/protocol/page_handler.cc b/headless/lib/browser/protocol/page_handler.cc
index 1951561..5e8f696 100644
--- a/headless/lib/browser/protocol/page_handler.cc
+++ b/headless/lib/browser/protocol/page_handler.cc
@@ -8,8 +8,8 @@
 #include "content/public/browser/web_contents.h"
 
 #if BUILDFLAG(ENABLE_PRINTING)
+#include <optional>
 #include "components/printing/browser/print_to_pdf/pdf_print_utils.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #endif
 
 namespace headless {
@@ -17,8 +17,8 @@
 
 #if BUILDFLAG(ENABLE_PRINTING)
 template <typename T>
-absl::optional<T> OptionalFromMaybe(const Maybe<T>& maybe) {
-  return maybe.has_value() ? absl::optional<T>(maybe.value()) : absl::nullopt;
+std::optional<T> OptionalFromMaybe(const Maybe<T>& maybe) {
+  return maybe.has_value() ? std::optional<T>(maybe.value()) : std::nullopt;
 }
 #endif
 
diff --git a/headless/lib/headless_content_main_delegate.cc b/headless/lib/headless_content_main_delegate.cc
index c607d36..f36b434 100644
--- a/headless/lib/headless_content_main_delegate.cc
+++ b/headless/lib/headless_content_main_delegate.cc
@@ -188,7 +188,7 @@
   g_current_headless_content_main_delegate = nullptr;
 }
 
-absl::optional<int> HeadlessContentMainDelegate::BasicStartupComplete() {
+std::optional<int> HeadlessContentMainDelegate::BasicStartupComplete() {
   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
 
   // The DevTools remote debugging pipe file descriptors need to be checked
@@ -240,7 +240,7 @@
 #endif
 
   content::Profiling::ProcessStarted();
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void HeadlessContentMainDelegate::InitLogging(
@@ -462,7 +462,7 @@
   return g_current_headless_content_main_delegate;
 }
 
-absl::optional<int> HeadlessContentMainDelegate::PreBrowserMain() {
+std::optional<int> HeadlessContentMainDelegate::PreBrowserMain() {
   HeadlessBrowser::Options::Builder builder;
 
   if (!HandleCommandLineSwitches(*base::CommandLine::ForCurrentProcess(),
@@ -479,7 +479,7 @@
 #if BUILDFLAG(IS_MAC)
   PlatformPreBrowserMain();
 #endif
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 #if BUILDFLAG(IS_WIN)
@@ -514,10 +514,10 @@
   return utility_client_.get();
 }
 
-absl::optional<int> HeadlessContentMainDelegate::PostEarlyInitialization(
+std::optional<int> HeadlessContentMainDelegate::PostEarlyInitialization(
     InvokedIn invoked_in) {
   if (absl::holds_alternative<InvokedInChildProcess>(invoked_in))
-    return absl::nullopt;
+    return std::nullopt;
 
   if (base::FeatureList::IsEnabled(features::kVirtualTime)) {
     // Only pass viz flags into the virtual time mode.
@@ -543,7 +543,7 @@
       base::CommandLine::ForCurrentProcess()->AppendSwitch(flag);
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace headless
diff --git a/headless/lib/headless_content_main_delegate.h b/headless/lib/headless_content_main_delegate.h
index 2ba4248..ccaf7a3 100644
--- a/headless/lib/headless_content_main_delegate.h
+++ b/headless/lib/headless_content_main_delegate.h
@@ -8,6 +8,7 @@
 #include <memory>
 #include <string>
 
+#include <optional>
 #include "build/build_config.h"
 #include "content/public/app/content_main_delegate.h"
 #include "content/public/browser/content_browser_client.h"
@@ -15,7 +16,6 @@
 #include "headless/lib/headless_content_client.h"
 #include "headless/public/headless_browser.h"
 #include "headless/public/headless_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class CommandLine;
@@ -40,12 +40,12 @@
 
  private:
   // content::ContentMainDelegate implementation:
-  absl::optional<int> BasicStartupComplete() override;
+  std::optional<int> BasicStartupComplete() override;
   void PreSandboxStartup() override;
   absl::variant<int, content::MainFunctionParams> RunProcess(
       const std::string& process_type,
       content::MainFunctionParams main_function_params) override;
-  absl::optional<int> PreBrowserMain() override;
+  std::optional<int> PreBrowserMain() override;
 #if BUILDFLAG(IS_WIN)
   bool ShouldHandleConsoleControlEvents() override;
 #endif
@@ -54,7 +54,7 @@
   content::ContentUtilityClient* CreateContentUtilityClient() override;
   content::ContentRendererClient* CreateContentRendererClient() override;
 
-  absl::optional<int> PostEarlyInitialization(InvokedIn invoked_in) override;
+  std::optional<int> PostEarlyInitialization(InvokedIn invoked_in) override;
 #if BUILDFLAG(IS_MAC)
   void PlatformPreBrowserMain();
 #endif
diff --git a/headless/public/internal/value_conversions.h b/headless/public/internal/value_conversions.h
index 1da0bcc4..48d0401 100644
--- a/headless/public/internal/value_conversions.h
+++ b/headless/public/internal/value_conversions.h
@@ -127,11 +127,11 @@
 
 template <>
 struct FromValue<base::Value::Dict> {
-  static absl::optional<base::Value::Dict> Parse(const base::Value& value,
-                                                 ErrorReporter* errors) {
+  static std::optional<base::Value::Dict> Parse(const base::Value& value,
+                                                ErrorReporter* errors) {
     if (!value.is_dict()) {
       errors->AddError("dictionary value expected");
-      return absl::nullopt;
+      return std::nullopt;
     }
     return value.GetDict().Clone();
   }
diff --git a/headless/test/headless_browser_test_utils.cc b/headless/test/headless_browser_test_utils.cc
index 11b102e..6f6a2c3a 100644
--- a/headless/test/headless_browser_test_utils.cc
+++ b/headless/test/headless_browser_test_utils.cc
@@ -4,6 +4,7 @@
 
 #include "headless/test/headless_browser_test_utils.h"
 
+#include <optional>
 #include "base/functional/bind.h"
 #include "base/json/json_writer.h"
 #include "base/logging.h"
@@ -15,7 +16,6 @@
 #include "headless/lib/browser/headless_web_contents_impl.h"
 #include "headless/public/headless_web_contents.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using simple_devtools_protocol_client::SimpleDevToolsProtocolClient;
 
@@ -100,14 +100,14 @@
 }
 
 int DictInt(const base::Value::Dict& dict, base::StringPiece path) {
-  absl::optional<int> result = dict.FindIntByDottedPath(path);
+  std::optional<int> result = dict.FindIntByDottedPath(path);
   CHECK(result) << "Missing value for '" << path << "' in:\n"
                 << dict.DebugString();
   return *result;
 }
 
 bool DictBool(const base::Value::Dict& dict, base::StringPiece path) {
-  absl::optional<bool> result = dict.FindBoolByDottedPath(path);
+  std::optional<bool> result = dict.FindBoolByDottedPath(path);
   CHECK(result) << "Missing value for '" << path << "' in:\n"
                 << dict.DebugString();
   return *result;
diff --git a/headless/test/headless_browser_user_agent_metadata_browsertest.cc b/headless/test/headless_browser_user_agent_metadata_browsertest.cc
index 1bf2b034..f243cc1 100644
--- a/headless/test/headless_browser_user_agent_metadata_browsertest.cc
+++ b/headless/test/headless_browser_user_agent_metadata_browsertest.cc
@@ -289,7 +289,7 @@
 
   bool IsRequestHeaderSet(
       const std::string header,
-      const absl::optional<std::string> value = absl::nullopt) {
+      const std::optional<std::string> value = std::nullopt) {
     if (!got_headers_.contains(header)) {
       return false;
     }
diff --git a/headless/test/headless_command_browsertest.cc b/headless/test/headless_command_browsertest.cc
index abf0c83..cadf888 100644
--- a/headless/test/headless_command_browsertest.cc
+++ b/headless/test/headless_command_browsertest.cc
@@ -5,6 +5,7 @@
 #include <cmath>
 #include <string>
 
+#include <optional>
 #include "base/command_line.h"
 #include "base/containers/cxx20_erase.h"
 #include "base/files/file_path.h"
@@ -36,7 +37,6 @@
 #include "pdf/buildflags.h"
 #include "printing/buildflags/buildflags.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/display/display_switches.h"
@@ -116,7 +116,7 @@
 
   void set_aborted() { aborted_ = true; }
 
-  absl::optional<HeadlessCommandHandler::Result> result() const {
+  std::optional<HeadlessCommandHandler::Result> result() const {
     return result_;
   }
 
@@ -129,7 +129,7 @@
   }
 
   bool aborted_ = false;
-  absl::optional<HeadlessCommandHandler::Result> result_;
+  std::optional<HeadlessCommandHandler::Result> result_;
 };
 
 class HeadlessFileCommandBrowserTest : public HeadlessCommandBrowserTest {
diff --git a/headless/test/headless_devtools_client_browsertest.cc b/headless/test/headless_devtools_client_browsertest.cc
index 6d953e5..f33a753 100644
--- a/headless/test/headless_devtools_client_browsertest.cc
+++ b/headless/test/headless_devtools_client_browsertest.cc
@@ -590,14 +590,16 @@
 
       // Golden file expects scrollOffsetXY to have fractional part.
       // TODO(kvitekp): Consider updating golden files.
-      if (absl::optional<double> x = node_dict.FindDouble("scrollOffsetX"))
+      if (std::optional<double> x = node_dict.FindDouble("scrollOffsetX")) {
         node_dict.Set("scrollOffsetX", *x);
+      }
 
-      if (absl::optional<double> y = node_dict.FindDouble("scrollOffsetY"))
+      if (std::optional<double> y = node_dict.FindDouble("scrollOffsetY")) {
         node_dict.Set("scrollOffsetY", *y);
+      }
 
       // Merge LayoutTreeNode data into the dom_node dictionary.
-      if (absl::optional<int> layout_node_index =
+      if (std::optional<int> layout_node_index =
               node_dict.FindInt("layoutNodeIndex")) {
         ASSERT_LE(0, *layout_node_index);
         ASSERT_GT(layout_tree_nodes_list->size(),
@@ -617,7 +619,7 @@
           node_dict.Set("layoutText", *layout_text);
         }
 
-        if (absl::optional<int> style_index =
+        if (std::optional<int> style_index =
                 layout_tree_node.FindInt("styleIndex")) {
           node_dict.Set("styleIndex", *style_index);
         }
diff --git a/headless/test/headless_printtopdf_browsertest.cc b/headless/test/headless_printtopdf_browsertest.cc
index b37e5476..8a21ae4 100644
--- a/headless/test/headless_printtopdf_browsertest.cc
+++ b/headless/test/headless_printtopdf_browsertest.cc
@@ -6,6 +6,7 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/base64.h"
 #include "base/command_line.h"
 #include "base/functional/bind.h"
@@ -28,7 +29,6 @@
 #include "printing/units.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/inspector_protocol/crdtp/dispatch.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size_conversions.h"
@@ -96,7 +96,7 @@
         .render_device_type = chrome_pdf::RenderDeviceType::kPrinter,
     };
     for (int i = 0; i < num_pages; i++) {
-      absl::optional<gfx::SizeF> size_in_points =
+      std::optional<gfx::SizeF> size_in_points =
           chrome_pdf::GetPDFPageSizeByIndex(pdf_span, i);
       ASSERT_TRUE(size_in_points.has_value());
       EXPECT_EQ(static_cast<int>(size_in_points.value().width()),
@@ -198,7 +198,7 @@
     EXPECT_TRUE(chrome_pdf::GetPDFDocInfo(pdf_span, &num_pages, nullptr));
     EXPECT_EQ(std::ceil(kDocHeight / kPaperHeight), num_pages);
 
-    absl::optional<bool> tagged = chrome_pdf::IsPDFDocTagged(pdf_span);
+    std::optional<bool> tagged = chrome_pdf::IsPDFDocTagged(pdf_span);
     ASSERT_TRUE(tagged.has_value());
     EXPECT_FALSE(tagged.value());
 
@@ -236,7 +236,7 @@
   }
 
   void OnPDFCreated(base::Value::Dict result) {
-    absl::optional<int> error_code = result.FindIntByDottedPath("error.code");
+    std::optional<int> error_code = result.FindIntByDottedPath("error.code");
     const std::string* error_message =
         result.FindStringByDottedPath("error.message");
     ASSERT_EQ(error_code.has_value(), !!error_message);
@@ -654,7 +654,7 @@
   void OnPDFReady(base::span<const uint8_t> pdf_span, int num_pages) override {
     EXPECT_THAT(num_pages, testing::Eq(1));
 
-    absl::optional<bool> tagged = chrome_pdf::IsPDFDocTagged(pdf_span);
+    std::optional<bool> tagged = chrome_pdf::IsPDFDocTagged(pdf_span);
     ASSERT_THAT(tagged, testing::Optional(true));
 
     constexpr int kFirstPage = 0;
@@ -690,7 +690,7 @@
   void OnPDFReady(base::span<const uint8_t> pdf_span, int num_pages) override {
     EXPECT_THAT(num_pages, testing::Eq(1));
 
-    absl::optional<bool> tagged = chrome_pdf::IsPDFDocTagged(pdf_span);
+    std::optional<bool> tagged = chrome_pdf::IsPDFDocTagged(pdf_span);
     EXPECT_THAT(tagged, testing::Optional(false));
   }
 };
@@ -718,7 +718,7 @@
   void OnPDFReady(base::span<const uint8_t> pdf_span, int num_pages) override {
     EXPECT_THAT(num_pages, testing::Eq(1));
 
-    absl::optional<bool> is_pdf_tagged = chrome_pdf::IsPDFDocTagged(pdf_span);
+    std::optional<bool> is_pdf_tagged = chrome_pdf::IsPDFDocTagged(pdf_span);
     EXPECT_THAT(is_pdf_tagged, testing::Optional(generate_tagged_pdf()));
   }
 };
diff --git a/headless/test/headless_web_contents_browsertest.cc b/headless/test/headless_web_contents_browsertest.cc
index 10ccaf3b..4156f4e0 100644
--- a/headless/test/headless_web_contents_browsertest.cc
+++ b/headless/test/headless_web_contents_browsertest.cc
@@ -6,6 +6,7 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/base64.h"
 #include "base/check_op.h"
 #include "base/command_line.h"
@@ -31,7 +32,6 @@
 #include "headless/test/test_network_interceptor.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/switches.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkColor.h"
diff --git a/headless/test/test_network_interceptor.cc b/headless/test/test_network_interceptor.cc
index 46c4a28..4e2e50e 100644
--- a/headless/test/test_network_interceptor.cc
+++ b/headless/test/test_network_interceptor.cc
@@ -44,7 +44,7 @@
       const std::vector<std::string>& removed_headers,
       const net::HttpRequestHeaders& modified_headers,
       const net::HttpRequestHeaders& modified_cors_exempt_headers,
-      const absl::optional<GURL>& new_url) override;
+      const std::optional<GURL>& new_url) override;
 
   void SetPriority(net::RequestPriority priority,
                    int32_t intra_priority_value) override {}
@@ -132,7 +132,7 @@
     const std::vector<std::string>& removed_headers /* unused */,
     const net::HttpRequestHeaders& modified_headers /* unused */,
     const net::HttpRequestHeaders& modified_cors_exempt_headers /* unused */,
-    const absl::optional<GURL>& new_url) {
+    const std::optional<GURL>& new_url) {
   response_ = interceptor_impl_->FindResponse(method_, url_.spec());
   CHECK(response_) << "No content for " << url_.spec();
   std::string location;
diff --git a/ipc/ipc_channel_mojo.cc b/ipc/ipc_channel_mojo.cc
index b984b1f..7f4f4f9 100644
--- a/ipc/ipc_channel_mojo.cc
+++ b/ipc/ipc_channel_mojo.cc
@@ -312,7 +312,7 @@
 // static
 MojoResult ChannelMojo::ReadFromMessageAttachmentSet(
     Message* message,
-    absl::optional<std::vector<mojo::native::SerializedHandlePtr>>* handles) {
+    std::optional<std::vector<mojo::native::SerializedHandlePtr>>* handles) {
   DCHECK(!*handles);
 
   MojoResult result = MOJO_RESULT_OK;
@@ -341,7 +341,7 @@
 
 // static
 MojoResult ChannelMojo::WriteToMessageAttachmentSet(
-    absl::optional<std::vector<mojo::native::SerializedHandlePtr>> handles,
+    std::optional<std::vector<mojo::native::SerializedHandlePtr>> handles,
     Message* message) {
   if (!handles)
     return MOJO_RESULT_OK;
diff --git a/ipc/ipc_channel_mojo.h b/ipc/ipc_channel_mojo.h
index 2b9c6e3..00a873ff 100644
--- a/ipc/ipc_channel_mojo.h
+++ b/ipc/ipc_channel_mojo.h
@@ -83,11 +83,11 @@
   // These access protected API of IPC::Message, which has ChannelMojo
   // as a friend class.
   static MojoResult WriteToMessageAttachmentSet(
-      absl::optional<std::vector<mojo::native::SerializedHandlePtr>> handles,
+      std::optional<std::vector<mojo::native::SerializedHandlePtr>> handles,
       Message* message);
   static MojoResult ReadFromMessageAttachmentSet(
       Message* message,
-      absl::optional<std::vector<mojo::native::SerializedHandlePtr>>* handles);
+      std::optional<std::vector<mojo::native::SerializedHandlePtr>>* handles);
 
   // MessagePipeReader::Delegate
   void OnPeerPidReceived(int32_t peer_pid) override;
diff --git a/ipc/ipc_channel_mojo_unittest.cc b/ipc/ipc_channel_mojo_unittest.cc
index b1731f3..02c80518 100644
--- a/ipc/ipc_channel_mojo_unittest.cc
+++ b/ipc/ipc_channel_mojo_unittest.cc
@@ -12,6 +12,7 @@
 #include <memory>
 #include <utility>
 
+#include <optional>
 #include "base/base_paths.h"
 #include "base/containers/queue.h"
 #include "base/files/file.h"
@@ -59,7 +60,6 @@
 #include "mojo/public/cpp/system/functions.h"
 #include "mojo/public/cpp/system/wait.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
 #include "base/file_descriptor_posix.h"
@@ -349,8 +349,8 @@
 
   // NOTE: We can't create a RunLoop before Init() is called, but we have to set
   // the default ProcessErrorCallback (which we want to reference the RunLoop)
-  // before Init() launches a child process. Hence the absl::optional here.
-  absl::optional<base::RunLoop> wait_for_error_loop;
+  // before Init() launches a child process. Hence the std::optional here.
+  std::optional<base::RunLoop> wait_for_error_loop;
   bool process_error_received = false;
   mojo::SetDefaultProcessErrorHandler(
       base::BindLambdaForTesting([&](const std::string&) {
diff --git a/ipc/ipc_message_pipe_reader.cc b/ipc/ipc_message_pipe_reader.cc
index 7f30d677a..dc7f480 100644
--- a/ipc/ipc_message_pipe_reader.cc
+++ b/ipc/ipc_message_pipe_reader.cc
@@ -109,7 +109,7 @@
   CHECK(message->IsValid());
   TRACE_EVENT_WITH_FLOW0("toplevel.flow", "MessagePipeReader::Send",
                          message->flags(), TRACE_EVENT_FLAG_FLOW_OUT);
-  absl::optional<std::vector<mojo::native::SerializedHandlePtr>> handles;
+  std::optional<std::vector<mojo::native::SerializedHandlePtr>> handles;
   MojoResult result = MOJO_RESULT_OK;
   result = ChannelMojo::ReadFromMessageAttachmentSet(message.get(), &handles);
   if (result != MOJO_RESULT_OK)
diff --git a/ipc/ipc_message_utils.cc b/ipc/ipc_message_utils.cc
index 81b77d3..c17f4dd 100644
--- a/ipc/ipc_message_utils.cc
+++ b/ipc/ipc_message_utils.cc
@@ -281,7 +281,7 @@
       break;
     }
     case base::Value::Type::BINARY: {
-      absl::optional<base::span<const uint8_t>> data = iter->ReadData();
+      std::optional<base::span<const uint8_t>> data = iter->ReadData();
       if (!data) {
         return false;
       }
@@ -1322,7 +1322,7 @@
   // This is not mapped as nullable_is_same_type, so any UnguessableToken
   // deserialized by the traits should always yield a non-empty token.
   // If deserialization results in an empty token, the data is malformed.
-  absl::optional<base::UnguessableToken> token =
+  std::optional<base::UnguessableToken> token =
       base::UnguessableToken::Deserialize(high, low);
   if (!token.has_value()) {
     return false;
diff --git a/ipc/ipc_message_utils.h b/ipc/ipc_message_utils.h
index a85db9b..8a2de76 100644
--- a/ipc/ipc_message_utils.h
+++ b/ipc/ipc_message_utils.h
@@ -17,6 +17,7 @@
 #include <unordered_map>
 #include <vector>
 
+#include <optional>
 #include "base/check.h"
 #include "base/compiler_specific.h"
 #include "base/component_export.h"
@@ -34,7 +35,6 @@
 #include "ipc/ipc_buildflags.h"
 #include "ipc/ipc_param_traits.h"
 #include "third_party/abseil-cpp/absl/container/inlined_vector.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_ANDROID)
 #include "base/android/scoped_hardware_buffer_handle.h"
@@ -973,8 +973,8 @@
 // absl types ParamTraits
 
 template <class P>
-struct ParamTraits<absl::optional<P>> {
-  typedef absl::optional<P> param_type;
+struct ParamTraits<std::optional<P>> {
+  typedef std::optional<P> param_type;
   static void Write(base::Pickle* m, const param_type& p) {
     const bool is_set = static_cast<bool>(p);
     WriteParam(m, is_set);
diff --git a/ipc/ipc_message_utils_unittest.cc b/ipc/ipc_message_utils_unittest.cc
index 5485c21..ec98f48 100644
--- a/ipc/ipc_message_utils_unittest.cc
+++ b/ipc/ipc_message_utils_unittest.cc
@@ -117,7 +117,7 @@
 }
 
 TEST(IPCMessageUtilsTest, OptionalUnset) {
-  absl::optional<int> opt;
+  std::optional<int> opt;
   base::Pickle pickle;
   IPC::WriteParam(&pickle, opt);
 
@@ -125,14 +125,14 @@
   IPC::LogParam(opt, &log);
   EXPECT_EQ("(unset)", log);
 
-  absl::optional<int> unserialized_opt;
+  std::optional<int> unserialized_opt;
   base::PickleIterator iter(pickle);
   EXPECT_TRUE(IPC::ReadParam(&pickle, &iter, &unserialized_opt));
   EXPECT_FALSE(unserialized_opt);
 }
 
 TEST(IPCMessageUtilsTest, OptionalSet) {
-  absl::optional<int> opt(10);
+  std::optional<int> opt(10);
   base::Pickle pickle;
   IPC::WriteParam(&pickle, opt);
 
@@ -140,7 +140,7 @@
   IPC::LogParam(opt, &log);
   EXPECT_EQ("10", log);
 
-  absl::optional<int> unserialized_opt;
+  std::optional<int> unserialized_opt;
   base::PickleIterator iter(pickle);
   EXPECT_TRUE(IPC::ReadParam(&pickle, &iter, &unserialized_opt));
   EXPECT_TRUE(unserialized_opt);
diff --git a/ipc/ipc_mojo_bootstrap.cc b/ipc/ipc_mojo_bootstrap.cc
index 360901a..c394c62d 100644
--- a/ipc/ipc_mojo_bootstrap.cc
+++ b/ipc/ipc_mojo_bootstrap.cc
@@ -13,6 +13,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/check_op.h"
 #include "base/containers/circular_deque.h"
 #include "base/containers/contains.h"
@@ -50,7 +51,6 @@
 #include "mojo/public/cpp/bindings/sequence_local_sync_event_watcher.h"
 #include "mojo/public/cpp/bindings/tracing_helpers.h"
 #include "third_party/abseil-cpp/absl/base/attributes.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace IPC {
 
@@ -363,7 +363,7 @@
 
   void CloseEndpointHandle(
       mojo::InterfaceId id,
-      const absl::optional<mojo::DisconnectReason>& reason) override {
+      const std::optional<mojo::DisconnectReason>& reason) override {
     if (!mojo::IsValidInterfaceId(id))
       return;
     {
@@ -539,12 +539,12 @@
       handle_created_ = true;
     }
 
-    const absl::optional<mojo::DisconnectReason>& disconnect_reason() const {
+    const std::optional<mojo::DisconnectReason>& disconnect_reason() const {
       return disconnect_reason_;
     }
 
     void set_disconnect_reason(
-        const absl::optional<mojo::DisconnectReason>& disconnect_reason) {
+        const std::optional<mojo::DisconnectReason>& disconnect_reason) {
       disconnect_reason_ = disconnect_reason;
     }
 
@@ -583,11 +583,11 @@
       sync_watcher_.reset();
     }
 
-    absl::optional<uint32_t> EnqueueSyncMessage(MessageWrapper message) {
+    std::optional<uint32_t> EnqueueSyncMessage(MessageWrapper message) {
       controller_->lock_.AssertAcquired();
       if (exclusive_wait_ && exclusive_wait_->TryFulfillingWith(message)) {
         exclusive_wait_ = nullptr;
-        return absl::nullopt;
+        return std::nullopt;
       }
 
       uint32_t id = GenerateSyncMessageId();
@@ -645,7 +645,7 @@
     }
 
     MessageWrapper WaitForIncomingSyncReply(uint64_t request_id) {
-      absl::optional<ExclusiveSyncWait> wait;
+      std::optional<ExclusiveSyncWait> wait;
       {
         base::AutoLock lock(controller_->lock_);
         for (auto& [id, message] : sync_messages_) {
@@ -785,7 +785,7 @@
     bool peer_closed_ = false;
     bool handle_created_ = false;
     bool was_bound_off_sequence_ = false;
-    absl::optional<mojo::DisconnectReason> disconnect_reason_;
+    std::optional<mojo::DisconnectReason> disconnect_reason_;
     raw_ptr<mojo::InterfaceEndpointClient> client_ = nullptr;
     scoped_refptr<base::SequencedTaskRunner> task_runner_;
     std::unique_ptr<mojo::SequenceLocalSyncEventWatcher> sync_watcher_;
@@ -909,7 +909,7 @@
     DCHECK(endpoint->task_runner() && endpoint->client());
     if (endpoint->task_runner()->RunsTasksInCurrentSequence() && !force_async) {
       mojo::InterfaceEndpointClient* client = endpoint->client();
-      absl::optional<mojo::DisconnectReason> reason(
+      std::optional<mojo::DisconnectReason> reason(
           endpoint->disconnect_reason());
 
       base::AutoUnlock unlocker(lock_);
@@ -1051,7 +1051,7 @@
         // sync message queue. If the endpoint was blocking, it will dequeue the
         // message and dispatch it. Otherwise the posted |AcceptSyncMessage()|
         // call will dequeue the message and dispatch it.
-        absl::optional<uint32_t> message_id =
+        std::optional<uint32_t> message_id =
             endpoint->EnqueueSyncMessage(std::move(message_wrapper));
         if (message_id) {
           task_runner->PostTask(
@@ -1189,7 +1189,7 @@
   // mojo::PipeControlMessageHandlerDelegate:
   bool OnPeerAssociatedEndpointClosed(
       mojo::InterfaceId id,
-      const absl::optional<mojo::DisconnectReason>& reason) override {
+      const std::optional<mojo::DisconnectReason>& reason) override {
     DCHECK(thread_checker_.CalledOnValidThread());
 
     scoped_refptr<ChannelAssociatedGroupController> keepalive(this);
diff --git a/ipc/ipc_mojo_bootstrap_unittest.cc b/ipc/ipc_mojo_bootstrap_unittest.cc
index f7bd5f5c..1736067 100644
--- a/ipc/ipc_mojo_bootstrap_unittest.cc
+++ b/ipc/ipc_mojo_bootstrap_unittest.cc
@@ -206,8 +206,8 @@
   auto& sender = connection.GetSender();
 
   uint8_t data = 0;
-  sender->Receive(IPC::MessageView(base::make_span(&data, 0u),
-                                   absl::nullopt /* handles */));
+  sender->Receive(
+      IPC::MessageView(base::make_span(&data, 0u), std::nullopt /* handles */));
 
   base::RunLoop run_loop;
   PeerPidReceiver impl(std::move(receiver), run_loop.QuitClosure());
diff --git a/ipc/message_mojom_traits.cc b/ipc/message_mojom_traits.cc
index 8b94705..5a59b59 100644
--- a/ipc/message_mojom_traits.cc
+++ b/ipc/message_mojom_traits.cc
@@ -14,7 +14,7 @@
 }
 
 // static
-absl::optional<std::vector<mojo::native::SerializedHandlePtr>>
+std::optional<std::vector<mojo::native::SerializedHandlePtr>>
 StructTraits<IPC::mojom::MessageDataView, IPC::MessageView>::handles(
     IPC::MessageView& view) {
   return view.TakeHandles();
@@ -27,7 +27,7 @@
   mojo::ArrayDataView<uint8_t> bytes;
   data.GetBytesDataView(&bytes);
 
-  absl::optional<std::vector<mojo::native::SerializedHandlePtr>> handles;
+  std::optional<std::vector<mojo::native::SerializedHandlePtr>> handles;
   if (!data.ReadHandles(&handles))
     return false;
 
diff --git a/ipc/message_mojom_traits.h b/ipc/message_mojom_traits.h
index 4b5c671..0e71969 100644
--- a/ipc/message_mojom_traits.h
+++ b/ipc/message_mojom_traits.h
@@ -7,12 +7,12 @@
 
 #include <vector>
 
+#include <optional>
 #include "base/containers/span.h"
 #include "ipc/ipc.mojom-shared.h"
 #include "ipc/message_view.h"
 #include "mojo/public/cpp/bindings/struct_traits.h"
 #include "mojo/public/interfaces/bindings/native_struct.mojom.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 
@@ -20,7 +20,7 @@
 class StructTraits<IPC::mojom::MessageDataView, IPC::MessageView> {
  public:
   static base::span<const uint8_t> bytes(IPC::MessageView& view);
-  static absl::optional<std::vector<mojo::native::SerializedHandlePtr>> handles(
+  static std::optional<std::vector<mojo::native::SerializedHandlePtr>> handles(
       IPC::MessageView& view);
 
   static bool Read(IPC::mojom::MessageDataView data, IPC::MessageView* out);
diff --git a/ipc/message_view.cc b/ipc/message_view.cc
index 7cb859a..7b38621 100644
--- a/ipc/message_view.cc
+++ b/ipc/message_view.cc
@@ -12,7 +12,7 @@
 
 MessageView::MessageView(
     base::span<const uint8_t> bytes,
-    absl::optional<std::vector<mojo::native::SerializedHandlePtr>> handles)
+    std::optional<std::vector<mojo::native::SerializedHandlePtr>> handles)
     : bytes_(bytes), handles_(std::move(handles)) {}
 
 MessageView::MessageView(MessageView&&) = default;
@@ -21,7 +21,7 @@
 
 MessageView& MessageView::operator=(MessageView&&) = default;
 
-absl::optional<std::vector<mojo::native::SerializedHandlePtr>>
+std::optional<std::vector<mojo::native::SerializedHandlePtr>>
 MessageView::TakeHandles() {
   return std::move(handles_);
 }
diff --git a/ipc/message_view.h b/ipc/message_view.h
index 55276b9..67f394f8 100644
--- a/ipc/message_view.h
+++ b/ipc/message_view.h
@@ -7,11 +7,11 @@
 
 #include <vector>
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/containers/span.h"
 #include "ipc/ipc_message.h"
 #include "mojo/public/interfaces/bindings/native_struct.mojom-forward.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace IPC {
 
@@ -20,7 +20,7 @@
   MessageView();
   MessageView(
       base::span<const uint8_t> bytes,
-      absl::optional<std::vector<mojo::native::SerializedHandlePtr>> handles);
+      std::optional<std::vector<mojo::native::SerializedHandlePtr>> handles);
   MessageView(MessageView&&);
 
   MessageView(const MessageView&) = delete;
@@ -31,11 +31,11 @@
   MessageView& operator=(MessageView&&);
 
   base::span<const uint8_t> bytes() const { return bytes_; }
-  absl::optional<std::vector<mojo::native::SerializedHandlePtr>> TakeHandles();
+  std::optional<std::vector<mojo::native::SerializedHandlePtr>> TakeHandles();
 
  private:
   base::span<const uint8_t> bytes_;
-  absl::optional<std::vector<mojo::native::SerializedHandlePtr>> handles_;
+  std::optional<std::vector<mojo::native::SerializedHandlePtr>> handles_;
 };
 
 }  // namespace IPC
diff --git a/mojo/core/broker_posix.cc b/mojo/core/broker_posix.cc
index 26c7c2d..98713e4 100644
--- a/mojo/core/broker_posix.cc
+++ b/mojo/core/broker_posix.cc
@@ -133,7 +133,7 @@
     const BufferResponseData* data;
     if (!GetBrokerMessageData(message.get(), &data))
       return base::WritableSharedMemoryRegion();
-    absl::optional<base::UnguessableToken> guid =
+    std::optional<base::UnguessableToken> guid =
         base::UnguessableToken::Deserialize(data->guid_high, data->guid_low);
     if (!guid.has_value()) {
       return base::WritableSharedMemoryRegion();
diff --git a/mojo/core/broker_win.cc b/mojo/core/broker_win.cc
index f9e95020..be287e68 100644
--- a/mojo/core/broker_win.cc
+++ b/mojo/core/broker_win.cc
@@ -150,7 +150,7 @@
     BufferResponseData* data;
     if (!GetBrokerMessageData(response.get(), &data))
       return base::WritableSharedMemoryRegion();
-    absl::optional<base::UnguessableToken> guid =
+    std::optional<base::UnguessableToken> guid =
         base::UnguessableToken::Deserialize(data->guid_high, data->guid_low);
     if (!guid.has_value()) {
       return base::WritableSharedMemoryRegion();
diff --git a/mojo/core/channel_unittest.cc b/mojo/core/channel_unittest.cc
index 6bb1cd3..2384f4b 100644
--- a/mojo/core/channel_unittest.cc
+++ b/mojo/core/channel_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <atomic>
 
+#include <optional>
 #include "base/functional/bind.h"
 #include "base/memory/page_size.h"
 #include "base/memory/ptr_util.h"
@@ -22,7 +23,6 @@
 #include "mojo/public/cpp/platform/platform_channel.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 namespace core {
@@ -320,7 +320,7 @@
 
  private:
   size_t num_messages_ = 0;
-  absl::optional<base::RunLoop> wait_for_error_loop_;
+  std::optional<base::RunLoop> wait_for_error_loop_;
 };
 
 TEST(ChannelTest, RejectHandles) {
diff --git a/mojo/core/core.cc b/mojo/core/core.cc
index f1ec7b9..cca2027 100644
--- a/mojo/core/core.cc
+++ b/mojo/core/core.cc
@@ -1047,7 +1047,7 @@
   if (!handles_ok)
     return MOJO_RESULT_INVALID_ARGUMENT;
 
-  absl::optional<base::UnguessableToken> token =
+  std::optional<base::UnguessableToken> token =
       mojo::internal::PlatformHandleInternal::UnmarshalUnguessableToken(guid);
   if (!token.has_value()) {
     return MOJO_RESULT_INVALID_ARGUMENT;
diff --git a/mojo/core/core_ipcz.cc b/mojo/core/core_ipcz.cc
index 17c02f9..7acd38a1 100644
--- a/mojo/core/core_ipcz.cc
+++ b/mojo/core/core_ipcz.cc
@@ -397,7 +397,7 @@
       config.byte_capacity < config.element_size) {
     return MOJO_RESULT_INVALID_ARGUMENT;
   }
-  absl::optional<DataPipe::Pair> pipe = DataPipe::CreatePair(config);
+  std::optional<DataPipe::Pair> pipe = DataPipe::CreatePair(config);
   if (!pipe) {
     // This result implies that we failed to allocate or map a new shared memory
     // region and therefore have no transfer buffer for the pipe.
diff --git a/mojo/core/data_pipe_consumer_dispatcher.cc b/mojo/core/data_pipe_consumer_dispatcher.cc
index ba0e8eed..2247436 100644
--- a/mojo/core/data_pipe_consumer_dispatcher.cc
+++ b/mojo/core/data_pipe_consumer_dispatcher.cc
@@ -390,7 +390,7 @@
     return nullptr;
   }
 
-  absl::optional<base::UnguessableToken> buffer_guid =
+  std::optional<base::UnguessableToken> buffer_guid =
       base::UnguessableToken::Deserialize(state->buffer_guid_high,
                                           state->buffer_guid_low);
   if (!buffer_guid.has_value()) {
diff --git a/mojo/core/data_pipe_producer_dispatcher.cc b/mojo/core/data_pipe_producer_dispatcher.cc
index 1a54b1a..398db64 100644
--- a/mojo/core/data_pipe_producer_dispatcher.cc
+++ b/mojo/core/data_pipe_producer_dispatcher.cc
@@ -351,7 +351,7 @@
     return nullptr;
   }
 
-  absl::optional<base::UnguessableToken> buffer_guid =
+  std::optional<base::UnguessableToken> buffer_guid =
       base::UnguessableToken::Deserialize(state->buffer_guid_high,
                                           state->buffer_guid_low);
   if (!buffer_guid.has_value()) {
diff --git a/mojo/core/invitation_unittest.cc b/mojo/core/invitation_unittest.cc
index 507de6bc..fab7e00 100644
--- a/mojo/core/invitation_unittest.cc
+++ b/mojo/core/invitation_unittest.cc
@@ -6,6 +6,7 @@
 #include <cstring>
 #include <string>
 
+#include <optional>
 #include "base/base_paths.h"
 #include "base/base_switches.h"
 #include "base/check_op.h"
@@ -42,7 +43,6 @@
 #include "mojo/public/cpp/system/invitation.h"
 #include "mojo/public/cpp/system/message_pipe.h"
 #include "mojo/public/cpp/system/platform_handle.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(MOJO_USE_APPLE_CHANNEL)
 #include "base/mac/mach_port_rendezvous.h"
diff --git a/mojo/core/ipcz_driver/data_pipe.cc b/mojo/core/ipcz_driver/data_pipe.cc
index 62f9196f..a4413a80 100644
--- a/mojo/core/ipcz_driver/data_pipe.cc
+++ b/mojo/core/ipcz_driver/data_pipe.cc
@@ -11,6 +11,7 @@
 #include <limits>
 #include <tuple>
 
+#include <optional>
 #include "base/check.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/unsafe_shared_memory_region.h"
@@ -18,7 +19,6 @@
 #include "base/synchronization/lock.h"
 #include "mojo/core/ipcz_api.h"
 #include "mojo/core/ipcz_driver/ring_buffer.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/ipcz/include/ipcz/ipcz.h"
 
 namespace mojo::core::ipcz_driver {
@@ -140,7 +140,7 @@
 }
 
 // static
-absl::optional<DataPipe::Pair> DataPipe::CreatePair(const Config& config) {
+std::optional<DataPipe::Pair> DataPipe::CreatePair(const Config& config) {
   ScopedIpczHandle producer;
   ScopedIpczHandle consumer;
   const IpczResult result =
@@ -152,12 +152,12 @@
   base::UnsafeSharedMemoryRegion consumer_region =
       base::UnsafeSharedMemoryRegion::Create(config.byte_capacity);
   if (!consumer_region.IsValid()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   base::UnsafeSharedMemoryRegion producer_region = consumer_region.Duplicate();
   if (!producer_region.IsValid()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   scoped_refptr<SharedBuffer> consumer_buffer =
@@ -169,7 +169,7 @@
   auto producer_mapping =
       SharedBufferMapping::Create(producer_buffer->region());
   if (!consumer_mapping || !producer_mapping) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   Pair pair;
diff --git a/mojo/core/ipcz_driver/data_pipe.h b/mojo/core/ipcz_driver/data_pipe.h
index c4a67eb0..389005b 100644
--- a/mojo/core/ipcz_driver/data_pipe.h
+++ b/mojo/core/ipcz_driver/data_pipe.h
@@ -10,6 +10,7 @@
 #include <memory>
 #include <utility>
 
+#include <optional>
 #include "base/containers/span.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/synchronization/lock.h"
@@ -19,7 +20,6 @@
 #include "mojo/core/scoped_ipcz_handle.h"
 #include "mojo/public/c/system/data_pipe.h"
 #include "mojo/public/c/system/types.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/ipcz/include/ipcz/ipcz.h"
 
 namespace mojo::core::ipcz_driver {
@@ -103,7 +103,7 @@
     scoped_refptr<DataPipe> consumer;
     scoped_refptr<DataPipe> producer;
   };
-  static absl::optional<Pair> CreatePair(const Config& config);
+  static std::optional<Pair> CreatePair(const Config& config);
 
   bool is_producer() const { return endpoint_type_ == EndpointType::kProducer; }
   bool is_consumer() const { return endpoint_type_ == EndpointType::kConsumer; }
@@ -181,8 +181,8 @@
   // data pipe endpoint's local cache of the buffer state.
   scoped_refptr<SharedBuffer> buffer_ GUARDED_BY(lock_);
   RingBuffer data_ GUARDED_BY(lock_);
-  absl::optional<RingBuffer::DirectWriter> two_phase_writer_;
-  absl::optional<RingBuffer::DirectReader> two_phase_reader_;
+  std::optional<RingBuffer::DirectWriter> two_phase_writer_;
+  std::optional<RingBuffer::DirectReader> two_phase_reader_;
 
   // Indicates whether this endpoint is in the process of being serialized and
   // transmitted elsewhere.
diff --git a/mojo/core/ipcz_driver/driver_for_ipcz_tests.cc b/mojo/core/ipcz_driver/driver_for_ipcz_tests.cc
index cfe77d73..ba2d6a7 100644
--- a/mojo/core/ipcz_driver/driver_for_ipcz_tests.cc
+++ b/mojo/core/ipcz_driver/driver_for_ipcz_tests.cc
@@ -147,7 +147,7 @@
   const raw_ref<ipcz::test::TestNode> source_;
   const bool is_broker_;
   base::Process process_;
-  absl::optional<bool> result_;
+  std::optional<bool> result_;
 };
 
 // TestDriver implementation for the mojo-ipcz driver to have coverage in ipcz'
diff --git a/mojo/core/ipcz_driver/mojo_trap.cc b/mojo/core/ipcz_driver/mojo_trap.cc
index 7a5765a..1cc82ef 100644
--- a/mojo/core/ipcz_driver/mojo_trap.cc
+++ b/mojo/core/ipcz_driver/mojo_trap.cc
@@ -8,6 +8,7 @@
 #include <tuple>
 #include <utility>
 
+#include <optional>
 #include "base/check_op.h"
 #include "base/memory/ref_counted.h"
 #include "base/notreached.h"
@@ -15,7 +16,6 @@
 #include "base/threading/thread_restrictions.h"
 #include "mojo/core/ipcz_api.h"
 #include "mojo/core/ipcz_driver/data_pipe.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/ipcz/include/ipcz/ipcz.h"
 
 namespace mojo::core::ipcz_driver {
diff --git a/mojo/core/ipcz_driver/mojo_trap.h b/mojo/core/ipcz_driver/mojo_trap.h
index c800fecf..e226ae6 100644
--- a/mojo/core/ipcz_driver/mojo_trap.h
+++ b/mojo/core/ipcz_driver/mojo_trap.h
@@ -7,6 +7,7 @@
 
 #include <cstdint>
 
+#include <optional>
 #include "base/containers/flat_map.h"
 #include "base/containers/span.h"
 #include "base/memory/scoped_refptr.h"
@@ -17,7 +18,6 @@
 #include "mojo/public/c/system/trap.h"
 #include "mojo/public/c/system/types.h"
 #include "third_party/abseil-cpp/absl/container/inlined_vector.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/ipcz/include/ipcz/ipcz.h"
 
 namespace mojo::core::ipcz_driver {
@@ -89,7 +89,7 @@
 
   // A ref identifying the thread which is currently dispatching an event for
   // this trap, if any.
-  absl::optional<base::PlatformThreadRef> dispatching_thread_ GUARDED_BY(lock_);
+  std::optional<base::PlatformThreadRef> dispatching_thread_ GUARDED_BY(lock_);
 
   using TriggerMap = base::flat_map<uintptr_t, scoped_refptr<Trigger>>;
   TriggerMap triggers_ GUARDED_BY(lock_);
diff --git a/mojo/core/ipcz_driver/ring_buffer_test.cc b/mojo/core/ipcz_driver/ring_buffer_test.cc
index 6c91455..2ba6301 100644
--- a/mojo/core/ipcz_driver/ring_buffer_test.cc
+++ b/mojo/core/ipcz_driver/ring_buffer_test.cc
@@ -10,6 +10,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/containers/span.h"
 #include "base/memory/unsafe_shared_memory_region.h"
 #include "base/ranges/algorithm.h"
@@ -17,7 +18,6 @@
 #include "mojo/core/ipcz_driver/shared_buffer.h"
 #include "mojo/core/ipcz_driver/shared_buffer_mapping.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo::core::ipcz_driver {
 namespace {
@@ -53,10 +53,10 @@
     return std::string(AsString(bytes.first(size)));
   }
 
-  absl::optional<std::string> ReadAll(size_t n) {
+  std::optional<std::string> ReadAll(size_t n) {
     std::vector<uint8_t> data(n);
     if (!buffer_.ReadAll(base::make_span(data))) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return std::string(data.begin(), data.end());
   }
@@ -68,10 +68,10 @@
     return std::string(AsString(bytes.first(size)));
   }
 
-  absl::optional<std::string> PeekAll(size_t n) {
+  std::optional<std::string> PeekAll(size_t n) {
     std::vector<uint8_t> data(n);
     if (!buffer_.PeekAll(base::make_span(data))) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return std::string(data.begin(), data.end());
   }
diff --git a/mojo/core/ipcz_driver/shared_buffer.cc b/mojo/core/ipcz_driver/shared_buffer.cc
index 510a7f20..879fafd 100644
--- a/mojo/core/ipcz_driver/shared_buffer.cc
+++ b/mojo/core/ipcz_driver/shared_buffer.cc
@@ -136,7 +136,7 @@
       return nullptr;
   }
 
-  absl::optional<base::UnguessableToken> guid =
+  std::optional<base::UnguessableToken> guid =
       base::UnguessableToken::Deserialize(mojo_guid.high, mojo_guid.low);
   if (!guid.has_value()) {
     return nullptr;
@@ -261,7 +261,7 @@
       return nullptr;
   }
 
-  absl::optional<base::UnguessableToken> guid =
+  std::optional<base::UnguessableToken> guid =
       base::UnguessableToken::Deserialize(header.guid_high, header.guid_low);
   if (!guid.has_value()) {
     return nullptr;
diff --git a/mojo/core/message_pipe_dispatcher.cc b/mojo/core/message_pipe_dispatcher.cc
index 440903b..c74d8b08 100644
--- a/mojo/core/message_pipe_dispatcher.cc
+++ b/mojo/core/message_pipe_dispatcher.cc
@@ -202,7 +202,7 @@
 }
 
 MojoResult MessagePipeDispatcher::SetQuota(MojoQuotaType type, uint64_t limit) {
-  absl::optional<uint64_t> new_ack_request_interval;
+  std::optional<uint64_t> new_ack_request_interval;
   {
     base::AutoLock lock(signal_lock_);
     switch (type) {
diff --git a/mojo/core/message_pipe_dispatcher.h b/mojo/core/message_pipe_dispatcher.h
index 8a9a697..b171331 100644
--- a/mojo/core/message_pipe_dispatcher.h
+++ b/mojo/core/message_pipe_dispatcher.h
@@ -10,12 +10,12 @@
 #include <memory>
 #include <queue>
 
+#include <optional>
 #include "base/memory/raw_ptr_exclusion.h"
 #include "mojo/core/atomic_flag.h"
 #include "mojo/core/dispatcher.h"
 #include "mojo/core/ports/port_ref.h"
 #include "mojo/core/watcher_set.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 namespace core {
@@ -110,9 +110,9 @@
   bool port_transferred_ = false;
   AtomicFlag port_closed_;
   WatcherSet watchers_;
-  absl::optional<uint64_t> receive_queue_length_limit_;
-  absl::optional<uint64_t> receive_queue_memory_size_limit_;
-  absl::optional<uint64_t> unread_message_count_limit_;
+  std::optional<uint64_t> receive_queue_length_limit_;
+  std::optional<uint64_t> receive_queue_memory_size_limit_;
+  std::optional<uint64_t> unread_message_count_limit_;
 };
 
 }  // namespace core
diff --git a/mojo/core/node_controller.cc b/mojo/core/node_controller.cc
index 774a095..568df5a 100644
--- a/mojo/core/node_controller.cc
+++ b/mojo/core/node_controller.cc
@@ -7,6 +7,7 @@
 #include <limits>
 #include <vector>
 
+#include <optional>
 #include "base/containers/contains.h"
 #include "base/containers/queue.h"
 #include "base/functional/bind.h"
@@ -29,7 +30,6 @@
 #include "mojo/public/cpp/platform/named_platform_channel.h"
 #include "mojo/public/cpp/platform/platform_channel.h"
 #include "mojo/public/cpp/platform/platform_channel_server.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_WIN)
 #include <windows.h>
@@ -151,7 +151,7 @@
 };
 
 #if !BUILDFLAG(IS_APPLE) && !BUILDFLAG(IS_NACL) && !BUILDFLAG(IS_FUCHSIA)
-absl::optional<ConnectionParams> CreateSyncNodeConnectionParams(
+std::optional<ConnectionParams> CreateSyncNodeConnectionParams(
     const base::Process& target_process,
     ConnectionParams connection_params,
     const ProcessErrorCallback& process_error_callback,
@@ -172,7 +172,7 @@
   node_connection_params.set_is_untrusted_process(is_untrusted_process);
   if (!broker_host->SendChannel(
           node_channel.TakeRemoteEndpoint().TakePlatformHandle())) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return node_connection_params;
@@ -225,7 +225,7 @@
 
 void NodeController::AcceptBrokerClientInvitation(
     ConnectionParams connection_params) {
-  absl::optional<PlatformHandle> broker_host_handle;
+  std::optional<PlatformHandle> broker_host_handle;
   DCHECK(!GetConfiguration().is_broker_process);
 #if !BUILDFLAG(IS_APPLE) && !BUILDFLAG(IS_NACL) && !BUILDFLAG(IS_FUCHSIA)
   if (!connection_params.is_async()) {
@@ -464,7 +464,7 @@
     }
 #endif
 
-    absl::optional<ConnectionParams> params = CreateSyncNodeConnectionParams(
+    std::optional<ConnectionParams> params = CreateSyncNodeConnectionParams(
         target_process, std::move(connection_params), process_error_callback,
         handle_policy);
     if (!params) {
@@ -514,7 +514,7 @@
 
 void NodeController::AcceptBrokerClientInvitationOnIOThread(
     ConnectionParams connection_params,
-    absl::optional<PlatformHandle> broker_host_handle) {
+    std::optional<PlatformHandle> broker_host_handle) {
   DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
 
   {
diff --git a/mojo/core/node_controller.h b/mojo/core/node_controller.h
index 70a914c..a8b6a8f 100644
--- a/mojo/core/node_controller.h
+++ b/mojo/core/node_controller.h
@@ -13,6 +13,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/containers/queue.h"
 #include "base/containers/span.h"
 #include "base/functional/callback.h"
@@ -29,7 +30,6 @@
 #include "mojo/core/ports/node_delegate.h"
 #include "mojo/core/system_impl_export.h"
 #include "mojo/public/cpp/platform/platform_handle.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 namespace core {
@@ -199,7 +199,7 @@
 
   void AcceptBrokerClientInvitationOnIOThread(
       ConnectionParams connection_params,
-      absl::optional<PlatformHandle> broker_host_handle);
+      std::optional<PlatformHandle> broker_host_handle);
 
   void ConnectIsolatedOnIOThread(ConnectionParams connection_params,
                                  ports::PortRef port,
diff --git a/mojo/core/platform_wrapper_unittest.cc b/mojo/core/platform_wrapper_unittest.cc
index 82372876..34818e6 100644
--- a/mojo/core/platform_wrapper_unittest.cc
+++ b/mojo/core/platform_wrapper_unittest.cc
@@ -202,7 +202,7 @@
   EXPECT_EQ(MOJO_PLATFORM_SHARED_MEMORY_REGION_ACCESS_MODE_UNSAFE, access_mode);
 
   auto mode = base::subtle::PlatformSharedMemoryRegion::Mode::kUnsafe;
-  absl::optional<base::UnguessableToken> guid =
+  std::optional<base::UnguessableToken> guid =
       base::UnguessableToken::Deserialize(mojo_guid.high, mojo_guid.low);
   ASSERT_TRUE(guid.has_value());
 #if BUILDFLAG(IS_WIN)
diff --git a/mojo/core/ports/node.cc b/mojo/core/ports/node.cc
index 224cdfe..4e16b56 100644
--- a/mojo/core/ports/node.cc
+++ b/mojo/core/ports/node.cc
@@ -12,6 +12,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
@@ -23,7 +24,6 @@
 #include "mojo/core/ports/node_delegate.h"
 #include "mojo/core/ports/port_locker.h"
 #include "third_party/abseil-cpp/absl/container/inlined_vector.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if !BUILDFLAG(IS_NACL)
 #include "crypto/random.h"
@@ -1290,7 +1290,7 @@
     PortLocker::AssertNoPortsLockedOnCurrentThread();
     base::ReleasableAutoLock ports_locker(&ports_lock_);
 
-    absl::optional<PortLocker> locker(absl::in_place, port_refs, 2);
+    std::optional<PortLocker> locker(std::in_place, port_refs, 2);
     auto* port0 = locker->GetPort(port0_ref);
     auto* port1 = locker->GetPort(port1_ref);
 
diff --git a/mojo/core/run_all_core_unittests.cc b/mojo/core/run_all_core_unittests.cc
index 03ec406a..e5da67a1 100644
--- a/mojo/core/run_all_core_unittests.cc
+++ b/mojo/core/run_all_core_unittests.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <optional>
 #include "base/base_switches.h"
 #include "base/command_line.h"
 #include "base/files/file_path.h"
@@ -15,7 +16,6 @@
 #include "mojo/core/mojo_core_unittest.h"
 #include "mojo/public/c/system/core.h"
 #include "mojo/public/cpp/system/dynamic_library_support.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 base::FilePath GetMojoCoreLibraryPath() {
 #if BUILDFLAG(IS_FUCHSIA)
@@ -48,7 +48,7 @@
   if (!command_line.HasSwitch(switches::kTestChildProcess))
     flags |= MOJO_INITIALIZE_FLAG_AS_BROKER;
 
-  absl::optional<base::FilePath> library_path;
+  std::optional<base::FilePath> library_path;
   if (command_line.HasSwitch(switches::kMojoUseExplicitLibraryPath))
     library_path = GetMojoCoreLibraryPath();
 
diff --git a/mojo/core/shared_buffer_dispatcher.cc b/mojo/core/shared_buffer_dispatcher.cc
index b1c2777..ab30a68 100644
--- a/mojo/core/shared_buffer_dispatcher.cc
+++ b/mojo/core/shared_buffer_dispatcher.cc
@@ -165,7 +165,7 @@
 #endif
   handles[0] = std::move(platform_handles[0]);
 
-  absl::optional<base::UnguessableToken> guid =
+  std::optional<base::UnguessableToken> guid =
       base::UnguessableToken::Deserialize(serialized_state->guid_high,
                                           serialized_state->guid_low);
   if (!guid.has_value()) {
diff --git a/mojo/core/watcher_set.h b/mojo/core/watcher_set.h
index 9af52e3..890c164 100644
--- a/mojo/core/watcher_set.h
+++ b/mojo/core/watcher_set.h
@@ -5,12 +5,12 @@
 #ifndef MOJO_CORE_WATCHER_SET_H_
 #define MOJO_CORE_WATCHER_SET_H_
 
+#include <optional>
 #include "base/containers/flat_map.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
 #include "mojo/core/handle_signals_state.h"
 #include "mojo/core/watcher_dispatcher.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 namespace core {
@@ -65,7 +65,7 @@
 
   const raw_ptr<Dispatcher> owner_;
   base::flat_map<WatcherDispatcher*, Entry> watchers_;
-  absl::optional<HandleSignalsState> last_known_state_;
+  std::optional<HandleSignalsState> last_known_state_;
 };
 
 }  // namespace core
diff --git a/mojo/public/c/system/thunks.cc b/mojo/public/c/system/thunks.cc
index f0c568e1..30f8f9c 100644
--- a/mojo/public/c/system/thunks.cc
+++ b/mojo/public/c/system/thunks.cc
@@ -25,11 +25,11 @@
 
 #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || \
     BUILDFLAG(IS_FUCHSIA)
+#include <optional>
 #include "base/environment.h"
 #include "base/files/file_path.h"
 #include "base/scoped_native_library.h"
 #include "base/threading/thread_restrictions.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #endif
 
 namespace {
@@ -144,7 +144,7 @@
  private:
 #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || \
     BUILDFLAG(IS_FUCHSIA)
-  absl::optional<base::ScopedNativeLibrary> library_;
+  std::optional<base::ScopedNativeLibrary> library_;
 #endif
 };
 
diff --git a/mojo/public/cpp/base/big_buffer.cc b/mojo/public/cpp/base/big_buffer.cc
index 1e7a98a..e75caae 100644
--- a/mojo/public/cpp/base/big_buffer.cc
+++ b/mojo/public/cpp/base/big_buffer.cc
@@ -42,7 +42,7 @@
 void TryCreateSharedMemory(
     size_t size,
     BigBuffer::StorageType* storage_type,
-    absl::optional<internal::BigBufferSharedMemoryRegion>* shared_memory) {
+    std::optional<internal::BigBufferSharedMemoryRegion>* shared_memory) {
   if (size > BigBuffer::kMaxInlineBytes) {
     auto buffer = mojo::SharedBufferHandle::Create(size);
     if (buffer.is_valid()) {
diff --git a/mojo/public/cpp/base/big_buffer.h b/mojo/public/cpp/base/big_buffer.h
index bac0625..ec6b1cd 100644
--- a/mojo/public/cpp/base/big_buffer.h
+++ b/mojo/public/cpp/base/big_buffer.h
@@ -8,11 +8,11 @@
 #include <cstdint>
 #include <vector>
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/containers/span.h"
 #include "mojo/public/cpp/bindings/struct_traits.h"
 #include "mojo/public/cpp/system/buffer.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo_base {
 
@@ -135,7 +135,7 @@
   StorageType storage_type_;
   std::unique_ptr<uint8_t[]> bytes_;
   size_t bytes_size_;
-  absl::optional<internal::BigBufferSharedMemoryRegion> shared_memory_;
+  std::optional<internal::BigBufferSharedMemoryRegion> shared_memory_;
 };
 
 // Similar to BigBuffer, but doesn't *necessarily* own the buffer storage.
@@ -191,7 +191,7 @@
  private:
   BigBuffer::StorageType storage_type_ = BigBuffer::StorageType::kBytes;
   base::span<const uint8_t> bytes_;
-  absl::optional<internal::BigBufferSharedMemoryRegion> shared_memory_;
+  std::optional<internal::BigBufferSharedMemoryRegion> shared_memory_;
 };
 
 }  // namespace mojo_base
diff --git a/mojo/public/cpp/base/read_only_file_mojom_traits.cc b/mojo/public/cpp/base/read_only_file_mojom_traits.cc
index ccbf555..51aa7cd 100644
--- a/mojo/public/cpp/base/read_only_file_mojom_traits.cc
+++ b/mojo/public/cpp/base/read_only_file_mojom_traits.cc
@@ -29,7 +29,7 @@
 bool IsReadOnlyFile(base::File& file) {
   bool is_readonly = true;
 #if BUILDFLAG(IS_WIN)
-  absl::optional<ACCESS_MASK> flags =
+  std::optional<ACCESS_MASK> flags =
       base::win::GetGrantedAccess(file.GetPlatformFile());
   if (!flags.has_value()) {
     return false;
diff --git a/mojo/public/cpp/base/safe_base_name_unittest.cc b/mojo/public/cpp/base/safe_base_name_unittest.cc
index 939a01d..b1f26ef6 100644
--- a/mojo/public/cpp/base/safe_base_name_unittest.cc
+++ b/mojo/public/cpp/base/safe_base_name_unittest.cc
@@ -10,14 +10,14 @@
 namespace mojo_base {
 
 namespace {
-absl::optional<base::SafeBaseName> CreateSafeBaseName() {
+std::optional<base::SafeBaseName> CreateSafeBaseName() {
   return base::SafeBaseName::Create(base::FilePath());
 }
 }  // namespace
 
 TEST(SafeBaseNameTest, PathEmpty) {
-  absl::optional<base::SafeBaseName> basename = CreateSafeBaseName();
-  absl::optional<base::SafeBaseName> basename_out = CreateSafeBaseName();
+  std::optional<base::SafeBaseName> basename = CreateSafeBaseName();
+  std::optional<base::SafeBaseName> basename_out = CreateSafeBaseName();
 
   ASSERT_TRUE(mojo::test::SerializeAndDeserialize<mojom::SafeBaseName>(
       *basename, *basename_out));
@@ -25,9 +25,9 @@
 }
 
 TEST(SafeBaseNameTest, PathContainsNoSeparators) {
-  absl::optional<base::SafeBaseName> basename(
+  std::optional<base::SafeBaseName> basename(
       base::SafeBaseName::Create(FILE_PATH_LITERAL("hello")));
-  absl::optional<base::SafeBaseName> basename_out = CreateSafeBaseName();
+  std::optional<base::SafeBaseName> basename_out = CreateSafeBaseName();
 
   ASSERT_TRUE(mojo::test::SerializeAndDeserialize<mojom::SafeBaseName>(
       *basename, *basename_out));
@@ -37,8 +37,8 @@
 TEST(SafeBaseNameTest, PathContainsSeparators) {
   base::FilePath file = base::FilePath(FILE_PATH_LITERAL("hello"))
                             .Append(FILE_PATH_LITERAL("world"));
-  absl::optional<base::SafeBaseName> basename(base::SafeBaseName::Create(file));
-  absl::optional<base::SafeBaseName> basename_out = CreateSafeBaseName();
+  std::optional<base::SafeBaseName> basename(base::SafeBaseName::Create(file));
+  std::optional<base::SafeBaseName> basename_out = CreateSafeBaseName();
 
   ASSERT_TRUE(mojo::test::SerializeAndDeserialize<mojom::SafeBaseName>(
       *basename, *basename_out));
@@ -49,8 +49,8 @@
   base::FilePath file = base::FilePath(FILE_PATH_LITERAL("hello"))
                             .Append(FILE_PATH_LITERAL("world"))
                             .AsEndingWithSeparator();
-  absl::optional<base::SafeBaseName> basename(base::SafeBaseName::Create(file));
-  absl::optional<base::SafeBaseName> basename_out = CreateSafeBaseName();
+  std::optional<base::SafeBaseName> basename(base::SafeBaseName::Create(file));
+  std::optional<base::SafeBaseName> basename_out = CreateSafeBaseName();
 
   ASSERT_TRUE(mojo::test::SerializeAndDeserialize<mojom::SafeBaseName>(
       *basename, *basename_out));
@@ -62,7 +62,7 @@
   mojo_base::mojom::SafeBaseNamePtr mojom_basename =
       mojo_base::mojom::SafeBaseName::New();
   mojom_basename->path = base::FilePath(FILE_PATH_LITERAL("C:\\"));
-  absl::optional<base::SafeBaseName> basename_out = CreateSafeBaseName();
+  std::optional<base::SafeBaseName> basename_out = CreateSafeBaseName();
 
   // Expect deserialization to fail because "C:\\ is an absolute path. See
   // safe_base_name.h
@@ -74,7 +74,7 @@
   mojo_base::mojom::SafeBaseNamePtr mojom_basename =
       mojo_base::mojom::SafeBaseName::New();
   mojom_basename->path = base::FilePath(FILE_PATH_LITERAL("/"));
-  absl::optional<base::SafeBaseName> basename_out = CreateSafeBaseName();
+  std::optional<base::SafeBaseName> basename_out = CreateSafeBaseName();
 
   // Expect deserialization to fail because "/" is an absolute path. See
   // safe_base_name.h
@@ -85,9 +85,9 @@
 
 #if defined(FILE_PATH_USES_WIN_SEPARATORS)
 TEST(SafeBaseNameTest, PathIsFileInRootWin) {
-  absl::optional<base::SafeBaseName> basename(
+  std::optional<base::SafeBaseName> basename(
       base::SafeBaseName::Create(FILE_PATH_LITERAL("C:\\foo.txt")));
-  absl::optional<base::SafeBaseName> basename_out = CreateSafeBaseName();
+  std::optional<base::SafeBaseName> basename_out = CreateSafeBaseName();
 
   ASSERT_TRUE(mojo::test::SerializeAndDeserialize<mojom::SafeBaseName>(
       *basename, *basename_out));
diff --git a/mojo/public/cpp/base/unguessable_token_mojom_traits.cc b/mojo/public/cpp/base/unguessable_token_mojom_traits.cc
index ba96eea..ac1abe25 100644
--- a/mojo/public/cpp/base/unguessable_token_mojom_traits.cc
+++ b/mojo/public/cpp/base/unguessable_token_mojom_traits.cc
@@ -17,7 +17,7 @@
   // This is not mapped as nullable_is_same_type, so any UnguessableToken
   // deserialized by the traits should always yield a non-empty token.
   // If deserialization results in an empty token, the data is malformed.
-  absl::optional<base::UnguessableToken> token =
+  std::optional<base::UnguessableToken> token =
       base::UnguessableToken::Deserialize(high, low);
   if (!token.has_value()) {
     return false;
diff --git a/mojo/public/cpp/bindings/associated_group_controller.h b/mojo/public/cpp/bindings/associated_group_controller.h
index bf2f3e79..c42aeb6 100644
--- a/mojo/public/cpp/bindings/associated_group_controller.h
+++ b/mojo/public/cpp/bindings/associated_group_controller.h
@@ -5,13 +5,13 @@
 #ifndef MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_GROUP_CONTROLLER_H_
 #define MOJO_PUBLIC_CPP_BINDINGS_ASSOCIATED_GROUP_CONTROLLER_H_
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/memory/ref_counted.h"
 #include "base/task/sequenced_task_runner.h"
 #include "mojo/public/cpp/bindings/disconnect_reason.h"
 #include "mojo/public/cpp/bindings/interface_id.h"
 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 
@@ -46,7 +46,7 @@
   // Closes an interface endpoint handle.
   virtual void CloseEndpointHandle(
       InterfaceId id,
-      const absl::optional<DisconnectReason>& reason) = 0;
+      const std::optional<DisconnectReason>& reason) = 0;
 
   // Attaches a client to the specified endpoint to send and receive messages.
   // The returned object is still owned by the controller. It must only be used
diff --git a/mojo/public/cpp/bindings/clone_traits.h b/mojo/public/cpp/bindings/clone_traits.h
index 7962ff7b..8e8c5129 100644
--- a/mojo/public/cpp/bindings/clone_traits.h
+++ b/mojo/public/cpp/bindings/clone_traits.h
@@ -9,9 +9,9 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/containers/flat_map.h"
 #include "mojo/public/cpp/bindings/lib/template_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 
@@ -40,12 +40,12 @@
 };
 
 template <typename T>
-struct CloneTraits<absl::optional<T>> {
-  static absl::optional<T> Clone(const absl::optional<T>& input) {
+struct CloneTraits<std::optional<T>> {
+  static std::optional<T> Clone(const std::optional<T>& input) {
     if (!input)
-      return absl::nullopt;
+      return std::nullopt;
 
-    return absl::optional<T>(mojo::Clone(*input));
+    return std::optional<T>(mojo::Clone(*input));
   }
 };
 
diff --git a/mojo/public/cpp/bindings/connector.h b/mojo/public/cpp/bindings/connector.h
index 72f8281b8..e3dd9e21 100644
--- a/mojo/public/cpp/bindings/connector.h
+++ b/mojo/public/cpp/bindings/connector.h
@@ -9,6 +9,7 @@
 #include <memory>
 #include <utility>
 
+#include <optional>
 #include "base/compiler_specific.h"
 #include "base/component_export.h"
 #include "base/functional/callback.h"
@@ -23,7 +24,6 @@
 #include "mojo/public/cpp/system/handle_signal_tracker.h"
 #include "mojo/public/cpp/system/message_pipe.h"
 #include "mojo/public/cpp/system/simple_watcher.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class Lock;
@@ -311,7 +311,7 @@
 
   scoped_refptr<base::SequencedTaskRunner> task_runner_;
   std::unique_ptr<SimpleWatcher> handle_watcher_;
-  absl::optional<HandleSignalTracker> peer_remoteness_tracker_;
+  std::optional<HandleSignalTracker> peer_remoteness_tracker_;
 
   std::atomic<bool> error_;
   bool drop_writes_ = false;
@@ -327,7 +327,7 @@
 
   // If sending messages is allowed from multiple sequences, |lock_| is used to
   // protect modifications to |message_pipe_| and |drop_writes_|.
-  absl::optional<base::Lock> lock_;
+  std::optional<base::Lock> lock_;
 
   std::unique_ptr<SyncHandleWatcher> sync_watcher_;
 
diff --git a/mojo/public/cpp/bindings/enum_utils.h b/mojo/public/cpp/bindings/enum_utils.h
index 1631f94..30172c1 100644
--- a/mojo/public/cpp/bindings/enum_utils.h
+++ b/mojo/public/cpp/bindings/enum_utils.h
@@ -7,21 +7,21 @@
 
 #include <type_traits>
 
+#include <optional>
 #include "base/numerics/safe_conversions.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 
 // Converts |int_value| to |TMojoEnum|.  If |int_value| represents a known enum
 // value, then a corresponding |TMojoEnum| value will be returned.  Returns
-// |absl::nullopt| otherwise.
+// |std::nullopt| otherwise.
 //
 // Using base::StrictNumeric as the parameter type prevents callers from
 // accidentally using an implicit narrowing conversion when calling this
 // function (e.g. calling it with an int64_t argument, when the enum's
 // underlying type is int32_t).
 template <typename TMojoEnum>
-absl::optional<TMojoEnum> ConvertIntToMojoEnum(
+std::optional<TMojoEnum> ConvertIntToMojoEnum(
     base::StrictNumeric<int32_t> int_value) {
   // Today all mojo enums use |int32_t| as the underlying type, so the code
   // can simply use |int32_t| rather than |std::underlying_type_t<TMojoEnum>|.
@@ -56,7 +56,7 @@
   // TMojoEnum and |enum_value|) - we rely on ADL (argument-dependent lookup) to
   // find the right overload below.
   if (!IsKnownEnumValue(enum_value))
-    return absl::nullopt;
+    return std::nullopt;
 
   return enum_value;
 }
diff --git a/mojo/public/cpp/bindings/equals_traits.h b/mojo/public/cpp/bindings/equals_traits.h
index e0f15cd..73877e3 100644
--- a/mojo/public/cpp/bindings/equals_traits.h
+++ b/mojo/public/cpp/bindings/equals_traits.h
@@ -9,9 +9,9 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/containers/flat_map.h"
 #include "mojo/public/cpp/bindings/lib/template_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 
@@ -44,15 +44,15 @@
 };
 
 template <typename T>
-struct EqualsTraits<absl::optional<T>> {
-  static bool Equals(const absl::optional<T>& a, const absl::optional<T>& b) {
+struct EqualsTraits<std::optional<T>> {
+  static bool Equals(const std::optional<T>& a, const std::optional<T>& b) {
     if (!a && !b)
       return true;
     if (!a || !b)
       return false;
 
     // NOTE: Not just Equals() because that's EqualsTraits<>::Equals() and we
-    // want mojo::Equals() for things like absl::optional<std::vector<T>>.
+    // want mojo::Equals() for things like std::optional<std::vector<T>>.
     return mojo::Equals(*a, *b);
   }
 };
diff --git a/mojo/public/cpp/bindings/generic_pending_associated_receiver.h b/mojo/public/cpp/bindings/generic_pending_associated_receiver.h
index 7808d932..ebea14c 100644
--- a/mojo/public/cpp/bindings/generic_pending_associated_receiver.h
+++ b/mojo/public/cpp/bindings/generic_pending_associated_receiver.h
@@ -7,11 +7,11 @@
 
 #include <string>
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/strings/string_piece.h"
 #include "mojo/public/cpp/bindings/pending_associated_receiver.h"
 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 
@@ -54,7 +54,7 @@
 
   void reset();
 
-  const absl::optional<std::string>& interface_name() const {
+  const std::optional<std::string>& interface_name() const {
     return interface_name_;
   }
 
@@ -73,7 +73,7 @@
   mojo::ScopedInterfaceEndpointHandle PassHandleIfNameIs(
       const char* interface_name);
 
-  absl::optional<std::string> interface_name_;
+  std::optional<std::string> interface_name_;
   mojo::ScopedInterfaceEndpointHandle handle_;
 };
 
diff --git a/mojo/public/cpp/bindings/generic_pending_receiver.h b/mojo/public/cpp/bindings/generic_pending_receiver.h
index 985dd72f..1465d03 100644
--- a/mojo/public/cpp/bindings/generic_pending_receiver.h
+++ b/mojo/public/cpp/bindings/generic_pending_receiver.h
@@ -7,11 +7,11 @@
 
 #include <string>
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/strings/string_piece.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/system/message_pipe.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"
 
 namespace mojo {
@@ -47,7 +47,7 @@
 
   void reset();
 
-  const absl::optional<std::string>& interface_name() const {
+  const std::optional<std::string>& interface_name() const {
     return interface_name_;
   }
 
@@ -69,7 +69,7 @@
  private:
   mojo::ScopedMessagePipeHandle PassPipeIfNameIs(const char* interface_name);
 
-  absl::optional<std::string> interface_name_;
+  std::optional<std::string> interface_name_;
   mojo::ScopedMessagePipeHandle pipe_;
 };
 
diff --git a/mojo/public/cpp/bindings/interface_endpoint_client.h b/mojo/public/cpp/bindings/interface_endpoint_client.h
index 6154a68..5abf7b2 100644
--- a/mojo/public/cpp/bindings/interface_endpoint_client.h
+++ b/mojo/public/cpp/bindings/interface_endpoint_client.h
@@ -11,6 +11,7 @@
 #include <memory>
 #include <utility>
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/containers/span.h"
 #include "base/dcheck_is_on.h"
@@ -36,7 +37,6 @@
 #include "mojo/public/cpp/bindings/message_metadata_helpers.h"
 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
 #include "mojo/public/cpp/bindings/thread_safe_proxy.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 
@@ -153,7 +153,7 @@
 
   // NOTE: |message| must have passed message header validation.
   bool HandleIncomingMessage(Message* message);
-  void NotifyError(const absl::optional<DisconnectReason>& reason);
+  void NotifyError(const std::optional<DisconnectReason>& reason);
 
   // The following methods send interface control messages.
   // They must only be called when the handle is not in pending association
@@ -300,11 +300,11 @@
 
   // The timeout to wait for continuous idling before notiftying our peer that
   // we're idle.
-  absl::optional<base::TimeDelta> idle_timeout_;
+  std::optional<base::TimeDelta> idle_timeout_;
 
   // The current idle timer, valid only while we're idle. If this fires, we send
   // a NotifyIdle to our peer.
-  absl::optional<base::OneShotTimer> notify_idle_timer_;
+  std::optional<base::OneShotTimer> notify_idle_timer_;
 
   // A ref to a ConnectionGroup used to track the idle state of this endpoint,
   // if any. Only non-null if an EnableIdleTracking message has been received.
diff --git a/mojo/public/cpp/bindings/lib/connector.cc b/mojo/public/cpp/bindings/lib/connector.cc
index c4d71cb5..f6babc4 100644
--- a/mojo/public/cpp/bindings/lib/connector.cc
+++ b/mojo/public/cpp/bindings/lib/connector.cc
@@ -521,7 +521,7 @@
   }
 
   base::WeakPtr<Connector> weak_self = weak_self_;
-  absl::optional<ActiveDispatchTracker> dispatch_tracker;
+  std::optional<ActiveDispatchTracker> dispatch_tracker;
   if (!is_dispatching_ && nesting_observer_) {
     is_dispatching_ = true;
     dispatch_tracker.emplace(weak_self);
diff --git a/mojo/public/cpp/bindings/lib/hash_util.h b/mojo/public/cpp/bindings/lib/hash_util.h
index 182bfbe..80805da 100644
--- a/mojo/public/cpp/bindings/lib/hash_util.h
+++ b/mojo/public/cpp/bindings/lib/hash_util.h
@@ -10,8 +10,8 @@
 #include <type_traits>
 #include <vector>
 
+#include <optional>
 #include "mojo/public/cpp/bindings/lib/template_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 namespace internal {
@@ -62,8 +62,8 @@
 };
 
 template <typename T>
-struct HashTraits<absl::optional<std::vector<T>>, false> {
-  static size_t Hash(size_t seed, const absl::optional<std::vector<T>>& value) {
+struct HashTraits<std::optional<std::vector<T>>, false> {
+  static size_t Hash(size_t seed, const std::optional<std::vector<T>>& value) {
     if (!value)
       return HashCombine(seed, 0);
 
diff --git a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
index 7e4d699..4608719 100644
--- a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
+++ b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
@@ -8,6 +8,7 @@
 
 #include <tuple>
 
+#include <optional>
 #include "base/check.h"
 #include "base/containers/contains.h"
 #include "base/containers/cxx20_erase.h"
@@ -34,7 +35,6 @@
 #include "mojo/public/cpp/bindings/sync_call_restrictions.h"
 #include "mojo/public/cpp/bindings/sync_event_watcher.h"
 #include "mojo/public/cpp/bindings/thread_safe_proxy.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/perfetto/protos/perfetto/trace/track_event/chrome_mojo_event_info.pbzero.h"
 
 namespace mojo {
@@ -708,7 +708,7 @@
 }
 
 void InterfaceEndpointClient::NotifyError(
-    const absl::optional<DisconnectReason>& reason) {
+    const std::optional<DisconnectReason>& reason) {
   TRACE_EVENT("toplevel", "Closed mojo endpoint",
               [&](perfetto::EventContext& ctx) {
                 auto* info = ctx.event()->set_chrome_mojo_event_info();
@@ -851,7 +851,7 @@
 }
 
 void InterfaceEndpointClient::ForgetAsyncRequest(uint64_t request_id) {
-  absl::optional<PendingAsyncResponse> response;
+  std::optional<PendingAsyncResponse> response;
   {
     base::AutoLock lock(async_responders_lock_);
     auto it = async_responders_.find(request_id);
@@ -914,7 +914,7 @@
                   info->set_ipc_hash((*method_info)());
                   const auto method_address =
                       reinterpret_cast<uintptr_t>(method_info);
-                  const absl::optional<size_t> location_iid =
+                  const std::optional<size_t> location_iid =
                       base::trace_event::InternedUnsymbolizedSourceLocation::
                           Get(&ctx, method_address);
                   if (location_iid) {
@@ -993,7 +993,7 @@
       sync_responses_.erase(it);
     }
 
-    absl::optional<PendingAsyncResponse> pending_response;
+    std::optional<PendingAsyncResponse> pending_response;
     {
       base::AutoLock lock(async_responders_lock_);
       auto it = async_responders_.find(request_id);
diff --git a/mojo/public/cpp/bindings/lib/may_auto_lock.h b/mojo/public/cpp/bindings/lib/may_auto_lock.h
index 63534d8..11be766 100644
--- a/mojo/public/cpp/bindings/lib/may_auto_lock.h
+++ b/mojo/public/cpp/bindings/lib/may_auto_lock.h
@@ -5,10 +5,10 @@
 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_MAY_AUTO_LOCK_H_
 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_MAY_AUTO_LOCK_H_
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/memory/raw_ptr_exclusion.h"
 #include "base/synchronization/lock.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 namespace internal {
@@ -17,7 +17,7 @@
 // the constructor is null.
 class COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) MayAutoLock {
  public:
-  explicit MayAutoLock(absl::optional<base::Lock>* lock)
+  explicit MayAutoLock(std::optional<base::Lock>* lock)
       : lock_(lock->has_value() ? &lock->value() : nullptr) {
     if (lock_)
       lock_->Acquire();
@@ -43,7 +43,7 @@
 // into the constructor is null.
 class COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) MayAutoUnlock {
  public:
-  explicit MayAutoUnlock(absl::optional<base::Lock>* lock)
+  explicit MayAutoUnlock(std::optional<base::Lock>* lock)
       : lock_(lock->has_value() ? &lock->value() : nullptr) {
     if (lock_) {
       lock_->AssertAcquired();
diff --git a/mojo/public/cpp/bindings/lib/message_fragment.h b/mojo/public/cpp/bindings/lib/message_fragment.h
index 5b0809ab..21e59e4 100644
--- a/mojo/public/cpp/bindings/lib/message_fragment.h
+++ b/mojo/public/cpp/bindings/lib/message_fragment.h
@@ -20,7 +20,7 @@
 
 // Sentinel value used to denote an invalid index and thus a null fragment. Note
 // that we choose a sentinel value over something more explicit like
-// absl::optional because this is used heavily in generated code, so code size
+// std::optional because this is used heavily in generated code, so code size
 // is particularly relevant.
 constexpr size_t kInvalidFragmentIndex = std::numeric_limits<size_t>::max();
 
diff --git a/mojo/public/cpp/bindings/lib/multiplex_router.cc b/mojo/public/cpp/bindings/lib/multiplex_router.cc
index ed69861..90913f4 100644
--- a/mojo/public/cpp/bindings/lib/multiplex_router.cc
+++ b/mojo/public/cpp/bindings/lib/multiplex_router.cc
@@ -73,11 +73,11 @@
     handle_created_ = true;
   }
 
-  const absl::optional<DisconnectReason>& disconnect_reason() const {
+  const std::optional<DisconnectReason>& disconnect_reason() const {
     return disconnect_reason_;
   }
   void set_disconnect_reason(
-      const absl::optional<DisconnectReason>& disconnect_reason) {
+      const std::optional<DisconnectReason>& disconnect_reason) {
     router_->AssertLockAcquired();
     disconnect_reason_ = disconnect_reason;
   }
@@ -235,7 +235,7 @@
   // endpoint.
   bool handle_created_;
 
-  absl::optional<DisconnectReason> disconnect_reason_;
+  std::optional<DisconnectReason> disconnect_reason_;
 
   // The task runner on which |client_|'s methods can be called.
   scoped_refptr<base::SequencedTaskRunner> task_runner_;
@@ -493,7 +493,7 @@
 
 void MultiplexRouter::CloseEndpointHandle(
     InterfaceId id,
-    const absl::optional<DisconnectReason>& reason) {
+    const std::optional<DisconnectReason>& reason) {
   if (!IsValidInterfaceId(id))
     return;
 
@@ -742,7 +742,7 @@
 
 bool MultiplexRouter::OnPeerAssociatedEndpointClosed(
     InterfaceId id,
-    const absl::optional<DisconnectReason>& reason) {
+    const std::optional<DisconnectReason>& reason) {
   MayAutoLock locker(&lock_);
   InterfaceEndpoint* endpoint = FindOrInsertEndpoint(id, nullptr);
 
@@ -997,7 +997,7 @@
   DCHECK(endpoint->task_runner()->RunsTasksInCurrentSequence());
 
   InterfaceEndpointClient* client = endpoint->client();
-  absl::optional<DisconnectReason> disconnect_reason(
+  std::optional<DisconnectReason> disconnect_reason(
       endpoint->disconnect_reason());
 
   {
@@ -1237,7 +1237,7 @@
 
     UpdateEndpointStateMayRemove(endpoint, ENDPOINT_CLOSED);
     MayAutoUnlock unlocker(&lock_);
-    control_message_proxy_.NotifyPeerEndpointClosed(ids[i], absl::nullopt);
+    control_message_proxy_.NotifyPeerEndpointClosed(ids[i], std::nullopt);
   }
 
   ProcessTasks(NO_DIRECT_CLIENT_CALLS, nullptr);
diff --git a/mojo/public/cpp/bindings/lib/multiplex_router.h b/mojo/public/cpp/bindings/lib/multiplex_router.h
index 8d66503..d1d0b94 100644
--- a/mojo/public/cpp/bindings/lib/multiplex_router.h
+++ b/mojo/public/cpp/bindings/lib/multiplex_router.h
@@ -10,6 +10,7 @@
 #include <map>
 #include <memory>
 
+#include <optional>
 #include "base/check.h"
 #include "base/component_export.h"
 #include "base/containers/circular_deque.h"
@@ -28,7 +29,6 @@
 #include "mojo/public/cpp/bindings/pipe_control_message_handler_delegate.h"
 #include "mojo/public/cpp/bindings/pipe_control_message_proxy.h"
 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class SequencedTaskRunner;
@@ -131,7 +131,7 @@
       InterfaceId id) override;
   void CloseEndpointHandle(
       InterfaceId id,
-      const absl::optional<DisconnectReason>& reason) override;
+      const std::optional<DisconnectReason>& reason) override;
   InterfaceEndpointController* AttachEndpointClient(
       const ScopedInterfaceEndpointHandle& handle,
       InterfaceEndpointClient* endpoint_client,
@@ -221,7 +221,7 @@
   // PipeControlMessageHandlerDelegate implementation:
   bool OnPeerAssociatedEndpointClosed(
       InterfaceId id,
-      const absl::optional<DisconnectReason>& reason) override;
+      const std::optional<DisconnectReason>& reason) override;
   bool WaitForFlushToComplete(ScopedMessagePipeHandle flush_pipe) override;
 
   void OnPipeConnectionError(bool force_async_dispatch);
@@ -307,7 +307,7 @@
 
   // Active whenever dispatch is blocked by a pending remote flush.
   ScopedMessagePipeHandle active_flush_pipe_;
-  absl::optional<mojo::SimpleWatcher> flush_pipe_watcher_;
+  std::optional<mojo::SimpleWatcher> flush_pipe_watcher_;
 
   // Tracks information about the current exclusive sync wait, if any, on the
   // MultiplexRouter's primary thread. Note that exclusive off-thread sync waits
@@ -317,13 +317,13 @@
     uint64_t request_id = 0;
     bool finished = false;
   };
-  absl::optional<ExclusiveSyncWaitInfo> exclusive_sync_wait_;
+  std::optional<ExclusiveSyncWaitInfo> exclusive_sync_wait_;
 
   SEQUENCE_CHECKER(sequence_checker_);
 
   // Protects the following members.
   // Not set in Config::SINGLE_INTERFACE* mode.
-  mutable absl::optional<base::Lock> lock_;
+  mutable std::optional<base::Lock> lock_;
   PipeControlMessageHandler control_message_handler_;
 
   // NOTE: It is unsafe to call into this object while holding |lock_|.
diff --git a/mojo/public/cpp/bindings/lib/pipe_control_message_handler.cc b/mojo/public/cpp/bindings/lib/pipe_control_message_handler.cc
index 54191c5..9cabdf3a 100644
--- a/mojo/public/cpp/bindings/lib/pipe_control_message_handler.cc
+++ b/mojo/public/cpp/bindings/lib/pipe_control_message_handler.cc
@@ -71,7 +71,7 @@
     const auto& event =
         params_ptr->input->get_peer_associated_endpoint_closed_event();
 
-    absl::optional<DisconnectReason> reason;
+    std::optional<DisconnectReason> reason;
     if (event->disconnect_reason) {
       reason.emplace(event->disconnect_reason->custom_reason,
                      event->disconnect_reason->description);
diff --git a/mojo/public/cpp/bindings/lib/pipe_control_message_proxy.cc b/mojo/public/cpp/bindings/lib/pipe_control_message_proxy.cc
index 42bcf32..b0e9dca0 100644
--- a/mojo/public/cpp/bindings/lib/pipe_control_message_proxy.cc
+++ b/mojo/public/cpp/bindings/lib/pipe_control_message_proxy.cc
@@ -43,7 +43,7 @@
 
 void PipeControlMessageProxy::NotifyPeerEndpointClosed(
     InterfaceId id,
-    const absl::optional<DisconnectReason>& reason) {
+    const std::optional<DisconnectReason>& reason) {
   Message message(ConstructPeerEndpointClosedMessage(id, reason));
   message.set_heap_profiler_tag(kMessageTag);
   std::ignore = receiver_->Accept(&message);
@@ -66,7 +66,7 @@
 // static
 Message PipeControlMessageProxy::ConstructPeerEndpointClosedMessage(
     InterfaceId id,
-    const absl::optional<DisconnectReason>& reason) {
+    const std::optional<DisconnectReason>& reason) {
   auto event = pipe_control::PeerAssociatedEndpointClosedEvent::New();
   event->id = id;
   if (reason) {
diff --git a/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc b/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc
index a6838394..83b15f6b 100644
--- a/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc
+++ b/mojo/public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc
@@ -39,7 +39,7 @@
     peer_state_ = std::move(peer);
   }
 
-  void Close(const absl::optional<DisconnectReason>& reason) {
+  void Close(const std::optional<DisconnectReason>& reason) {
     scoped_refptr<AssociatedGroupController> cached_group_controller;
     InterfaceId cached_id = kInvalidInterfaceId;
     scoped_refptr<State> cached_peer_state;
@@ -164,7 +164,7 @@
     return group_controller_.get();
   }
 
-  const absl::optional<DisconnectReason>& disconnect_reason() const {
+  const std::optional<DisconnectReason>& disconnect_reason() const {
     internal::MayAutoLock locker(&lock_);
     return disconnect_reason_;
   }
@@ -215,7 +215,7 @@
 
   // Called by the peer, maybe from a different sequence.
   void OnPeerClosedBeforeAssociation(
-      const absl::optional<DisconnectReason>& reason) {
+      const std::optional<DisconnectReason>& reason) {
     AssociationEventCallback handler;
     {
       internal::MayAutoLock locker(&lock_);
@@ -269,10 +269,10 @@
 
   // Protects the following members if the handle is initially set to pending
   // association.
-  mutable absl::optional<base::Lock> lock_;
+  mutable std::optional<base::Lock> lock_;
 
   bool pending_association_ = false;
-  absl::optional<DisconnectReason> disconnect_reason_;
+  std::optional<DisconnectReason> disconnect_reason_;
 
   scoped_refptr<State> peer_state_;
 
@@ -308,7 +308,7 @@
 }
 
 ScopedInterfaceEndpointHandle::~ScopedInterfaceEndpointHandle() {
-  state_->Close(absl::nullopt);
+  state_->Close(std::nullopt);
 }
 
 ScopedInterfaceEndpointHandle& ScopedInterfaceEndpointHandle::operator=(
@@ -335,7 +335,7 @@
   return state_->group_controller();
 }
 
-const absl::optional<DisconnectReason>&
+const std::optional<DisconnectReason>&
 ScopedInterfaceEndpointHandle::disconnect_reason() const {
   return state_->disconnect_reason();
 }
@@ -346,7 +346,7 @@
 }
 
 void ScopedInterfaceEndpointHandle::reset() {
-  ResetInternal(absl::nullopt);
+  ResetInternal(std::nullopt);
 }
 
 void ScopedInterfaceEndpointHandle::ResetWithReason(
@@ -369,7 +369,7 @@
 }
 
 void ScopedInterfaceEndpointHandle::ResetInternal(
-    const absl::optional<DisconnectReason>& reason) {
+    const std::optional<DisconnectReason>& reason) {
   auto new_state = base::MakeRefCounted<State>();
   state_->Close(reason);
   state_.swap(new_state);
diff --git a/mojo/public/cpp/bindings/lib/serialization_forward.h b/mojo/public/cpp/bindings/lib/serialization_forward.h
index fac9ba0..ce05a0e 100644
--- a/mojo/public/cpp/bindings/lib/serialization_forward.h
+++ b/mojo/public/cpp/bindings/lib/serialization_forward.h
@@ -7,6 +7,7 @@
 
 #include <type_traits>
 
+#include <optional>
 #include "mojo/public/cpp/bindings/array_traits.h"
 #include "mojo/public/cpp/bindings/enum_traits.h"
 #include "mojo/public/cpp/bindings/lib/buffer.h"
@@ -18,7 +19,6 @@
 #include "mojo/public/cpp/bindings/string_traits.h"
 #include "mojo/public/cpp/bindings/struct_traits.h"
 #include "mojo/public/cpp/bindings/union_traits.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // This file is included by serialization implementation files to avoid circular
 // includes.
@@ -32,7 +32,7 @@
 struct Serializer;
 
 template <typename T>
-using IsAbslOptional = IsSpecializationOf<absl::optional, std::decay_t<T>>;
+using IsAbslOptional = IsSpecializationOf<std::optional, std::decay_t<T>>;
 
 template <typename T>
 using IsOptionalAsPointer =
@@ -61,7 +61,7 @@
 bool Deserialize(DataType&& input, InputUserType* output, Args&&... args) {
   if constexpr (IsAbslOptional<InputUserType>::value) {
     if (!input) {
-      *output = absl::nullopt;
+      *output = std::nullopt;
       return true;
     }
     if (!*output) {
diff --git a/mojo/public/cpp/bindings/optional_as_pointer.h b/mojo/public/cpp/bindings/optional_as_pointer.h
index ebeab30..5263f72 100644
--- a/mojo/public/cpp/bindings/optional_as_pointer.h
+++ b/mojo/public/cpp/bindings/optional_as_pointer.h
@@ -14,15 +14,15 @@
 // Simple wrapper around a pointer to allow zero-copy serialization of a
 // nullable type.
 //
-// Traits for nullable fields typically return `const absl::optional<T>&` or
-// `absl::optional<T>&`. However, if the field is not already an
-// `absl::optional`, this can be inefficient:
+// Traits for nullable fields typically return `const std::optional<T>&` or
+// `std::optional<T>&`. However, if the field is not already an
+// `std::optional`, this can be inefficient:
 //
-//   static absl::optional<std::string> nullable_field_getter(
+//   static std::optional<std::string> nullable_field_getter(
 //       const MyType& input) {
-//     // Bad: copies input.data() to populate `absl::optional`.
-//     return absl::make_optional(
-//         input.has_valid_data() ? input.data() : absl::nullopt);
+//     // Bad: copies input.data() to populate `std::optional`.
+//     return std::make_optional(
+//         input.has_valid_data() ? input.data() : std::nullopt);
 //   }
 //
 // Using this wrapper allows this to be serialized without additional copies:
diff --git a/mojo/public/cpp/bindings/pipe_control_message_handler_delegate.h b/mojo/public/cpp/bindings/pipe_control_message_handler_delegate.h
index 3c99c19..c092414 100644
--- a/mojo/public/cpp/bindings/pipe_control_message_handler_delegate.h
+++ b/mojo/public/cpp/bindings/pipe_control_message_handler_delegate.h
@@ -5,9 +5,9 @@
 #ifndef MOJO_PUBLIC_CPP_BINDINGS_PIPE_CONTROL_MESSAGE_HANDLER_DELEGATE_H_
 #define MOJO_PUBLIC_CPP_BINDINGS_PIPE_CONTROL_MESSAGE_HANDLER_DELEGATE_H_
 
+#include <optional>
 #include "mojo/public/cpp/bindings/disconnect_reason.h"
 #include "mojo/public/cpp/bindings/interface_id.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 
@@ -18,7 +18,7 @@
   // expected to close the message pipe.
   virtual bool OnPeerAssociatedEndpointClosed(
       InterfaceId id,
-      const absl::optional<DisconnectReason>& reason) = 0;
+      const std::optional<DisconnectReason>& reason) = 0;
 
   // The implementation should cease dispatching messages until the
   // |flush_pipe|'s peer is closed.
diff --git a/mojo/public/cpp/bindings/pipe_control_message_proxy.h b/mojo/public/cpp/bindings/pipe_control_message_proxy.h
index 66d2f1d..3266cf1 100644
--- a/mojo/public/cpp/bindings/pipe_control_message_proxy.h
+++ b/mojo/public/cpp/bindings/pipe_control_message_proxy.h
@@ -5,6 +5,7 @@
 #ifndef MOJO_PUBLIC_CPP_BINDINGS_PIPE_CONTROL_MESSAGE_PROXY_H_
 #define MOJO_PUBLIC_CPP_BINDINGS_PIPE_CONTROL_MESSAGE_PROXY_H_
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/memory/raw_ptr.h"
 #include "mojo/public/cpp/bindings/async_flusher.h"
@@ -12,7 +13,6 @@
 #include "mojo/public/cpp/bindings/interface_id.h"
 #include "mojo/public/cpp/bindings/message.h"
 #include "mojo/public/cpp/bindings/pending_flush.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 
@@ -31,13 +31,13 @@
   PipeControlMessageProxy& operator=(const PipeControlMessageProxy&) = delete;
 
   void NotifyPeerEndpointClosed(InterfaceId id,
-                                const absl::optional<DisconnectReason>& reason);
+                                const std::optional<DisconnectReason>& reason);
   void PausePeerUntilFlushCompletes(PendingFlush flush);
   void FlushAsync(AsyncFlusher flusher);
 
   static Message ConstructPeerEndpointClosedMessage(
       InterfaceId id,
-      const absl::optional<DisconnectReason>& reason);
+      const std::optional<DisconnectReason>& reason);
 
  private:
   // Not owned.
diff --git a/mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h b/mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h
index 9acfe5275..3939c20 100644
--- a/mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h
+++ b/mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h
@@ -5,13 +5,13 @@
 #ifndef MOJO_PUBLIC_CPP_BINDINGS_SCOPED_INTERFACE_ENDPOINT_HANDLE_H_
 #define MOJO_PUBLIC_CPP_BINDINGS_SCOPED_INTERFACE_ENDPOINT_HANDLE_H_
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/functional/callback.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/strings/string_piece.h"
 #include "mojo/public/cpp/bindings/disconnect_reason.h"
 #include "mojo/public/cpp/bindings/interface_id.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 
@@ -57,7 +57,7 @@
 
   // Returns the disconnect reason if the peer handle is closed before
   // association and specifies a custom disconnect reason.
-  const absl::optional<DisconnectReason>& disconnect_reason() const;
+  const std::optional<DisconnectReason>& disconnect_reason() const;
 
   enum AssociationEvent {
     // The interface has been associated with a message pipe.
@@ -95,7 +95,7 @@
       InterfaceId id,
       scoped_refptr<AssociatedGroupController> peer_group_controller);
 
-  void ResetInternal(const absl::optional<DisconnectReason>& reason);
+  void ResetInternal(const std::optional<DisconnectReason>& reason);
 
   // Used by AssociatedGroup.
   // It is safe to run the returned callback on any sequence, or after this
diff --git a/mojo/public/cpp/bindings/struct_ptr.h b/mojo/public/cpp/bindings/struct_ptr.h
index f31236f..f3c1278 100644
--- a/mojo/public/cpp/bindings/struct_ptr.h
+++ b/mojo/public/cpp/bindings/struct_ptr.h
@@ -60,7 +60,7 @@
   }
 
   template <typename... Args>
-  StructPtr(absl::in_place_t, Args&&... args)
+  StructPtr(std::in_place_t, Args&&... args)
       : ptr_(new Struct(std::forward<Args>(args)...)) {}
 
   template <typename U>
@@ -159,7 +159,7 @@
   }
 
   template <typename... Args>
-  InlinedStructPtr(absl::in_place_t, Args&&... args)
+  InlinedStructPtr(std::in_place_t, Args&&... args)
       : value_(std::forward<Args>(args)...), state_(VALID) {}
 
   template <typename U>
diff --git a/mojo/public/cpp/bindings/struct_traits.h b/mojo/public/cpp/bindings/struct_traits.h
index e319728..13e5e86 100644
--- a/mojo/public/cpp/bindings/struct_traits.h
+++ b/mojo/public/cpp/bindings/struct_traits.h
@@ -49,7 +49,7 @@
 //          Value of any type that has an EnumTraits defined.
 //
 //      For any nullable string/struct/array/map/union field you could also
-//      return value or reference of absl::optional<T>, if T has the right
+//      return value or reference of std::optional<T>, if T has the right
 //      *Traits defined.
 //
 //      During serialization, getters for all fields are called exactly once. It
diff --git a/mojo/public/cpp/bindings/tests/connection_group_unittest.cc b/mojo/public/cpp/bindings/tests/connection_group_unittest.cc
index d97348f..11b5ad1b 100644
--- a/mojo/public/cpp/bindings/tests/connection_group_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/connection_group_unittest.cc
@@ -169,7 +169,7 @@
 }
 
 TEST_F(ConnectionGroupTest, NotifyOnDecrementToZeroMultipleTimes) {
-  absl::optional<base::RunLoop> loop;
+  std::optional<base::RunLoop> loop;
   ConnectionGroup::Ref ref =
       ConnectionGroup::Create(base::BindLambdaForTesting([&] {
                                 ASSERT_TRUE(loop.has_value());
diff --git a/mojo/public/cpp/bindings/tests/default_construct_unittest.cc b/mojo/public/cpp/bindings/tests/default_construct_unittest.cc
index e8ec529..f676c74 100644
--- a/mojo/public/cpp/bindings/tests/default_construct_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/default_construct_unittest.cc
@@ -125,7 +125,7 @@
 
 TEST(DefaultConstructOptionalTest, InitializedToNullopt) {
   auto container = mojom::OptionalTestStructContainer::New();
-  EXPECT_EQ(absl::nullopt, container->test_struct);
+  EXPECT_EQ(std::nullopt, container->test_struct);
 }
 
 }  // namespace mojo::test::default_construct
diff --git a/mojo/public/cpp/bindings/tests/equals_unittest.cc b/mojo/public/cpp/bindings/tests/equals_unittest.cc
index 963aac2..42ed5f8 100644
--- a/mojo/public/cpp/bindings/tests/equals_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/equals_unittest.cc
@@ -58,7 +58,7 @@
   NamedRegionPtr n2(n1.Clone());
   EXPECT_TRUE(n1.Equals(n2));
 
-  n2->rects = absl::nullopt;
+  n2->rects = std::nullopt;
   EXPECT_FALSE(n1.Equals(n2));
   n2->rects.emplace();
   EXPECT_FALSE(n1.Equals(n2));
diff --git a/mojo/public/cpp/bindings/tests/flush_async_unittest.cc b/mojo/public/cpp/bindings/tests/flush_async_unittest.cc
index 87f8480..d0a8370 100644
--- a/mojo/public/cpp/bindings/tests/flush_async_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/flush_async_unittest.cc
@@ -6,6 +6,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/barrier_closure.h"
 #include "base/containers/flat_map.h"
 #include "base/functional/bind.h"
@@ -25,7 +26,6 @@
 #include "mojo/public/cpp/bindings/tests/bindings_test_base.h"
 #include "mojo/public/cpp/bindings/tests/flush_async_unittest.test-mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 namespace test {
@@ -262,7 +262,7 @@
   // corresponding AsyncFlusher. The call should eventually execute.
   base::RunLoop loop;
   base::flat_map<std::string, std::string> snapshot;
-  absl::optional<AsyncFlusher> flusher(absl::in_place);
+  std::optional<AsyncFlusher> flusher(std::in_place);
   key_value_store().PauseReceiverUntilFlushCompletes(
       PendingFlush(&flusher.value()));
   key_value_store()->GetSnapshot(base::BindLambdaForTesting(
@@ -300,7 +300,7 @@
   Remote<mojom::Pinger> pinger;
   PingerImpl impl(pinger.BindNewPipeAndPassReceiver());
 
-  absl::optional<AsyncFlusher> flusher(absl::in_place);
+  std::optional<AsyncFlusher> flusher(std::in_place);
   PendingFlush flush(&flusher.value());
   pinger.PauseReceiverUntilFlushCompletes(std::move(flush));
 
@@ -344,7 +344,7 @@
   Remote<mojom::Pinger> pinger;
   PingerImpl impl(pinger.BindNewPipeAndPassReceiver());
 
-  absl::optional<AsyncFlusher> flusher(absl::in_place);
+  std::optional<AsyncFlusher> flusher(std::in_place);
   PendingFlush flush(&flusher.value());
   pinger.PauseReceiverUntilFlushCompletes(std::move(flush));
 
diff --git a/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc b/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc
index 343a634..7fba344 100644
--- a/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/handle_passing_unittest.cc
@@ -212,7 +212,7 @@
                                       run_loop.QuitClosure());
 
   sample::RequestPtr request(sample::Request::New(
-      1, std::move(pipe1.handle0), absl::nullopt, std::move(imported)));
+      1, std::move(pipe1.handle0), std::nullopt, std::move(imported)));
   bool got_response = false;
   std::string got_text_reply;
   base::RunLoop run_loop2;
@@ -236,7 +236,7 @@
   SampleFactoryImpl factory_impl(factory.BindNewPipeAndPassReceiver());
 
   sample::RequestPtr request(sample::Request::New(1, ScopedMessagePipeHandle(),
-                                                  absl::nullopt, NullRemote()));
+                                                  std::nullopt, NullRemote()));
 
   bool got_response = false;
   std::string got_text_reply;
diff --git a/mojo/public/cpp/bindings/tests/new_endpoint_types_unittest.cc b/mojo/public/cpp/bindings/tests/new_endpoint_types_unittest.cc
index e15179755..dab12f6 100644
--- a/mojo/public/cpp/bindings/tests/new_endpoint_types_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/new_endpoint_types_unittest.cc
@@ -7,6 +7,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "base/run_loop.h"
@@ -19,7 +20,6 @@
 #include "mojo/public/cpp/bindings/unique_receiver_set.h"
 #include "mojo/public/interfaces/bindings/tests/new_endpoint_types.test-mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 namespace test {
diff --git a/mojo/public/cpp/bindings/tests/nullable_value_types_unittest.cc b/mojo/public/cpp/bindings/tests/nullable_value_types_unittest.cc
index dadecde..39ddfc4 100644
--- a/mojo/public/cpp/bindings/tests/nullable_value_types_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/nullable_value_types_unittest.cc
@@ -4,6 +4,7 @@
 
 #include <utility>
 
+#include <optional>
 #include "base/test/bind.h"
 #include "base/test/task_environment.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -13,7 +14,6 @@
 #include "mojo/public/cpp/test_support/test_utils.h"
 #include "mojo/public/interfaces/bindings/tests/nullable_value_types.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo::test::nullable_value_types {
 namespace {
@@ -30,20 +30,20 @@
     TypemappedEnum::kValueOne;
 
 template <typename T>
-std::pair<bool, T> FromOpt(const absl::optional<T>& opt) {
+std::pair<bool, T> FromOpt(const std::optional<T>& opt) {
   return opt.has_value() ? std::pair(true, opt.value())
                          : std::pair(false, kDefaultValue<T>);
 }
 
 template <typename T>
-absl::optional<T> ToOpt(bool has_value, T value) {
-  return has_value ? absl::make_optional(value) : absl::nullopt;
+std::optional<T> ToOpt(bool has_value, T value) {
+  return has_value ? std::make_optional(value) : std::nullopt;
 }
 
-absl::optional<mojom::RegularEnum> Transform(
-    absl::optional<mojom::RegularEnum> in) {
+std::optional<mojom::RegularEnum> Transform(
+    std::optional<mojom::RegularEnum> in) {
   if (!in.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   switch (in.value()) {
     case mojom::RegularEnum::kThisValue:
@@ -53,9 +53,9 @@
   }
 }
 
-absl::optional<TypemappedEnum> Transform(absl::optional<TypemappedEnum> in) {
+std::optional<TypemappedEnum> Transform(std::optional<TypemappedEnum> in) {
   if (!in.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   switch (in.value()) {
     case TypemappedEnum::kValueOne:
@@ -65,79 +65,79 @@
   }
 }
 
-absl::optional<bool> Transform(absl::optional<bool> in) {
+std::optional<bool> Transform(std::optional<bool> in) {
   if (!in.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return !in.value();
 }
 
-absl::optional<uint8_t> Transform(absl::optional<uint8_t> in) {
+std::optional<uint8_t> Transform(std::optional<uint8_t> in) {
   if (!in.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return ~in.value();
 }
 
-absl::optional<uint16_t> Transform(absl::optional<uint16_t> in) {
+std::optional<uint16_t> Transform(std::optional<uint16_t> in) {
   if (!in.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return ~in.value();
 }
 
-absl::optional<uint32_t> Transform(absl::optional<uint32_t> in) {
+std::optional<uint32_t> Transform(std::optional<uint32_t> in) {
   if (!in.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return ~in.value();
 }
 
-absl::optional<uint64_t> Transform(absl::optional<uint64_t> in) {
+std::optional<uint64_t> Transform(std::optional<uint64_t> in) {
   if (!in.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return ~in.value();
 }
 
-absl::optional<int8_t> Transform(absl::optional<int8_t> in) {
+std::optional<int8_t> Transform(std::optional<int8_t> in) {
   if (!in.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return -in.value();
 }
 
-absl::optional<int16_t> Transform(absl::optional<int16_t> in) {
+std::optional<int16_t> Transform(std::optional<int16_t> in) {
   if (!in.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return -in.value();
 }
 
-absl::optional<int32_t> Transform(absl::optional<int32_t> in) {
+std::optional<int32_t> Transform(std::optional<int32_t> in) {
   if (!in.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return -in.value();
 }
 
-absl::optional<int64_t> Transform(absl::optional<int64_t> in) {
+std::optional<int64_t> Transform(std::optional<int64_t> in) {
   if (!in.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return -in.value();
 }
 
-absl::optional<float> Transform(absl::optional<float> in) {
+std::optional<float> Transform(std::optional<float> in) {
   if (!in.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return -2 * in.value();
 }
 
-absl::optional<double> Transform(absl::optional<double> in) {
+std::optional<double> Transform(std::optional<double> in) {
   if (!in.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return -2 * in.value();
 }
@@ -285,13 +285,13 @@
  public:
   explicit InterfaceV2Impl(
       PendingReceiver<mojom::InterfaceV2> receiver,
-      absl::optional<CallerVersion> caller_version = absl::nullopt)
+      std::optional<CallerVersion> caller_version = std::nullopt)
       : receiver_(this, std::move(receiver)), caller_version_(caller_version) {}
 
  private:
   // mojom::InterfaceV2 implementation:
-  void MethodWithEnums(absl::optional<mojom::RegularEnum> enum_value,
-                       absl::optional<TypemappedEnum> mapped_enum_value,
+  void MethodWithEnums(std::optional<mojom::RegularEnum> enum_value,
+                       std::optional<TypemappedEnum> mapped_enum_value,
                        MethodWithEnumsCallback callback) override {
     std::move(callback).Run(Transform(enum_value),
                             Transform(mapped_enum_value));
@@ -304,17 +304,17 @@
         Transform(in->enum_value), Transform(in->mapped_enum_value)));
   }
 
-  void MethodWithNumerics(absl::optional<bool> bool_value,
-                          absl::optional<uint8_t> u8_value,
-                          absl::optional<uint16_t> u16_value,
-                          absl::optional<uint32_t> u32_value,
-                          absl::optional<uint64_t> u64_value,
-                          absl::optional<int8_t> i8_value,
-                          absl::optional<int16_t> i16_value,
-                          absl::optional<int32_t> i32_value,
-                          absl::optional<int64_t> i64_value,
-                          absl::optional<float> float_value,
-                          absl::optional<double> double_value,
+  void MethodWithNumerics(std::optional<bool> bool_value,
+                          std::optional<uint8_t> u8_value,
+                          std::optional<uint16_t> u16_value,
+                          std::optional<uint32_t> u32_value,
+                          std::optional<uint64_t> u64_value,
+                          std::optional<int8_t> i8_value,
+                          std::optional<int16_t> i16_value,
+                          std::optional<int32_t> i32_value,
+                          std::optional<int64_t> i64_value,
+                          std::optional<float> float_value,
+                          std::optional<double> double_value,
                           MethodWithNumericsCallback callback) override {
     std::move(callback).Run(
         Transform(bool_value), Transform(u8_value), Transform(u16_value),
@@ -336,37 +336,37 @@
   }
 
   void MethodWithVersionedArgs(
-      absl::optional<bool> bool_value,
-      absl::optional<uint8_t> u8_value,
-      absl::optional<uint16_t> u16_value,
-      absl::optional<uint32_t> u32_value,
-      absl::optional<uint64_t> u64_value,
-      absl::optional<int8_t> i8_value,
-      absl::optional<int16_t> i16_value,
-      absl::optional<int32_t> i32_value,
-      absl::optional<int64_t> i64_value,
-      absl::optional<float> float_value,
-      absl::optional<double> double_value,
-      absl::optional<mojom::RegularEnum> enum_value,
-      absl::optional<TypemappedEnum> mapped_enum_value,
+      std::optional<bool> bool_value,
+      std::optional<uint8_t> u8_value,
+      std::optional<uint16_t> u16_value,
+      std::optional<uint32_t> u32_value,
+      std::optional<uint64_t> u64_value,
+      std::optional<int8_t> i8_value,
+      std::optional<int16_t> i16_value,
+      std::optional<int32_t> i32_value,
+      std::optional<int64_t> i64_value,
+      std::optional<float> float_value,
+      std::optional<double> double_value,
+      std::optional<mojom::RegularEnum> enum_value,
+      std::optional<TypemappedEnum> mapped_enum_value,
       MethodWithVersionedArgsCallback callback) override {
     switch (*caller_version_) {
       case CallerVersion::kV1:
         // A caller using the V1 interface will not know about the new
-        // arguments, so they should all equal absl::nullopt.
-        EXPECT_EQ(absl::nullopt, bool_value);
-        EXPECT_EQ(absl::nullopt, u8_value);
-        EXPECT_EQ(absl::nullopt, u16_value);
-        EXPECT_EQ(absl::nullopt, u32_value);
-        EXPECT_EQ(absl::nullopt, u64_value);
-        EXPECT_EQ(absl::nullopt, i8_value);
-        EXPECT_EQ(absl::nullopt, i16_value);
-        EXPECT_EQ(absl::nullopt, i32_value);
-        EXPECT_EQ(absl::nullopt, i64_value);
-        EXPECT_EQ(absl::nullopt, float_value);
-        EXPECT_EQ(absl::nullopt, double_value);
-        EXPECT_EQ(absl::nullopt, enum_value);
-        EXPECT_EQ(absl::nullopt, mapped_enum_value);
+        // arguments, so they should all equal std::nullopt.
+        EXPECT_EQ(std::nullopt, bool_value);
+        EXPECT_EQ(std::nullopt, u8_value);
+        EXPECT_EQ(std::nullopt, u16_value);
+        EXPECT_EQ(std::nullopt, u32_value);
+        EXPECT_EQ(std::nullopt, u64_value);
+        EXPECT_EQ(std::nullopt, i8_value);
+        EXPECT_EQ(std::nullopt, i16_value);
+        EXPECT_EQ(std::nullopt, i32_value);
+        EXPECT_EQ(std::nullopt, i64_value);
+        EXPECT_EQ(std::nullopt, float_value);
+        EXPECT_EQ(std::nullopt, double_value);
+        EXPECT_EQ(std::nullopt, enum_value);
+        EXPECT_EQ(std::nullopt, mapped_enum_value);
         break;
       case CallerVersion::kV2:
         EXPECT_EQ(true, bool_value);
@@ -396,20 +396,20 @@
     switch (*caller_version_) {
       case CallerVersion::kV1:
         // A caller using the V1 interface will not know about the new
-        // arguments, so they should all equal absl::nullopt.
-        EXPECT_EQ(absl::nullopt, in->bool_value);
-        EXPECT_EQ(absl::nullopt, in->u8_value);
-        EXPECT_EQ(absl::nullopt, in->u16_value);
-        EXPECT_EQ(absl::nullopt, in->u32_value);
-        EXPECT_EQ(absl::nullopt, in->u64_value);
-        EXPECT_EQ(absl::nullopt, in->i8_value);
-        EXPECT_EQ(absl::nullopt, in->i16_value);
-        EXPECT_EQ(absl::nullopt, in->i32_value);
-        EXPECT_EQ(absl::nullopt, in->i64_value);
-        EXPECT_EQ(absl::nullopt, in->float_value);
-        EXPECT_EQ(absl::nullopt, in->double_value);
-        EXPECT_EQ(absl::nullopt, in->enum_value);
-        EXPECT_EQ(absl::nullopt, in->mapped_enum_value);
+        // arguments, so they should all equal std::nullopt.
+        EXPECT_EQ(std::nullopt, in->bool_value);
+        EXPECT_EQ(std::nullopt, in->u8_value);
+        EXPECT_EQ(std::nullopt, in->u16_value);
+        EXPECT_EQ(std::nullopt, in->u32_value);
+        EXPECT_EQ(std::nullopt, in->u64_value);
+        EXPECT_EQ(std::nullopt, in->i8_value);
+        EXPECT_EQ(std::nullopt, in->i16_value);
+        EXPECT_EQ(std::nullopt, in->i32_value);
+        EXPECT_EQ(std::nullopt, in->i64_value);
+        EXPECT_EQ(std::nullopt, in->float_value);
+        EXPECT_EQ(std::nullopt, in->double_value);
+        EXPECT_EQ(std::nullopt, in->enum_value);
+        EXPECT_EQ(std::nullopt, in->mapped_enum_value);
         break;
       case CallerVersion::kV2:
         EXPECT_EQ(true, in->bool_value);
@@ -434,7 +434,7 @@
   }
 
   const Receiver<mojom::InterfaceV2> receiver_;
-  const absl::optional<CallerVersion> caller_version_;
+  const std::optional<CallerVersion> caller_version_;
 };
 
 class NullableValueTypes : public ::testing::Test {
@@ -444,37 +444,37 @@
 TEST_F(NullableValueTypes, StructWithEnums) {
   {
     auto input = mojom::StructWithEnums::New();
-    input->enum_value = absl::nullopt;
-    input->mapped_enum_value = absl::nullopt;
+    input->enum_value = std::nullopt;
+    input->mapped_enum_value = std::nullopt;
 
     mojom::StructWithEnumsPtr output;
     ASSERT_TRUE(SerializeAndDeserialize<mojom::StructWithEnums>(input, output));
 
-    EXPECT_EQ(absl::nullopt, output->enum_value);
-    EXPECT_EQ(absl::nullopt, output->mapped_enum_value);
+    EXPECT_EQ(std::nullopt, output->enum_value);
+    EXPECT_EQ(std::nullopt, output->mapped_enum_value);
   }
 
   {
     auto input = mojom::StructWithEnums::New();
     input->enum_value = mojom::RegularEnum::kThisValue;
-    input->mapped_enum_value = absl::nullopt;
+    input->mapped_enum_value = std::nullopt;
 
     mojom::StructWithEnumsPtr output;
     ASSERT_TRUE(SerializeAndDeserialize<mojom::StructWithEnums>(input, output));
 
     EXPECT_EQ(mojom::RegularEnum::kThisValue, output->enum_value);
-    EXPECT_EQ(absl::nullopt, output->mapped_enum_value);
+    EXPECT_EQ(std::nullopt, output->mapped_enum_value);
   }
 
   {
     auto input = mojom::StructWithEnums::New();
-    input->enum_value = absl::nullopt;
+    input->enum_value = std::nullopt;
     input->mapped_enum_value = TypemappedEnum::kValueOne;
 
     mojom::StructWithEnumsPtr output;
     ASSERT_TRUE(SerializeAndDeserialize<mojom::StructWithEnums>(input, output));
 
-    EXPECT_EQ(absl::nullopt, output->enum_value);
+    EXPECT_EQ(std::nullopt, output->enum_value);
     EXPECT_EQ(TypemappedEnum::kValueOne, output->mapped_enum_value);
   }
 
@@ -577,12 +577,12 @@
     {
       base::RunLoop loop;
       remote->MethodWithEnums(
-          absl::nullopt, absl::nullopt,
+          std::nullopt, std::nullopt,
           base::BindLambdaForTesting(
-              [&](absl::optional<mojom::RegularEnum> enum_value,
-                  absl::optional<TypemappedEnum> mapped_enum_value) {
-                EXPECT_EQ(absl::nullopt, enum_value);
-                EXPECT_EQ(absl::nullopt, mapped_enum_value);
+              [&](std::optional<mojom::RegularEnum> enum_value,
+                  std::optional<TypemappedEnum> mapped_enum_value) {
+                EXPECT_EQ(std::nullopt, enum_value);
+                EXPECT_EQ(std::nullopt, mapped_enum_value);
                 loop.Quit();
               }));
       loop.Run();
@@ -591,12 +591,12 @@
     {
       base::RunLoop loop;
       remote->MethodWithEnums(
-          mojom::RegularEnum::kThisValue, absl::nullopt,
+          mojom::RegularEnum::kThisValue, std::nullopt,
           base::BindLambdaForTesting(
-              [&](absl::optional<mojom::RegularEnum> enum_value,
-                  absl::optional<TypemappedEnum> mapped_enum_value) {
+              [&](std::optional<mojom::RegularEnum> enum_value,
+                  std::optional<TypemappedEnum> mapped_enum_value) {
                 EXPECT_EQ(mojom::RegularEnum::kThatValue, enum_value);
-                EXPECT_EQ(absl::nullopt, mapped_enum_value);
+                EXPECT_EQ(std::nullopt, mapped_enum_value);
                 loop.Quit();
               }));
       loop.Run();
@@ -605,11 +605,11 @@
     {
       base::RunLoop loop;
       remote->MethodWithEnums(
-          absl::nullopt, TypemappedEnum::kValueOne,
+          std::nullopt, TypemappedEnum::kValueOne,
           base::BindLambdaForTesting(
-              [&](absl::optional<mojom::RegularEnum> enum_value,
-                  absl::optional<TypemappedEnum> mapped_enum_value) {
-                EXPECT_EQ(absl::nullopt, enum_value);
+              [&](std::optional<mojom::RegularEnum> enum_value,
+                  std::optional<TypemappedEnum> mapped_enum_value) {
+                EXPECT_EQ(std::nullopt, enum_value);
                 EXPECT_EQ(TypemappedEnum::kValueTwo, mapped_enum_value);
                 loop.Quit();
               }));
@@ -621,8 +621,8 @@
       remote->MethodWithEnums(
           mojom::RegularEnum::kThatValue, TypemappedEnum::kValueTwo,
           base::BindLambdaForTesting(
-              [&](absl::optional<mojom::RegularEnum> enum_value,
-                  absl::optional<TypemappedEnum> mapped_enum_value) {
+              [&](std::optional<mojom::RegularEnum> enum_value,
+                  std::optional<TypemappedEnum> mapped_enum_value) {
                 EXPECT_EQ(mojom::RegularEnum::kThisValue, enum_value);
                 EXPECT_EQ(TypemappedEnum::kValueOne, mapped_enum_value);
                 loop.Quit();
@@ -715,10 +715,10 @@
     {
       base::RunLoop loop;
       remote->MethodWithStructWithEnums(
-          mojom::StructWithEnums::New(absl::nullopt, absl::nullopt),
+          mojom::StructWithEnums::New(std::nullopt, std::nullopt),
           base::BindLambdaForTesting([&](mojom::StructWithEnumsPtr out) {
-            EXPECT_EQ(absl::nullopt, out->enum_value);
-            EXPECT_EQ(absl::nullopt, out->mapped_enum_value);
+            EXPECT_EQ(std::nullopt, out->enum_value);
+            EXPECT_EQ(std::nullopt, out->mapped_enum_value);
             loop.Quit();
           }));
       loop.Run();
@@ -728,10 +728,10 @@
       base::RunLoop loop;
       remote->MethodWithStructWithEnums(
           mojom::StructWithEnums::New(mojom::RegularEnum::kThisValue,
-                                      absl::nullopt),
+                                      std::nullopt),
           base::BindLambdaForTesting([&](mojom::StructWithEnumsPtr out) {
             EXPECT_EQ(mojom::RegularEnum::kThatValue, out->enum_value);
-            EXPECT_EQ(absl::nullopt, out->mapped_enum_value);
+            EXPECT_EQ(std::nullopt, out->mapped_enum_value);
             loop.Quit();
           }));
       loop.Run();
@@ -740,9 +740,9 @@
     {
       base::RunLoop loop;
       remote->MethodWithStructWithEnums(
-          mojom::StructWithEnums::New(absl::nullopt, TypemappedEnum::kValueOne),
+          mojom::StructWithEnums::New(std::nullopt, TypemappedEnum::kValueOne),
           base::BindLambdaForTesting([&](mojom::StructWithEnumsPtr out) {
-            EXPECT_EQ(absl::nullopt, out->enum_value);
+            EXPECT_EQ(std::nullopt, out->enum_value);
             EXPECT_EQ(TypemappedEnum::kValueTwo, out->mapped_enum_value);
             loop.Quit();
           }));
@@ -768,15 +768,15 @@
   {
     auto input = mojom::StructWithNumerics::New();
     input->bool_value = true;
-    input->u8_value = absl::nullopt;
+    input->u8_value = std::nullopt;
     input->u16_value = 16;
-    input->u32_value = absl::nullopt;
+    input->u32_value = std::nullopt;
     input->u64_value = 64;
     input->i8_value = -8;
-    input->i16_value = absl::nullopt;
+    input->i16_value = std::nullopt;
     input->i32_value = -32;
-    input->i64_value = absl::nullopt;
-    input->float_value = absl::nullopt;
+    input->i64_value = std::nullopt;
+    input->float_value = std::nullopt;
     input->double_value = -64.0;
 
     mojom::StructWithNumericsPtr output;
@@ -784,47 +784,47 @@
         SerializeAndDeserialize<mojom::StructWithNumerics>(input, output));
 
     EXPECT_EQ(true, output->bool_value);
-    EXPECT_EQ(absl::nullopt, output->u8_value);
+    EXPECT_EQ(std::nullopt, output->u8_value);
     EXPECT_EQ(16u, output->u16_value);
-    EXPECT_EQ(absl::nullopt, output->u32_value);
+    EXPECT_EQ(std::nullopt, output->u32_value);
     EXPECT_EQ(64u, output->u64_value);
     EXPECT_EQ(-8, output->i8_value);
-    EXPECT_EQ(absl::nullopt, output->i16_value);
+    EXPECT_EQ(std::nullopt, output->i16_value);
     EXPECT_EQ(-32, output->i32_value);
-    EXPECT_EQ(absl::nullopt, output->i64_value);
-    EXPECT_EQ(absl::nullopt, output->float_value);
+    EXPECT_EQ(std::nullopt, output->i64_value);
+    EXPECT_EQ(std::nullopt, output->float_value);
     EXPECT_EQ(-64.0, output->double_value);
   }
 
   {
     auto input = mojom::StructWithNumerics::New();
-    input->bool_value = absl::nullopt;
+    input->bool_value = std::nullopt;
     input->u8_value = 8;
-    input->u16_value = absl::nullopt;
+    input->u16_value = std::nullopt;
     input->u32_value = 32;
-    input->u64_value = absl::nullopt;
-    input->i8_value = absl::nullopt;
+    input->u64_value = std::nullopt;
+    input->i8_value = std::nullopt;
     input->i16_value = -16;
-    input->i32_value = absl::nullopt;
+    input->i32_value = std::nullopt;
     input->i64_value = -64;
     input->float_value = -32.0f;
-    input->double_value = absl::nullopt;
+    input->double_value = std::nullopt;
 
     mojom::StructWithNumericsPtr output;
     ASSERT_TRUE(
         SerializeAndDeserialize<mojom::StructWithNumerics>(input, output));
 
-    EXPECT_EQ(absl::nullopt, output->bool_value);
+    EXPECT_EQ(std::nullopt, output->bool_value);
     EXPECT_EQ(8u, output->u8_value);
-    EXPECT_EQ(absl::nullopt, output->u16_value);
+    EXPECT_EQ(std::nullopt, output->u16_value);
     EXPECT_EQ(32u, output->u32_value);
-    EXPECT_EQ(absl::nullopt, output->u64_value);
-    EXPECT_EQ(absl::nullopt, output->i8_value);
+    EXPECT_EQ(std::nullopt, output->u64_value);
+    EXPECT_EQ(std::nullopt, output->i8_value);
     EXPECT_EQ(-16, output->i16_value);
-    EXPECT_EQ(absl::nullopt, output->i32_value);
+    EXPECT_EQ(std::nullopt, output->i32_value);
     EXPECT_EQ(-64, output->i64_value);
     EXPECT_EQ(-32.0f, output->float_value);
-    EXPECT_EQ(absl::nullopt, output->double_value);
+    EXPECT_EQ(std::nullopt, output->double_value);
   }
 }
 
@@ -931,33 +931,33 @@
     {
       base::RunLoop loop;
       remote->MethodWithNumerics(
-          true, absl::nullopt, uint16_t{16}, absl::nullopt, uint64_t{64},
-          int8_t{-8}, absl::nullopt, int32_t{-32}, absl::nullopt, absl::nullopt,
+          true, std::nullopt, uint16_t{16}, std::nullopt, uint64_t{64},
+          int8_t{-8}, std::nullopt, int32_t{-32}, std::nullopt, std::nullopt,
           -64.0,
-          base::BindLambdaForTesting([&](absl::optional<bool> bool_value,
-                                         absl::optional<uint8_t> u8_value,
-                                         absl::optional<uint16_t> u16_value,
-                                         absl::optional<uint32_t> u32_value,
-                                         absl::optional<uint64_t> u64_value,
-                                         absl::optional<int8_t> i8_value,
-                                         absl::optional<int16_t> i16_value,
-                                         absl::optional<int32_t> i32_value,
-                                         absl::optional<int64_t> i64_value,
-                                         absl::optional<float> float_value,
-                                         absl::optional<double> double_value) {
+          base::BindLambdaForTesting([&](std::optional<bool> bool_value,
+                                         std::optional<uint8_t> u8_value,
+                                         std::optional<uint16_t> u16_value,
+                                         std::optional<uint32_t> u32_value,
+                                         std::optional<uint64_t> u64_value,
+                                         std::optional<int8_t> i8_value,
+                                         std::optional<int16_t> i16_value,
+                                         std::optional<int32_t> i32_value,
+                                         std::optional<int64_t> i64_value,
+                                         std::optional<float> float_value,
+                                         std::optional<double> double_value) {
             EXPECT_EQ(false, bool_value);
-            EXPECT_EQ(absl::nullopt, u8_value);
+            EXPECT_EQ(std::nullopt, u8_value);
             // Note: the seemingly more obvious ~uint16_t{16} is not used
             // here because using ~ when sizeof(integer) < sizeof(int)
             // automatically promotes to an int. 🙃
             EXPECT_EQ(uint16_t{0xffef}, u16_value);
-            EXPECT_EQ(absl::nullopt, u32_value);
+            EXPECT_EQ(std::nullopt, u32_value);
             EXPECT_EQ(~uint64_t{64}, u64_value);
             EXPECT_EQ(8, i8_value);
-            EXPECT_EQ(absl::nullopt, i16_value);
+            EXPECT_EQ(std::nullopt, i16_value);
             EXPECT_EQ(32, i32_value);
-            EXPECT_EQ(absl::nullopt, i64_value);
-            EXPECT_EQ(absl::nullopt, float_value);
+            EXPECT_EQ(std::nullopt, i64_value);
+            EXPECT_EQ(std::nullopt, float_value);
             EXPECT_EQ(128.0, double_value);
             loop.Quit();
           }));
@@ -967,34 +967,34 @@
     {
       base::RunLoop loop;
       remote->MethodWithNumerics(
-          absl::nullopt, uint8_t{8}, absl::nullopt, uint32_t{32}, absl::nullopt,
-          absl::nullopt, int16_t{-16}, absl::nullopt, int64_t{-64}, -32.0f,
-          absl::nullopt,
-          base::BindLambdaForTesting([&](absl::optional<bool> bool_value,
-                                         absl::optional<uint8_t> u8_value,
-                                         absl::optional<uint16_t> u16_value,
-                                         absl::optional<uint32_t> u32_value,
-                                         absl::optional<uint64_t> u64_value,
-                                         absl::optional<int8_t> i8_value,
-                                         absl::optional<int16_t> i16_value,
-                                         absl::optional<int32_t> i32_value,
-                                         absl::optional<int64_t> i64_value,
-                                         absl::optional<float> float_value,
-                                         absl::optional<double> double_value) {
-            EXPECT_EQ(absl::nullopt, bool_value);
+          std::nullopt, uint8_t{8}, std::nullopt, uint32_t{32}, std::nullopt,
+          std::nullopt, int16_t{-16}, std::nullopt, int64_t{-64}, -32.0f,
+          std::nullopt,
+          base::BindLambdaForTesting([&](std::optional<bool> bool_value,
+                                         std::optional<uint8_t> u8_value,
+                                         std::optional<uint16_t> u16_value,
+                                         std::optional<uint32_t> u32_value,
+                                         std::optional<uint64_t> u64_value,
+                                         std::optional<int8_t> i8_value,
+                                         std::optional<int16_t> i16_value,
+                                         std::optional<int32_t> i32_value,
+                                         std::optional<int64_t> i64_value,
+                                         std::optional<float> float_value,
+                                         std::optional<double> double_value) {
+            EXPECT_EQ(std::nullopt, bool_value);
             // Note: the seemingly more obvious ~uint8_t{8} is not used
             // here because using ~ when sizeof(integer) < sizeof(int)
             // automatically promotes to an int. 🙃
             EXPECT_EQ(uint8_t{0xf7}, u8_value);
-            EXPECT_EQ(absl::nullopt, u16_value);
+            EXPECT_EQ(std::nullopt, u16_value);
             EXPECT_EQ(~uint32_t{32}, u32_value);
-            EXPECT_EQ(absl::nullopt, u64_value);
-            EXPECT_EQ(absl::nullopt, i8_value);
+            EXPECT_EQ(std::nullopt, u64_value);
+            EXPECT_EQ(std::nullopt, i8_value);
             EXPECT_EQ(16, i16_value);
-            EXPECT_EQ(absl::nullopt, i32_value);
+            EXPECT_EQ(std::nullopt, i32_value);
             EXPECT_EQ(64, i64_value);
             EXPECT_EQ(64.0, float_value);
-            EXPECT_EQ(absl::nullopt, double_value);
+            EXPECT_EQ(std::nullopt, double_value);
             loop.Quit();
           }));
       loop.Run();
@@ -1093,24 +1093,24 @@
     {
       base::RunLoop loop;
       remote->MethodWithStructWithNumerics(
-          mojom::StructWithNumerics::New(
-              true, absl::nullopt, uint16_t{16}, absl::nullopt, uint64_t{64},
-              int8_t{-8}, absl::nullopt, int32_t{-32}, absl::nullopt,
-              absl::nullopt, -64.0),
+          mojom::StructWithNumerics::New(true, std::nullopt, uint16_t{16},
+                                         std::nullopt, uint64_t{64}, int8_t{-8},
+                                         std::nullopt, int32_t{-32},
+                                         std::nullopt, std::nullopt, -64.0),
           base::BindLambdaForTesting([&](mojom::StructWithNumericsPtr out) {
             EXPECT_EQ(false, out->bool_value);
-            EXPECT_EQ(absl::nullopt, out->u8_value);
+            EXPECT_EQ(std::nullopt, out->u8_value);
             // Note: the seemingly more obvious ~uint16_t{16} is not used
             // here because using ~ when sizeof(integer) < sizeof(int)
             // automatically promotes to an int. 🙃
             EXPECT_EQ(uint16_t{0xffef}, out->u16_value);
-            EXPECT_EQ(absl::nullopt, out->u32_value);
+            EXPECT_EQ(std::nullopt, out->u32_value);
             EXPECT_EQ(~uint64_t{64}, out->u64_value);
             EXPECT_EQ(8, out->i8_value);
-            EXPECT_EQ(absl::nullopt, out->i16_value);
+            EXPECT_EQ(std::nullopt, out->i16_value);
             EXPECT_EQ(32, out->i32_value);
-            EXPECT_EQ(absl::nullopt, out->i64_value);
-            EXPECT_EQ(absl::nullopt, out->float_value);
+            EXPECT_EQ(std::nullopt, out->i64_value);
+            EXPECT_EQ(std::nullopt, out->float_value);
             EXPECT_EQ(128.0, out->double_value);
             loop.Quit();
           }));
@@ -1121,24 +1121,24 @@
       base::RunLoop loop;
       remote->MethodWithStructWithNumerics(
           mojom::StructWithNumerics::New(
-              absl::nullopt, uint8_t{8}, absl::nullopt, uint32_t{32},
-              absl::nullopt, absl::nullopt, int16_t{-16}, absl::nullopt,
-              int64_t{-64}, -32.0f, absl::nullopt),
+              std::nullopt, uint8_t{8}, std::nullopt, uint32_t{32},
+              std::nullopt, std::nullopt, int16_t{-16}, std::nullopt,
+              int64_t{-64}, -32.0f, std::nullopt),
           base::BindLambdaForTesting([&](mojom::StructWithNumericsPtr out) {
-            EXPECT_EQ(absl::nullopt, out->bool_value);
+            EXPECT_EQ(std::nullopt, out->bool_value);
             // Note: the seemingly more obvious ~uint8_t{8} is not used
             // here because using ~ when sizeof(integer) < sizeof(int)
             // automatically promotes to an int. 🙃
             EXPECT_EQ(uint8_t{0xf7}, out->u8_value);
-            EXPECT_EQ(absl::nullopt, out->u16_value);
+            EXPECT_EQ(std::nullopt, out->u16_value);
             EXPECT_EQ(~uint32_t{32}, out->u32_value);
-            EXPECT_EQ(absl::nullopt, out->u64_value);
-            EXPECT_EQ(absl::nullopt, out->i8_value);
+            EXPECT_EQ(std::nullopt, out->u64_value);
+            EXPECT_EQ(std::nullopt, out->i8_value);
             EXPECT_EQ(16, out->i16_value);
-            EXPECT_EQ(absl::nullopt, out->i32_value);
+            EXPECT_EQ(std::nullopt, out->i32_value);
             EXPECT_EQ(64, out->i64_value);
             EXPECT_EQ(64.0, out->float_value);
-            EXPECT_EQ(absl::nullopt, out->double_value);
+            EXPECT_EQ(std::nullopt, out->double_value);
             loop.Quit();
           }));
       loop.Run();
@@ -1215,35 +1215,35 @@
           int16_t{-32}, int32_t{-64}, int64_t{-128}, 256.0f, -512.0,
           mojom::RegularEnum::kThisValue, TypemappedEnum::kValueTwo,
           base::BindLambdaForTesting(
-              [&](absl::optional<bool> out_bool_value,
-                  absl::optional<uint8_t> out_u8_value,
-                  absl::optional<uint16_t> out_u16_value,
-                  absl::optional<uint32_t> out_u32_value,
-                  absl::optional<uint64_t> out_u64_value,
-                  absl::optional<int8_t> out_i8_value,
-                  absl::optional<int16_t> out_i16_value,
-                  absl::optional<int32_t> out_i32_value,
-                  absl::optional<int64_t> out_i64_value,
-                  absl::optional<float> out_float_value,
-                  absl::optional<double> out_double_value,
-                  absl::optional<mojom::RegularEnum> out_enum_value,
-                  absl::optional<TypemappedEnum> out_mapped_enum_value) {
+              [&](std::optional<bool> out_bool_value,
+                  std::optional<uint8_t> out_u8_value,
+                  std::optional<uint16_t> out_u16_value,
+                  std::optional<uint32_t> out_u32_value,
+                  std::optional<uint64_t> out_u64_value,
+                  std::optional<int8_t> out_i8_value,
+                  std::optional<int16_t> out_i16_value,
+                  std::optional<int32_t> out_i32_value,
+                  std::optional<int64_t> out_i64_value,
+                  std::optional<float> out_float_value,
+                  std::optional<double> out_double_value,
+                  std::optional<mojom::RegularEnum> out_enum_value,
+                  std::optional<TypemappedEnum> out_mapped_enum_value) {
                 // An implementation based on the V1 interface will not know
                 // about the new arguments, so they should all equal
-                // absl::nullopt.
-                EXPECT_EQ(absl::nullopt, out_bool_value);
-                EXPECT_EQ(absl::nullopt, out_u8_value);
-                EXPECT_EQ(absl::nullopt, out_u16_value);
-                EXPECT_EQ(absl::nullopt, out_u32_value);
-                EXPECT_EQ(absl::nullopt, out_u64_value);
-                EXPECT_EQ(absl::nullopt, out_i8_value);
-                EXPECT_EQ(absl::nullopt, out_i16_value);
-                EXPECT_EQ(absl::nullopt, out_i32_value);
-                EXPECT_EQ(absl::nullopt, out_i64_value);
-                EXPECT_EQ(absl::nullopt, out_float_value);
-                EXPECT_EQ(absl::nullopt, out_double_value);
-                EXPECT_EQ(absl::nullopt, out_enum_value);
-                EXPECT_EQ(absl::nullopt, out_mapped_enum_value);
+                // std::nullopt.
+                EXPECT_EQ(std::nullopt, out_bool_value);
+                EXPECT_EQ(std::nullopt, out_u8_value);
+                EXPECT_EQ(std::nullopt, out_u16_value);
+                EXPECT_EQ(std::nullopt, out_u32_value);
+                EXPECT_EQ(std::nullopt, out_u64_value);
+                EXPECT_EQ(std::nullopt, out_i8_value);
+                EXPECT_EQ(std::nullopt, out_i16_value);
+                EXPECT_EQ(std::nullopt, out_i32_value);
+                EXPECT_EQ(std::nullopt, out_i64_value);
+                EXPECT_EQ(std::nullopt, out_float_value);
+                EXPECT_EQ(std::nullopt, out_double_value);
+                EXPECT_EQ(std::nullopt, out_enum_value);
+                EXPECT_EQ(std::nullopt, out_mapped_enum_value);
                 loop.Quit();
               }));
       loop.Run();
@@ -1260,20 +1260,20 @@
           base::BindLambdaForTesting([&](mojom::VersionedStructV2Ptr out) {
             // An implementation based on the V1 interface will not know
             // about the new arguments, so they should all equal
-            // absl::nullopt.
-            EXPECT_EQ(absl::nullopt, out->bool_value);
-            EXPECT_EQ(absl::nullopt, out->u8_value);
-            EXPECT_EQ(absl::nullopt, out->u16_value);
-            EXPECT_EQ(absl::nullopt, out->u32_value);
-            EXPECT_EQ(absl::nullopt, out->u64_value);
-            EXPECT_EQ(absl::nullopt, out->i8_value);
-            EXPECT_EQ(absl::nullopt, out->i16_value);
-            EXPECT_EQ(absl::nullopt, out->i32_value);
-            EXPECT_EQ(absl::nullopt, out->i64_value);
-            EXPECT_EQ(absl::nullopt, out->float_value);
-            EXPECT_EQ(absl::nullopt, out->double_value);
-            EXPECT_EQ(absl::nullopt, out->enum_value);
-            EXPECT_EQ(absl::nullopt, out->mapped_enum_value);
+            // std::nullopt.
+            EXPECT_EQ(std::nullopt, out->bool_value);
+            EXPECT_EQ(std::nullopt, out->u8_value);
+            EXPECT_EQ(std::nullopt, out->u16_value);
+            EXPECT_EQ(std::nullopt, out->u32_value);
+            EXPECT_EQ(std::nullopt, out->u64_value);
+            EXPECT_EQ(std::nullopt, out->i8_value);
+            EXPECT_EQ(std::nullopt, out->i16_value);
+            EXPECT_EQ(std::nullopt, out->i32_value);
+            EXPECT_EQ(std::nullopt, out->i64_value);
+            EXPECT_EQ(std::nullopt, out->float_value);
+            EXPECT_EQ(std::nullopt, out->double_value);
+            EXPECT_EQ(std::nullopt, out->enum_value);
+            EXPECT_EQ(std::nullopt, out->mapped_enum_value);
             loop.Quit();
           }));
       loop.Run();
@@ -1294,19 +1294,19 @@
           int16_t{-32}, int32_t{-64}, int64_t{-128}, 256.0f, -512.0,
           mojom::RegularEnum::kThisValue, TypemappedEnum::kValueTwo,
           base::BindLambdaForTesting(
-              [&](absl::optional<bool> out_bool_value,
-                  absl::optional<uint8_t> out_u8_value,
-                  absl::optional<uint16_t> out_u16_value,
-                  absl::optional<uint32_t> out_u32_value,
-                  absl::optional<uint64_t> out_u64_value,
-                  absl::optional<int8_t> out_i8_value,
-                  absl::optional<int16_t> out_i16_value,
-                  absl::optional<int32_t> out_i32_value,
-                  absl::optional<int64_t> out_i64_value,
-                  absl::optional<float> out_float_value,
-                  absl::optional<double> out_double_value,
-                  absl::optional<mojom::RegularEnum> out_enum_value,
-                  absl::optional<TypemappedEnum> out_mapped_enum_value) {
+              [&](std::optional<bool> out_bool_value,
+                  std::optional<uint8_t> out_u8_value,
+                  std::optional<uint16_t> out_u16_value,
+                  std::optional<uint32_t> out_u32_value,
+                  std::optional<uint64_t> out_u64_value,
+                  std::optional<int8_t> out_i8_value,
+                  std::optional<int16_t> out_i16_value,
+                  std::optional<int32_t> out_i32_value,
+                  std::optional<int64_t> out_i64_value,
+                  std::optional<float> out_float_value,
+                  std::optional<double> out_double_value,
+                  std::optional<mojom::RegularEnum> out_enum_value,
+                  std::optional<TypemappedEnum> out_mapped_enum_value) {
                 EXPECT_EQ(false, out_bool_value);
                 EXPECT_EQ(uint8_t{128}, out_u8_value);
                 EXPECT_EQ(uint16_t{64}, out_u16_value);
diff --git a/mojo/public/cpp/bindings/tests/receiver_unittest.cc b/mojo/public/cpp/bindings/tests/receiver_unittest.cc
index 34ffa853f..ac6a759 100644
--- a/mojo/public/cpp/bindings/tests/receiver_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/receiver_unittest.cc
@@ -5,6 +5,7 @@
 #include <stdint.h>
 #include <utility>
 
+#include <optional>
 #include "base/check_op.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
@@ -33,7 +34,6 @@
 #include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h"
 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 namespace test {
@@ -768,7 +768,7 @@
 
   Receiver<mojom::TestGenericBinder> receiver_;
   bool connected_ = true;
-  absl::optional<base::RunLoop> wait_loop_;
+  std::optional<base::RunLoop> wait_loop_;
   raw_ptr<GenericPendingReceiver> next_receiver_storage_ = nullptr;
   raw_ptr<GenericPendingAssociatedReceiver> next_associated_receiver_storage_ =
       nullptr;
@@ -1013,7 +1013,7 @@
     constexpr size_t kNumIterations = 1000;
     constexpr size_t kNumReceiversPerIteration = 10;
     for (size_t i = 0; i < kNumIterations; ++i) {
-      std::vector<absl::optional<Receiver<mojom::TestInterface1>>> receivers(
+      std::vector<std::optional<Receiver<mojom::TestInterface1>>> receivers(
           kNumReceiversPerIteration);
       for (auto& receiver : receivers) {
         receiver.emplace(this);
diff --git a/mojo/public/cpp/bindings/tests/remote_unittest.cc b/mojo/public/cpp/bindings/tests/remote_unittest.cc
index 3801b5d..1df9c86 100644
--- a/mojo/public/cpp/bindings/tests/remote_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/remote_unittest.cc
@@ -7,6 +7,7 @@
 #include <tuple>
 #include <utility>
 
+#include <optional>
 #include "base/barrier_closure.h"
 #include "base/debug/dump_without_crashing.h"
 #include "base/functional/bind.h"
@@ -39,7 +40,6 @@
 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h"
 #include "mojo/public/interfaces/bindings/tests/scoping.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 namespace test {
@@ -1307,7 +1307,7 @@
 }
 
 TEST_P(RemoteTest, RemoteSet) {
-  std::vector<absl::optional<MathCalculatorImpl>> impls(4);
+  std::vector<std::optional<MathCalculatorImpl>> impls(4);
 
   PendingRemote<math::Calculator> remote0;
   PendingRemote<math::Calculator> remote1;
diff --git a/mojo/public/cpp/bindings/tests/sample_service_unittest.cc b/mojo/public/cpp/bindings/tests/sample_service_unittest.cc
index d7d4919..5e93add 100644
--- a/mojo/public/cpp/bindings/tests/sample_service_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/sample_service_unittest.cc
@@ -84,7 +84,7 @@
                   std::move(extra_bars), std::move(data),
                   std::move(pipe.handle1), std::move(input_streams),
                   std::move(output_streams), std::move(array_of_array_of_bools),
-                  absl::nullopt, absl::nullopt);
+                  std::nullopt, std::nullopt);
 }
 
 // Check that the given |Foo| is identical to the one made by |MakeFoo()|.
@@ -201,7 +201,7 @@
 template <typename T>
 void Print(int depth,
            const char* name,
-           const absl::optional<std::vector<T>>& array) {
+           const std::optional<std::vector<T>>& array) {
   if (array)
     Print(depth, name, *array);
   else
diff --git a/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc b/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc
index 2a57ca4..4cabf95e 100644
--- a/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc
@@ -27,9 +27,9 @@
 using mojo::internal::GetMapValidator;
 
 // Creates an array of arrays of handles (2 X 3) for testing.
-std::vector<absl::optional<std::vector<ScopedHandle>>>
+std::vector<std::optional<std::vector<ScopedHandle>>>
 CreateTestNestedHandleArray() {
-  std::vector<absl::optional<std::vector<ScopedHandle>>> array(2);
+  std::vector<std::optional<std::vector<ScopedHandle>>> array(2);
   for (size_t i = 0; i < array.size(); ++i) {
     std::vector<ScopedHandle> nested_array(3);
     for (size_t j = 0; j < nested_array.size(); ++j) {
@@ -159,7 +159,7 @@
 TEST_F(SerializationWarningTest, ArrayOfArraysOfHandles) {
   using MojomType = ArrayDataView<ArrayDataView<ScopedHandle>>;
   auto test_array = CreateTestNestedHandleArray();
-  test_array[0] = absl::nullopt;
+  test_array[0] = std::nullopt;
   (*test_array[1])[0] = ScopedHandle();
 
   constexpr const ContainerValidateParams& validate_params_0 =
@@ -169,7 +169,7 @@
                               &validate_params_0);
 
   test_array = CreateTestNestedHandleArray();
-  test_array[0] = absl::nullopt;
+  test_array[0] = std::nullopt;
   constexpr const ContainerValidateParams& validate_params_1 =
       GetArrayValidator<0, false, &GetArrayValidator<0, true, nullptr>()>();
   TestArrayWarning<MojomType>(
@@ -200,7 +200,7 @@
                               mojo::internal::VALIDATION_ERROR_NONE,
                               &validate_params_0);
 
-  std::vector<absl::optional<std::string>> optional_test_array(3);
+  std::vector<std::optional<std::string>> optional_test_array(3);
   constexpr const ContainerValidateParams& validate_params_1 =
       GetArrayValidator<0, false, &GetArrayValidator<0, false, nullptr>()>();
   TestArrayWarning<MojomType>(
diff --git a/mojo/public/cpp/bindings/tests/service_factory_unittest.cc b/mojo/public/cpp/bindings/tests/service_factory_unittest.cc
index 19393397..6fb7ffe 100644
--- a/mojo/public/cpp/bindings/tests/service_factory_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/service_factory_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "mojo/public/cpp/bindings/service_factory.h"
 
+#include <optional>
 #include "base/functional/callback.h"
 #include "base/functional/callback_helpers.h"
 #include "base/run_loop.h"
@@ -15,7 +16,6 @@
 #include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/bindings/tests/service_factory_unittest.test-mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 namespace test {
@@ -170,7 +170,7 @@
 }
 
 TEST_F(ServiceFactoryTest, DestroyInstancesOnFactoryDestruction) {
-  absl::optional<ServiceFactory> factory{absl::in_place};
+  std::optional<ServiceFactory> factory{std::in_place};
   factory->Add(RunTestService1);
 
   Remote<mojom::TestService1> remote1;
diff --git a/mojo/public/cpp/bindings/tests/struct_traits_unittest.cc b/mojo/public/cpp/bindings/tests/struct_traits_unittest.cc
index 7395550..15d9853 100644
--- a/mojo/public/cpp/bindings/tests/struct_traits_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/struct_traits_unittest.cc
@@ -160,7 +160,7 @@
   }
 
   void EchoNullableMoveOnlyStructWithTraits(
-      absl::optional<MoveOnlyStructWithTraitsImpl> s,
+      std::optional<MoveOnlyStructWithTraitsImpl> s,
       EchoNullableMoveOnlyStructWithTraitsCallback callback) override {
     std::move(callback).Run(std::move(s));
   }
@@ -401,9 +401,9 @@
 }
 
 void CaptureNullableMoveOnlyStructWithTraitsImpl(
-    absl::optional<MoveOnlyStructWithTraitsImpl>* storage,
+    std::optional<MoveOnlyStructWithTraitsImpl>* storage,
     base::OnceClosure closure,
-    absl::optional<MoveOnlyStructWithTraitsImpl> passed) {
+    std::optional<MoveOnlyStructWithTraitsImpl> passed) {
   *storage = std::move(passed);
   std::move(closure).Run();
 }
@@ -412,11 +412,10 @@
   base::RunLoop loop;
   Remote<TraitsTestService> proxy = GetTraitsTestProxy();
 
-  absl::optional<MoveOnlyStructWithTraitsImpl> received;
+  std::optional<MoveOnlyStructWithTraitsImpl> received;
   proxy->EchoNullableMoveOnlyStructWithTraits(
-      absl::nullopt,
-      base::BindOnce(&CaptureNullableMoveOnlyStructWithTraitsImpl, &received,
-                     loop.QuitClosure()));
+      std::nullopt, base::BindOnce(&CaptureNullableMoveOnlyStructWithTraitsImpl,
+                                   &received, loop.QuitClosure()));
   loop.Run();
 
   EXPECT_FALSE(received);
diff --git a/mojo/public/cpp/bindings/tests/wtf_types_unittest.cc b/mojo/public/cpp/bindings/tests/wtf_types_unittest.cc
index 250e518..d70117e 100644
--- a/mojo/public/cpp/bindings/tests/wtf_types_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/wtf_types_unittest.cc
@@ -31,20 +31,20 @@
       : receiver_(this, std::move(receiver)) {}
 
   // mojo::test::TestWTF implementation:
-  void EchoString(const absl::optional<std::string>& str,
+  void EchoString(const std::optional<std::string>& str,
                   EchoStringCallback callback) override {
     std::move(callback).Run(str);
   }
 
   void EchoStringArray(
-      const absl::optional<std::vector<absl::optional<std::string>>>& arr,
+      const std::optional<std::vector<std::optional<std::string>>>& arr,
       EchoStringArrayCallback callback) override {
     std::move(callback).Run(std::move(arr));
   }
 
   void EchoStringMap(
-      const absl::optional<
-          base::flat_map<std::string, absl::optional<std::string>>>& str_map,
+      const std::optional<
+          base::flat_map<std::string, std::optional<std::string>>>& str_map,
       EchoStringMapCallback callback) override {
     std::move(callback).Run(std::move(str_map));
   }
@@ -89,17 +89,17 @@
   std::move(closure).Run();
 }
 
-void ExpectStringArray(absl::optional<WTF::Vector<WTF::String>>* expected_arr,
+void ExpectStringArray(std::optional<WTF::Vector<WTF::String>>* expected_arr,
                        base::OnceClosure closure,
-                       const absl::optional<WTF::Vector<WTF::String>>& arr) {
+                       const std::optional<WTF::Vector<WTF::String>>& arr) {
   EXPECT_EQ(*expected_arr, arr);
   std::move(closure).Run();
 }
 
 void ExpectStringMap(
-    absl::optional<WTF::HashMap<WTF::String, WTF::String>>* expected_map,
+    std::optional<WTF::HashMap<WTF::String, WTF::String>>* expected_map,
     base::OnceClosure closure,
-    const absl::optional<WTF::HashMap<WTF::String, WTF::String>>& map) {
+    const std::optional<WTF::HashMap<WTF::String, WTF::String>>& map) {
   EXPECT_EQ(*expected_map, map);
   std::move(closure).Run();
 }
@@ -168,7 +168,7 @@
           0, true, &mojo::internal::GetArrayValidator<0, false, nullptr>()>();
   mojo::internal::Serialize<MojomType>(cloned_strs, fragment, &validate_params);
 
-  std::vector<absl::optional<std::string>> strs2;
+  std::vector<std::optional<std::string>> strs2;
   mojo::internal::Deserialize<MojomType>(fragment.data(), &strs2, &message);
 
   ASSERT_EQ(4u, strs2.size());
@@ -201,7 +201,7 @@
     base::RunLoop loop;
     // Test that a WTF::String is unchanged after the following conversion:
     //   - serialized;
-    //   - deserialized as absl::optional<std::string>;
+    //   - deserialized as std::optional<std::string>;
     //   - serialized;
     //   - deserialized as WTF::String.
     remote->EchoString(
@@ -215,7 +215,7 @@
   TestWTFImpl impl(
       ConvertPendingReceiver<TestWTF>(remote.BindNewPipeAndPassReceiver()));
 
-  absl::optional<WTF::Vector<WTF::String>> arrs[3];
+  std::optional<WTF::Vector<WTF::String>> arrs[3];
   // arrs[0] is empty.
   arrs[0].emplace();
   // arrs[1] is null.
@@ -223,13 +223,13 @@
 
   for (size_t i = 0; i < std::size(arrs); ++i) {
     base::RunLoop loop;
-    // Test that a absl::optional<WTF::Vector<WTF::String>> is unchanged after
+    // Test that a std::optional<WTF::Vector<WTF::String>> is unchanged after
     // the following conversion:
     //   - serialized;
     //   - deserialized as
-    //     absl::optional<std::vector<absl::optional<std::string>>>;
+    //     std::optional<std::vector<std::optional<std::string>>>;
     //   - serialized;
-    //   - deserialized as absl::optional<WTF::Vector<WTF::String>>.
+    //   - deserialized as std::optional<WTF::Vector<WTF::String>>.
     remote->EchoStringArray(
         arrs[i], base::BindOnce(&ExpectStringArray, base::Unretained(&arrs[i]),
                                 loop.QuitClosure()));
@@ -242,7 +242,7 @@
   TestWTFImpl impl(
       ConvertPendingReceiver<TestWTF>(remote.BindNewPipeAndPassReceiver()));
 
-  absl::optional<WTF::HashMap<WTF::String, WTF::String>> maps[3];
+  std::optional<WTF::HashMap<WTF::String, WTF::String>> maps[3];
   // maps[0] is empty.
   maps[0].emplace();
   // maps[1] is null.
@@ -250,13 +250,13 @@
 
   for (size_t i = 0; i < std::size(maps); ++i) {
     base::RunLoop loop;
-    // Test that a absl::optional<WTF::HashMap<WTF::String, WTF::String>> is
+    // Test that a std::optional<WTF::HashMap<WTF::String, WTF::String>> is
     // unchanged after the following conversion:
     //   - serialized;
-    //   - deserialized as absl::optional<
-    //         base::flat_map<std::string, absl::optional<std::string>>>;
+    //   - deserialized as std::optional<
+    //         base::flat_map<std::string, std::optional<std::string>>>;
     //   - serialized;
-    //   - deserialized as absl::optional<WTF::HashMap<WTF::String,
+    //   - deserialized as std::optional<WTF::HashMap<WTF::String,
     //     WTF::String>>.
     remote->EchoStringMap(
         maps[i], base::BindOnce(&ExpectStringMap, base::Unretained(&maps[i]),
diff --git a/mojo/public/cpp/platform/platform_handle_internal.h b/mojo/public/cpp/platform/platform_handle_internal.h
index 5cc7b44..3bbad7e 100644
--- a/mojo/public/cpp/platform/platform_handle_internal.h
+++ b/mojo/public/cpp/platform/platform_handle_internal.h
@@ -22,7 +22,7 @@
     return {.high = token.GetHighForSerialization(),
             .low = token.GetLowForSerialization()};
   }
-  static absl::optional<base::UnguessableToken> UnmarshalUnguessableToken(
+  static std::optional<base::UnguessableToken> UnmarshalUnguessableToken(
       const MojoSharedBufferGuid* guid) {
     return base::UnguessableToken::Deserialize(guid->high, guid->low);
   }
diff --git a/mojo/public/cpp/platform/platform_handle_security_util_win.cc b/mojo/public/cpp/platform/platform_handle_security_util_win.cc
index 76ed1d3..c3bb4e3 100644
--- a/mojo/public/cpp/platform/platform_handle_security_util_win.cc
+++ b/mojo/public/cpp/platform/platform_handle_security_util_win.cc
@@ -6,6 +6,7 @@
 
 #include <windows.h>
 
+#include <optional>
 #include "base/containers/span.h"
 #include "base/dcheck_is_on.h"
 #include "base/debug/stack_trace.h"
@@ -18,7 +19,6 @@
 #include "base/win/nt_status.h"
 #include "base/win/scoped_handle.h"
 #include "base/win/security_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 
@@ -47,10 +47,10 @@
   return full_path;
 }
 
-absl::optional<bool> IsReadOnlyHandle(HANDLE handle) {
-  absl::optional<ACCESS_MASK> flags = base::win::GetGrantedAccess(handle);
+std::optional<bool> IsReadOnlyHandle(HANDLE handle) {
+  std::optional<ACCESS_MASK> flags = base::win::GetGrantedAccess(handle);
   if (!flags.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   // Cannot use GENERIC_WRITE as that includes SYNCHRONIZE.
   // This is ~(all the writable permissions).
@@ -74,7 +74,7 @@
     return;
   }
 
-  absl::optional<bool> is_read_only = IsReadOnlyHandle(handle);
+  std::optional<bool> is_read_only = IsReadOnlyHandle(handle);
   if (!is_read_only.has_value()) {
     // If unable to obtain whether or not the handle is read-only, skip the rest
     // of the checks, since it's likely GetPathFromHandle below would fail
diff --git a/mojo/public/cpp/platform/tests/platform_channel_server_unittest.cc b/mojo/public/cpp/platform/tests/platform_channel_server_unittest.cc
index 3789ba8..3081e10 100644
--- a/mojo/public/cpp/platform/tests/platform_channel_server_unittest.cc
+++ b/mojo/public/cpp/platform/tests/platform_channel_server_unittest.cc
@@ -7,6 +7,7 @@
 #include <tuple>
 #include <utility>
 
+#include <optional>
 #include "base/containers/span.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/functional/callback.h"
@@ -18,7 +19,6 @@
 #include "mojo/core/channel.h"
 #include "mojo/public/cpp/platform/named_platform_channel.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 namespace {
@@ -99,7 +99,7 @@
   const scoped_refptr<core::Channel> channel_;
   base::RunLoop wait_for_message_;
   base::OnceClosure quit_{wait_for_message_.QuitClosure()};
-  absl::optional<std::string> received_message_;
+  std::optional<std::string> received_message_;
   bool stopped_ = false;
 };
 
diff --git a/mojo/public/cpp/system/dynamic_library_support.cc b/mojo/public/cpp/system/dynamic_library_support.cc
index 8e688b7..9a8cfac47 100644
--- a/mojo/public/cpp/system/dynamic_library_support.cc
+++ b/mojo/public/cpp/system/dynamic_library_support.cc
@@ -17,7 +17,7 @@
 
 // Helper for temporary storage related to |MojoInitialize()| calls.
 struct InitializationState {
-  InitializationState(const absl::optional<base::FilePath>& path,
+  InitializationState(const std::optional<base::FilePath>& path,
                       MojoInitializeFlags flags) {
     options.flags = flags;
 
@@ -44,18 +44,18 @@
 
 }  // namespace
 
-MojoResult LoadCoreLibrary(absl::optional<base::FilePath> path) {
+MojoResult LoadCoreLibrary(std::optional<base::FilePath> path) {
   InitializationState state(path, MOJO_INITIALIZE_FLAG_LOAD_ONLY);
   return MojoInitialize(&state.options);
 }
 
 MojoResult InitializeCoreLibrary(MojoInitializeFlags flags) {
   DCHECK_EQ(flags & MOJO_INITIALIZE_FLAG_LOAD_ONLY, 0u);
-  InitializationState state(absl::nullopt, flags);
+  InitializationState state(std::nullopt, flags);
   return MojoInitialize(&state.options);
 }
 
-MojoResult LoadAndInitializeCoreLibrary(absl::optional<base::FilePath> path,
+MojoResult LoadAndInitializeCoreLibrary(std::optional<base::FilePath> path,
                                         MojoInitializeFlags flags) {
   DCHECK_EQ(flags & MOJO_INITIALIZE_FLAG_LOAD_ONLY, 0u);
   InitializationState state(path, flags);
diff --git a/mojo/public/cpp/system/dynamic_library_support.h b/mojo/public/cpp/system/dynamic_library_support.h
index 745f65c6..bfec170 100644
--- a/mojo/public/cpp/system/dynamic_library_support.h
+++ b/mojo/public/cpp/system/dynamic_library_support.h
@@ -5,10 +5,10 @@
 #ifndef MOJO_PUBLIC_CPP_SYSTEM_DYNAMIC_LIBRARY_SUPPORT_H_
 #define MOJO_PUBLIC_CPP_SYSTEM_DYNAMIC_LIBRARY_SUPPORT_H_
 
+#include <optional>
 #include "base/files/file_path.h"
 #include "mojo/public/c/system/types.h"
 #include "mojo/public/cpp/system/system_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 
@@ -23,7 +23,7 @@
 // cases where the client application must perform some work (e.g. sandbox
 // configuration, forking, etc) between the loading and initialization steps.
 MOJO_CPP_SYSTEM_EXPORT MojoResult
-LoadCoreLibrary(absl::optional<base::FilePath> path);
+LoadCoreLibrary(std::optional<base::FilePath> path);
 
 // Initializes the dynamic Mojo Core library previously loaded by
 // |LoadCoreLibrary()| above.
@@ -37,7 +37,7 @@
 // where they don't need to be performed at different times by the client
 // application.
 MOJO_CPP_SYSTEM_EXPORT MojoResult
-LoadAndInitializeCoreLibrary(absl::optional<base::FilePath> path,
+LoadAndInitializeCoreLibrary(std::optional<base::FilePath> path,
                              MojoInitializeFlags flags);
 
 }  // namespace mojo
diff --git a/mojo/public/cpp/system/platform_handle.cc b/mojo/public/cpp/system/platform_handle.cc
index d6510a5..09e209d 100644
--- a/mojo/public/cpp/system/platform_handle.cc
+++ b/mojo/public/cpp/system/platform_handle.cc
@@ -173,7 +173,7 @@
       return base::subtle::PlatformSharedMemoryRegion();
   }
 
-  absl::optional<base::UnguessableToken> guid =
+  std::optional<base::UnguessableToken> guid =
       internal::PlatformHandleInternal::UnmarshalUnguessableToken(&mojo_guid);
   if (!guid.has_value()) {
     return base::subtle::PlatformSharedMemoryRegion();
diff --git a/mojo/public/cpp/system/tests/invitation_unittest.cc b/mojo/public/cpp/system/tests/invitation_unittest.cc
index f5f5c849..b7a8253b 100644
--- a/mojo/public/cpp/system/tests/invitation_unittest.cc
+++ b/mojo/public/cpp/system/tests/invitation_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include <optional>
 #include "base/base_paths.h"
 #include "base/base_switches.h"
 #include "base/check.h"
@@ -32,7 +33,6 @@
 #include "mojo/public/cpp/system/wait.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/multiprocess_func_list.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_IOS)
 #include "mojo/public/cpp/platform/named_platform_channel.h"
@@ -103,7 +103,7 @@
         base::GetMultiProcessTestChildBaseCommandLine());
 
     base::LaunchOptions launch_options;
-    absl::optional<PlatformChannel> channel;
+    std::optional<PlatformChannel> channel;
     PlatformChannelEndpoint channel_endpoint;
     PlatformChannelServerEndpoint server_endpoint;
     switch (transport_type) {
diff --git a/mojo/public/java/system/javatests/nullable_value_types_test_util.cc b/mojo/public/java/system/javatests/nullable_value_types_test_util.cc
index 81efdaf..9a8f602 100644
--- a/mojo/public/java/system/javatests/nullable_value_types_test_util.cc
+++ b/mojo/public/java/system/javatests/nullable_value_types_test_util.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include <optional>
 #include "base/android/jni_android.h"
 #include "base/notreached.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -14,15 +15,14 @@
 #include "mojo/public/cpp/system/message_pipe.h"
 #include "mojo/public/interfaces/bindings/tests/nullable_value_types.mojom.h"
 #include "mojo/public/java/system/mojo_javatests_jni/NullableValueTypesTestUtil_jni.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace mojo {
 namespace test::nullable_value_types {
 namespace {
 
 class InterfaceV2 : public mojom::InterfaceV2 {
-  void MethodWithEnums(absl::optional<mojom::RegularEnum> enum_value,
-                       absl::optional<TypemappedEnum> mapped_enum_value,
+  void MethodWithEnums(std::optional<mojom::RegularEnum> enum_value,
+                       std::optional<TypemappedEnum> mapped_enum_value,
                        MethodWithEnumsCallback reply) override {
     std::move(reply).Run(enum_value, mapped_enum_value);
   }
@@ -33,17 +33,17 @@
     std::move(reply).Run(std::move(in));
   }
 
-  void MethodWithNumerics(absl::optional<bool> bool_value,
-                          absl::optional<uint8_t> u8_value,
-                          absl::optional<uint16_t> u16_value,
-                          absl::optional<uint32_t> u32_value,
-                          absl::optional<uint64_t> u64_value,
-                          absl::optional<int8_t> i8_value,
-                          absl::optional<int16_t> i16_value,
-                          absl::optional<int32_t> i32_value,
-                          absl::optional<int64_t> i64_value,
-                          absl::optional<float> float_value,
-                          absl::optional<double> double_value,
+  void MethodWithNumerics(std::optional<bool> bool_value,
+                          std::optional<uint8_t> u8_value,
+                          std::optional<uint16_t> u16_value,
+                          std::optional<uint32_t> u32_value,
+                          std::optional<uint64_t> u64_value,
+                          std::optional<int8_t> i8_value,
+                          std::optional<int16_t> i16_value,
+                          std::optional<int32_t> i32_value,
+                          std::optional<int64_t> i64_value,
+                          std::optional<float> float_value,
+                          std::optional<double> double_value,
                           MethodWithNumericsCallback reply) override {
     std::move(reply).Run(bool_value, u8_value, u16_value, u32_value, u64_value,
                          i8_value, i16_value, i32_value, i64_value, float_value,
@@ -56,19 +56,19 @@
     std::move(reply).Run(std::move(in));
   }
 
-  void MethodWithVersionedArgs(absl::optional<bool> bool_value,
-                               absl::optional<uint8_t> u8_value,
-                               absl::optional<uint16_t> u16_value,
-                               absl::optional<uint32_t> u32_value,
-                               absl::optional<uint64_t> u64_value,
-                               absl::optional<int8_t> i8_value,
-                               absl::optional<int16_t> i16_value,
-                               absl::optional<int32_t> i32_value,
-                               absl::optional<int64_t> i64_value,
-                               absl::optional<float> float_value,
-                               absl::optional<double> double_value,
-                               absl::optional<mojom::RegularEnum> enum_value,
-                               absl::optional<TypemappedEnum> mapped_enum_value,
+  void MethodWithVersionedArgs(std::optional<bool> bool_value,
+                               std::optional<uint8_t> u8_value,
+                               std::optional<uint16_t> u16_value,
+                               std::optional<uint32_t> u32_value,
+                               std::optional<uint64_t> u64_value,
+                               std::optional<int8_t> i8_value,
+                               std::optional<int16_t> i16_value,
+                               std::optional<int32_t> i32_value,
+                               std::optional<int64_t> i64_value,
+                               std::optional<float> float_value,
+                               std::optional<double> double_value,
+                               std::optional<mojom::RegularEnum> enum_value,
+                               std::optional<TypemappedEnum> mapped_enum_value,
                                MethodWithVersionedArgsCallback reply) override {
     // Not currently exercised by tests.
     NOTREACHED_NORETURN();
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
index 9bfe902..10d1248 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
@@ -22,7 +22,7 @@
 #include <type_traits>
 #include <utility>
 
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include <optional>
 
 {%- if contains_only_enums %}
 #include "mojo/public/cpp/bindings/type_converter.h"
diff --git a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
index 9b3b643..dd2ae5d 100644
--- a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
+++ b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
@@ -666,7 +666,7 @@
 
   def _GetCppWrapperType(self, kind, add_same_module_namespaces=False):
     def _AddOptional(type_name):
-      return "absl::optional<%s>" % type_name
+      return "std::optional<%s>" % type_name
 
     if self._IsTypemappedKind(kind):
       type_name = self._GetNativeTypeName(kind)
@@ -1063,7 +1063,7 @@
 
     if mojom.IsEnumKind(kind):
       if kind.is_nullable:
-        return f"absl::optional<{_GetName(kind.MakeUnnullableKind())}>"
+        return f"std::optional<{_GetName(kind.MakeUnnullableKind())}>"
       return _GetName(kind)
     if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
       return "%sDataView" % _GetName(kind)
@@ -1106,7 +1106,7 @@
       return "mojo::PlatformHandle"
     assert isinstance(kind, mojom.ValueKind)
     if kind.is_nullable:
-      return f"absl::optional<{_kind_to_cpp_type[kind.MakeUnnullableKind()]}>"
+      return f"std::optional<{_kind_to_cpp_type[kind.MakeUnnullableKind()]}>"
     return _kind_to_cpp_type[kind]
 
   def _UnderToCamel(self, value, digits_split=False):
diff --git a/pdf/accessibility.cc b/pdf/accessibility.cc
index e8a7197d..70b2c86 100644
--- a/pdf/accessibility.cc
+++ b/pdf/accessibility.cc
@@ -58,7 +58,7 @@
 
   int char_index = 0;
   while (char_index < char_count) {
-    absl::optional<AccessibilityTextRunInfo> text_run_info_result =
+    std::optional<AccessibilityTextRunInfo> text_run_info_result =
         engine->GetTextRunInfo(page_index, char_index);
     DCHECK(text_run_info_result.has_value());
     const auto& text_run_info = text_run_info_result.value();
diff --git a/pdf/accessibility_helper.cc b/pdf/accessibility_helper.cc
index 89f62c9..f7ac169 100644
--- a/pdf/accessibility_helper.cc
+++ b/pdf/accessibility_helper.cc
@@ -8,9 +8,9 @@
 
 #include <vector>
 
+#include <optional>
 #include "base/numerics/safe_math.h"
 #include "pdf/accessibility_structs.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace chrome_pdf {
 
@@ -38,7 +38,7 @@
     return text_range;
   uint32_t end_char_index = checked_end_char_index.ValueOrDie();
   uint32_t current_char_index = 0;
-  absl::optional<size_t> start_text_run;
+  std::optional<size_t> start_text_run;
   for (size_t i = 0; i < text_runs.size(); ++i) {
     if (!start_text_run.has_value() &&
         IsCharWithinTextRun(text_runs[i], current_char_index,
diff --git a/pdf/parsed_params.cc b/pdf/parsed_params.cc
index 1e142613..d44711b 100644
--- a/pdf/parsed_params.cc
+++ b/pdf/parsed_params.cc
@@ -24,7 +24,7 @@
 
 ParsedParams::~ParsedParams() = default;
 
-absl::optional<ParsedParams> ParseWebPluginParams(
+std::optional<ParsedParams> ParseWebPluginParams(
     const blink::WebPluginParams& params) {
   ParsedParams result;
   for (size_t i = 0; i < params.attribute_names.size(); ++i) {
@@ -39,7 +39,7 @@
     } else if (params.attribute_names[i] == "background-color") {
       if (!base::StringToUint(params.attribute_values[i].Utf8(),
                               &result.background_color)) {
-        return absl::nullopt;
+        return std::nullopt;
       }
     } else if (params.attribute_names[i] == "javascript") {
       if (params.attribute_values[i] != "allow")
@@ -52,7 +52,7 @@
   }
 
   if (result.src_url.empty())
-    return absl::nullopt;
+    return std::nullopt;
 
   if (result.original_url.empty())
     result.original_url = result.src_url;
diff --git a/pdf/parsed_params.h b/pdf/parsed_params.h
index 6ae4fddb..995dfe2 100644
--- a/pdf/parsed_params.h
+++ b/pdf/parsed_params.h
@@ -7,8 +7,8 @@
 
 #include <string>
 
+#include <optional>
 #include "pdf/pdfium/pdfium_form_filler.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkColor.h"
 
 namespace blink {
@@ -53,8 +53,8 @@
 };
 
 // Creates an `ParsedParams` by parsing a `blink::WebPluginParams`. If
-// `blink::WebPluginParams` is invalid, returns absl::nullopt.
-absl::optional<ParsedParams> ParseWebPluginParams(
+// `blink::WebPluginParams` is invalid, returns std::nullopt.
+std::optional<ParsedParams> ParseWebPluginParams(
     const blink::WebPluginParams& params);
 
 }  // namespace chrome_pdf
diff --git a/pdf/parsed_params_unittest.cc b/pdf/parsed_params_unittest.cc
index 9d165c6..02e7b4d4 100644
--- a/pdf/parsed_params_unittest.cc
+++ b/pdf/parsed_params_unittest.cc
@@ -6,10 +6,10 @@
 
 #include <string>
 
+#include <optional>
 #include "pdf/pdfium/pdfium_form_filler.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/platform/web_string.h"
 #include "third_party/blink/public/platform/web_vector.h"
 #include "third_party/blink/public/web/web_plugin_params.h"
@@ -36,7 +36,7 @@
 TEST(ParsedParamsTest, ParseWebPluginParamsMinimal) {
   blink::WebPluginParams params = CreateMinimalWebPluginParams();
 
-  absl::optional<ParsedParams> result = ParseWebPluginParams(params);
+  std::optional<ParsedParams> result = ParseWebPluginParams(params);
   ASSERT_TRUE(result.has_value());
 
   EXPECT_EQ(kFakeSrcUrl, result->src_url);
@@ -52,7 +52,7 @@
 TEST(ParsedParamsTest, ParseWebPluginParamsWithoutSourceUrl) {
   blink::WebPluginParams params;
 
-  absl::optional<ParsedParams> result = ParseWebPluginParams(params);
+  std::optional<ParsedParams> result = ParseWebPluginParams(params);
   EXPECT_FALSE(result.has_value());
 }
 
@@ -62,7 +62,7 @@
   params.attribute_values.push_back(
       blink::WebString("https://example.com/original.pdf"));
 
-  absl::optional<ParsedParams> result = ParseWebPluginParams(params);
+  std::optional<ParsedParams> result = ParseWebPluginParams(params);
   ASSERT_TRUE(result.has_value());
 
   EXPECT_EQ(kFakeSrcUrl, result->src_url);
@@ -75,7 +75,7 @@
   params.attribute_values.push_back(
       blink::WebString("https://example.net/top.html"));
 
-  absl::optional<ParsedParams> result = ParseWebPluginParams(params);
+  std::optional<ParsedParams> result = ParseWebPluginParams(params);
   ASSERT_TRUE(result.has_value());
 
   EXPECT_EQ("https://example.net/top.html", result->top_level_url);
@@ -86,7 +86,7 @@
   params.attribute_names.push_back(blink::WebString("full-frame"));
   params.attribute_values.push_back(blink::WebString(""));
 
-  absl::optional<ParsedParams> result = ParseWebPluginParams(params);
+  std::optional<ParsedParams> result = ParseWebPluginParams(params);
   ASSERT_TRUE(result.has_value());
 
   EXPECT_TRUE(result->full_frame);
@@ -97,7 +97,7 @@
   params.attribute_names.push_back(blink::WebString("full-frame"));
   params.attribute_values.push_back(blink::WebString("false"));
 
-  absl::optional<ParsedParams> result = ParseWebPluginParams(params);
+  std::optional<ParsedParams> result = ParseWebPluginParams(params);
   ASSERT_TRUE(result.has_value());
 
   EXPECT_TRUE(result->full_frame);
@@ -108,7 +108,7 @@
   params.attribute_names.push_back(blink::WebString("background-color"));
   params.attribute_values.push_back(blink::WebString("4283586137"));
 
-  absl::optional<ParsedParams> result = ParseWebPluginParams(params);
+  std::optional<ParsedParams> result = ParseWebPluginParams(params);
   ASSERT_TRUE(result.has_value());
 
   EXPECT_EQ(4283586137, result->background_color);
@@ -119,7 +119,7 @@
   params.attribute_names.push_back(blink::WebString("background-color"));
   params.attribute_values.push_back(blink::WebString("red"));
 
-  absl::optional<ParsedParams> result = ParseWebPluginParams(params);
+  std::optional<ParsedParams> result = ParseWebPluginParams(params);
   EXPECT_FALSE(result.has_value());
 }
 
@@ -128,7 +128,7 @@
   params.attribute_names.push_back(blink::WebString("javascript"));
   params.attribute_values.push_back(blink::WebString("allow"));
 
-  absl::optional<ParsedParams> result = ParseWebPluginParams(params);
+  std::optional<ParsedParams> result = ParseWebPluginParams(params);
   ASSERT_TRUE(result.has_value());
 
   EXPECT_THAT(result->script_option,
@@ -141,7 +141,7 @@
   params.attribute_names.push_back(blink::WebString("javascript"));
   params.attribute_values.push_back(blink::WebString(""));
 
-  absl::optional<ParsedParams> result = ParseWebPluginParams(params);
+  std::optional<ParsedParams> result = ParseWebPluginParams(params);
   ASSERT_TRUE(result.has_value());
 
   EXPECT_EQ(PDFiumFormFiller::ScriptOption::kNoJavaScript,
@@ -153,7 +153,7 @@
   params.attribute_names.push_back(blink::WebString("javascript"));
   params.attribute_values.push_back(blink::WebString("true"));
 
-  absl::optional<ParsedParams> result = ParseWebPluginParams(params);
+  std::optional<ParsedParams> result = ParseWebPluginParams(params);
   ASSERT_TRUE(result.has_value());
 
   EXPECT_EQ(PDFiumFormFiller::ScriptOption::kNoJavaScript,
@@ -165,7 +165,7 @@
   params.attribute_names.push_back(blink::WebString("has-edits"));
   params.attribute_values.push_back(blink::WebString(""));
 
-  absl::optional<ParsedParams> result = ParseWebPluginParams(params);
+  std::optional<ParsedParams> result = ParseWebPluginParams(params);
   ASSERT_TRUE(result.has_value());
 
   EXPECT_TRUE(result->has_edits);
@@ -176,7 +176,7 @@
   params.attribute_names.push_back(blink::WebString("has-edits"));
   params.attribute_values.push_back(blink::WebString("false"));
 
-  absl::optional<ParsedParams> result = ParseWebPluginParams(params);
+  std::optional<ParsedParams> result = ParseWebPluginParams(params);
   ASSERT_TRUE(result.has_value());
 
   EXPECT_TRUE(result->has_edits);
@@ -187,7 +187,7 @@
   params.attribute_names.push_back(blink::WebString("use-skia"));
   params.attribute_values.push_back(blink::WebString(""));
 
-  absl::optional<ParsedParams> result = ParseWebPluginParams(params);
+  std::optional<ParsedParams> result = ParseWebPluginParams(params);
   ASSERT_TRUE(result.has_value());
 
   EXPECT_TRUE(result->use_skia);
@@ -198,7 +198,7 @@
   params.attribute_names.push_back(blink::WebString("use-skia"));
   params.attribute_values.push_back(blink::WebString("false"));
 
-  absl::optional<ParsedParams> result = ParseWebPluginParams(params);
+  std::optional<ParsedParams> result = ParseWebPluginParams(params);
   ASSERT_TRUE(result.has_value());
 
   EXPECT_TRUE(result->use_skia);
diff --git a/pdf/pdf.cc b/pdf/pdf.cc
index 9170b05..a3944f4 100644
--- a/pdf/pdf.cc
+++ b/pdf/pdf.cc
@@ -8,12 +8,12 @@
 
 #include <utility>
 
+#include <optional>
 #include "base/feature_list.h"
 #include "build/build_config.h"
 #include "pdf/pdf_engine.h"
 #include "pdf/pdf_features.h"
 #include "pdf/pdf_init.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size_f.h"
 
@@ -21,7 +21,7 @@
 
 namespace {
 
-absl::optional<bool> g_use_skia_renderer_enabled_by_policy;
+std::optional<bool> g_use_skia_renderer_enabled_by_policy;
 
 class ScopedSdkInitializer {
  public:
@@ -98,7 +98,7 @@
   return engine_exports->GetPDFDocInfo(pdf_buffer, page_count, max_page_width);
 }
 
-absl::optional<bool> IsPDFDocTagged(base::span<const uint8_t> pdf_buffer) {
+std::optional<bool> IsPDFDocTagged(base::span<const uint8_t> pdf_buffer) {
   ScopedSdkInitializer scoped_sdk_initializer(/*enable_v8=*/true);
   PDFEngineExports* engine_exports = PDFEngineExports::Get();
   return engine_exports->IsPDFDocTagged(pdf_buffer);
@@ -111,7 +111,7 @@
   return engine_exports->GetPDFStructTreeForPage(pdf_buffer, page_index);
 }
 
-absl::optional<gfx::SizeF> GetPDFPageSizeByIndex(
+std::optional<gfx::SizeF> GetPDFPageSizeByIndex(
     base::span<const uint8_t> pdf_buffer,
     int page_index) {
   ScopedSdkInitializer scoped_sdk_initializer(/*enable_v8=*/true);
diff --git a/pdf/pdf.h b/pdf/pdf.h
index f53e7ea..aa2de18c 100644
--- a/pdf/pdf.h
+++ b/pdf/pdf.h
@@ -102,7 +102,7 @@
 // Whether the PDF is Tagged (see 10.7 "Tagged PDF" in PDF Reference 1.7).
 // Returns true if it's a tagged (accessible) PDF, false if it's a valid
 // PDF but untagged, and nullopt if the PDF can't be parsed.
-absl::optional<bool> IsPDFDocTagged(base::span<const uint8_t> pdf_buffer);
+std::optional<bool> IsPDFDocTagged(base::span<const uint8_t> pdf_buffer);
 
 // Given a tagged PDF (see IsPDFDocTagged, above), return the portion of
 // the structure tree for a given page as a hierarchical tree of base::Values.
@@ -115,7 +115,7 @@
 // `page_index` is the page number that the function will get the dimensions of.
 // Returns the size of the page in points, or nullopt if the document or the
 // page number are not valid.
-absl::optional<gfx::SizeF> GetPDFPageSizeByIndex(
+std::optional<gfx::SizeF> GetPDFPageSizeByIndex(
     base::span<const uint8_t> pdf_buffer,
     int page_index);
 
diff --git a/pdf/pdf_engine.h b/pdf/pdf_engine.h
index 7e4868d..fcd9428 100644
--- a/pdf/pdf_engine.h
+++ b/pdf/pdf_engine.h
@@ -11,6 +11,7 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/containers/span.h"
 #include "base/functional/callback.h"
 #include "base/time/time.h"
@@ -18,7 +19,6 @@
 #include "build/build_config.h"
 #include "pdf/document_layout.h"
 #include "printing/mojom/print.mojom-forward.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/base/cursor/mojom/cursor_type.mojom-forward.h"
 #include "ui/base/window_open_disposition.h"
@@ -366,7 +366,7 @@
   // Gets the number of pages in the document.
   virtual int GetNumberOfPages() const = 0;
   // Gets the named destination by name.
-  virtual absl::optional<PDFEngine::NamedDestination> GetNamedDestination(
+  virtual std::optional<PDFEngine::NamedDestination> GetNamedDestination(
       const std::string& destination) = 0;
   // Gets the index of the most visible page, or -1 if none are visible.
   virtual int GetMostVisiblePage() = 0;
@@ -390,9 +390,9 @@
   virtual uint32_t GetCharUnicode(int page_index, int char_index) = 0;
   // Given a start char index, find the longest continuous run of text that's
   // in a single direction and with the same text style. Return a filled out
-  // AccessibilityTextRunInfo on success or absl::nullopt on failure. e.g. When
+  // AccessibilityTextRunInfo on success or std::nullopt on failure. e.g. When
   // `start_char_index` is out of bounds.
-  virtual absl::optional<AccessibilityTextRunInfo> GetTextRunInfo(
+  virtual std::optional<AccessibilityTextRunInfo> GetTextRunInfo(
       int page_index,
       int start_char_index) = 0;
   // For all the links on page `page_index`, get their urls, underlying text
@@ -429,8 +429,8 @@
   // Returns the duplex setting.
   virtual printing::mojom::DuplexMode GetDuplexMode() = 0;
   // Returns the uniform page size of the document in points. Returns
-  // `absl::nullopt` if the document has more than one page size.
-  virtual absl::optional<gfx::Size> GetUniformPageSizePoints() = 0;
+  // `std::nullopt` if the document has more than one page size.
+  virtual std::optional<gfx::Size> GetUniformPageSizePoints() = 0;
 
   // Returns a list of Values of Bookmarks. Each Bookmark is a dictionary Value
   // which contains the following key/values:
@@ -551,7 +551,7 @@
   // Whether the PDF is Tagged (see 10.7 "Tagged PDF" in PDF Reference 1.7).
   // Returns true if it's a tagged (accessible) PDF, false if it's a valid
   // PDF but untagged, and nullopt if the PDF can't be parsed.
-  virtual absl::optional<bool> IsPDFDocTagged(
+  virtual std::optional<bool> IsPDFDocTagged(
       base::span<const uint8_t> pdf_buffer) = 0;
 
   // Given a tagged PDF (see IsPDFDocTagged, above), return the portion of
@@ -561,7 +561,7 @@
       int page_index) = 0;
 
   // See the definition of GetPDFPageSizeByIndex in pdf.cc for details.
-  virtual absl::optional<gfx::SizeF> GetPDFPageSizeByIndex(
+  virtual std::optional<gfx::SizeF> GetPDFPageSizeByIndex(
       base::span<const uint8_t> pdf_buffer,
       int page_index) = 0;
 };
diff --git a/pdf/pdf_utils/dates.cc b/pdf/pdf_utils/dates.cc
index 0b16fda..ed1cd04 100644
--- a/pdf/pdf_utils/dates.cc
+++ b/pdf/pdf_utils/dates.cc
@@ -6,11 +6,11 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "base/time/time.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace chrome_pdf {
 
@@ -27,9 +27,9 @@
   // Pops the first `num_digits` characters from the string and converts them to
   // an int if possible. Popping too many characters or characters that cannot
   // be converted puts the deserializer in a stopped state.
-  absl::optional<int> PopDigits(size_t num_digits) {
+  std::optional<int> PopDigits(size_t num_digits) {
     if (stopped_)
-      return absl::nullopt;
+      return std::nullopt;
 
     // `base::StringToUint()` allows leading sign characters, so also verify
     // that the front character is a digit.
@@ -38,7 +38,7 @@
         !base::IsAsciiDigit(deserializing_.front()) ||
         !base::StringToUint(deserializing_.substr(0, num_digits), &value)) {
       stopped_ = true;
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     // Pop front characters.
@@ -47,14 +47,14 @@
   }
 
   // Pops the front character if it is not a digit. Otherwise, does not change
-  // the state of the deserializer and returns `absl::nullopt`.
-  absl::optional<char> TryPopNonDigit() {
+  // the state of the deserializer and returns `std::nullopt`.
+  std::optional<char> TryPopNonDigit() {
     if (stopped_ || deserializing_.empty())
-      return absl::nullopt;
+      return std::nullopt;
 
     const char front = deserializing_.front();
     if (base::IsAsciiDigit(front))
-      return absl::nullopt;
+      return std::nullopt;
 
     deserializing_ = deserializing_.substr(1);
     return front;
@@ -76,7 +76,7 @@
   base::TimeDelta offset;
 
   // UTC is assumed if no time zone information is provided.
-  const absl::optional<char> sign = deserializer.TryPopNonDigit();
+  const std::optional<char> sign = deserializer.TryPopNonDigit();
   if (!sign.has_value() || (sign.value() != '+' && sign.value() != '-'))
     return offset;
 
@@ -84,7 +84,7 @@
 
   // The spec requires that the hours offset be followed by an apostrophe, but
   // don't be strict about its presence.
-  const absl::optional<char> apostrophe = deserializer.TryPopNonDigit();
+  const std::optional<char> apostrophe = deserializer.TryPopNonDigit();
   if (apostrophe.has_value() && apostrophe.value() != '\'')
     return sign.value() == '+' ? offset : -offset;
 
@@ -108,7 +108,7 @@
   DateDeserializer deserializer(date);
 
   // Year is the only required part of a valid date.
-  const absl::optional<int> deserialized_year = deserializer.PopDigits(4);
+  const std::optional<int> deserialized_year = deserializer.PopDigits(4);
   if (!deserialized_year.has_value())
     return base::Time();
 
diff --git a/pdf/pdf_view_web_plugin.cc b/pdf/pdf_view_web_plugin.cc
index 55693fe..6055005 100644
--- a/pdf/pdf_view_web_plugin.cc
+++ b/pdf/pdf_view_web_plugin.cc
@@ -314,7 +314,7 @@
   // Allow the plugin to handle find requests.
   client_->UsePluginAsFindHandler();
 
-  absl::optional<ParsedParams> params = ParseWebPluginParams(initial_params_);
+  std::optional<ParsedParams> params = ParseWebPluginParams(initial_params_);
 
   // The contents of `initial_params_` are no longer needed.
   initial_params_ = {};
@@ -1342,7 +1342,7 @@
 
 void PdfViewWebPlugin::HandleGetNamedDestinationMessage(
     const base::Value::Dict& message) {
-  absl::optional<PDFEngine::NamedDestination> named_destination =
+  std::optional<PDFEngine::NamedDestination> named_destination =
       engine_->GetNamedDestination(*message.FindString("namedDestination"));
 
   const int page_number = named_destination.has_value()
diff --git a/pdf/pdf_view_web_plugin.h b/pdf/pdf_view_web_plugin.h
index e4a1818..11b8734 100644
--- a/pdf/pdf_view_web_plugin.h
+++ b/pdf/pdf_view_web_plugin.h
@@ -801,7 +801,7 @@
   std::vector<int> pages_to_print_;
 
   // Assigned a value only between `PrintBegin()` and `PrintEnd()` calls.
-  absl::optional<blink::WebPrintParams> print_params_;
+  std::optional<blink::WebPrintParams> print_params_;
 
   // For identifying actual print operations to avoid double logging of UMA.
   bool print_pages_called_;
diff --git a/pdf/pdf_view_web_plugin_unittest.cc b/pdf/pdf_view_web_plugin_unittest.cc
index 88739fc5..be70915 100644
--- a/pdf/pdf_view_web_plugin_unittest.cc
+++ b/pdf/pdf_view_web_plugin_unittest.cc
@@ -1771,7 +1771,7 @@
       return bookmarks;
     }
 
-    absl::optional<gfx::Size> GetUniformPageSizePoints() override {
+    std::optional<gfx::Size> GetUniformPageSizePoints() override {
       return gfx::Size(1000, 1200);
     }
 
diff --git a/pdf/pdfium/findtext_unittest.cc b/pdf/pdfium/findtext_unittest.cc
index 853d673..80b42ed 100644
--- a/pdf/pdfium/findtext_unittest.cc
+++ b/pdf/pdfium/findtext_unittest.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <optional>
 #include "base/check_op.h"
 #include "base/strings/utf_string_conversions.h"
 #include "pdf/document_layout.h"
@@ -9,7 +10,6 @@
 #include "pdf/pdfium/pdfium_test_base.h"
 #include "pdf/test/test_client.h"
 #include "testing/gmock/include/gmock/gmock.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using testing::_;
 using testing::InSequence;
diff --git a/pdf/pdfium/pdfium_api_string_buffer_adapter.h b/pdf/pdfium/pdfium_api_string_buffer_adapter.h
index 34951266..90c1e26 100644
--- a/pdf/pdfium/pdfium_api_string_buffer_adapter.h
+++ b/pdf/pdfium/pdfium_api_string_buffer_adapter.h
@@ -9,10 +9,10 @@
 
 #include <string>
 
+#include <optional>
 #include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/numerics/safe_math.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace chrome_pdf {
 
@@ -104,12 +104,12 @@
           class StringType,
           typename BufferType,
           typename ReturnType>
-absl::optional<StringType> CallPDFiumStringBufferApiAndReturnOptional(
+std::optional<StringType> CallPDFiumStringBufferApiAndReturnOptional(
     base::RepeatingCallback<ReturnType(BufferType*, ReturnType)> api,
     bool check_expected_size) {
   ReturnType expected_size = api.Run(nullptr, 0);
   if (expected_size == 0)
-    return absl::nullopt;
+    return std::nullopt;
 
   StringType str;
   AdapterType api_string_adapter(&str, expected_size, check_expected_size);
@@ -125,7 +125,7 @@
 StringType CallPDFiumStringBufferApi(
     base::RepeatingCallback<ReturnType(BufferType*, ReturnType)> api,
     bool check_expected_size) {
-  absl::optional<StringType> result =
+  std::optional<StringType> result =
       CallPDFiumStringBufferApiAndReturnOptional<AdapterType, StringType>(
           api, check_expected_size);
   return result.value_or(StringType());
@@ -147,7 +147,7 @@
 // Variant of CallPDFiumWideStringBufferApi() that distinguishes between API
 // call failures and empty string return values.
 template <typename BufferType>
-absl::optional<std::u16string> CallPDFiumWideStringBufferApiAndReturnOptional(
+std::optional<std::u16string> CallPDFiumWideStringBufferApiAndReturnOptional(
     base::RepeatingCallback<unsigned long(BufferType*, unsigned long)> api,
     bool check_expected_size) {
   using adapter_type = internal::PDFiumAPIStringBufferSizeInBytesAdapter;
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc
index 6eaee272..3d46297 100644
--- a/pdf/pdfium/pdfium_engine.cc
+++ b/pdf/pdfium/pdfium_engine.cc
@@ -2407,9 +2407,9 @@
     if (PageIndexInBounds(page_index)) {
       dict.Set("page", page_index);
 
-      absl::optional<float> x;
-      absl::optional<float> y;
-      absl::optional<float> zoom;
+      std::optional<float> x;
+      std::optional<float> y;
+      std::optional<float> zoom;
       pages_[page_index]->GetPageDestinationTarget(dest, &x, &y, &zoom);
 
       if (x)
@@ -2512,7 +2512,7 @@
   client_->ScrollBy(scroll_offset - global_point);
 }
 
-absl::optional<PDFEngine::NamedDestination> PDFiumEngine::GetNamedDestination(
+std::optional<PDFEngine::NamedDestination> PDFiumEngine::GetNamedDestination(
     const std::string& destination) {
   // Look for the destination.
   FPDF_DEST dest = FPDF_GetNamedDestByName(doc(), destination.c_str());
@@ -2607,7 +2607,7 @@
   return pages_[page_index]->GetCharUnicode(char_index);
 }
 
-absl::optional<AccessibilityTextRunInfo> PDFiumEngine::GetTextRunInfo(
+std::optional<AccessibilityTextRunInfo> PDFiumEngine::GetTextRunInfo(
     int page_index,
     int start_char_index) {
   DCHECK(PageIndexInBounds(page_index));
@@ -2668,14 +2668,14 @@
   }
 }
 
-absl::optional<gfx::Size> PDFiumEngine::GetUniformPageSizePoints() {
+std::optional<gfx::Size> PDFiumEngine::GetUniformPageSizePoints() {
   if (pages_.empty())
-    return absl::nullopt;
+    return std::nullopt;
 
   gfx::Size page_size = GetPageSize(0);
   for (size_t i = 1; i < pages_.size(); ++i) {
     if (page_size != GetPageSize(i))
-      return absl::nullopt;
+      return std::nullopt;
   }
 
   // Convert `page_size` back to points.
@@ -3140,19 +3140,19 @@
       static_cast<int>(ceil(inset_sizes.right * multiplier))));
 }
 
-absl::optional<size_t> PDFiumEngine::GetAdjacentPageIndexForTwoUpView(
+std::optional<size_t> PDFiumEngine::GetAdjacentPageIndexForTwoUpView(
     size_t page_index,
     size_t num_of_pages) const {
   DCHECK_LT(page_index, num_of_pages);
 
   if (layout_.options().page_spread() == DocumentLayout::PageSpread::kOneUp) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   int adjacent_page_offset = page_index % 2 ? -1 : 1;
   size_t adjacent_page_index = page_index + adjacent_page_offset;
   if (adjacent_page_index >= num_of_pages)
-    return absl::nullopt;
+    return std::nullopt;
 
   return adjacent_page_index;
 }
@@ -3337,7 +3337,7 @@
   int page_index = progressive_paints_[progressive_index].page_index();
   gfx::Rect dirty_in_screen = progressive_paints_[progressive_index].rect();
 
-  const absl::optional<RegionData> region =
+  const std::optional<RegionData> region =
       GetRegion(dirty_in_screen.origin(), image_data);
   if (!region.has_value()) {
     return;
@@ -3404,8 +3404,7 @@
 ScopedFPDFBitmap PDFiumEngine::CreateBitmap(const gfx::Rect& rect,
                                             bool has_alpha,
                                             SkBitmap& image_data) const {
-  const absl::optional<RegionData> region =
-      GetRegion(rect.origin(), image_data);
+  const std::optional<RegionData> region = GetRegion(rect.origin(), image_data);
   if (!region.has_value()) {
     return nullptr;
   }
@@ -3462,7 +3461,7 @@
       GetInsetSizes(layout_.options(), page_index, pages_.size());
 
   int max_page_height = page_rect.height();
-  absl::optional<size_t> adjacent_page_index =
+  std::optional<size_t> adjacent_page_index =
       GetAdjacentPageIndexForTwoUpView(page_index, pages_.size());
   if (adjacent_page_index.has_value()) {
     max_page_height = std::max(
@@ -3723,24 +3722,24 @@
   DrawShadow(image_data, shadow_rect, page_rect, clip_rect, *page_shadow_);
 }
 
-absl::optional<PDFiumEngine::RegionData> PDFiumEngine::GetRegion(
+std::optional<PDFiumEngine::RegionData> PDFiumEngine::GetRegion(
     const gfx::Point& location,
     SkBitmap& image_data) const {
   if (image_data.isNull()) {
     DCHECK(plugin_size().IsEmpty());
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   uint8_t* buffer = static_cast<uint8_t*>(image_data.getPixels());
   if (!buffer) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   gfx::Point offset_location = location + page_offset_;
   // TODO: update this when we support BIDI and scrollbars can be on the left.
   if (!gfx::Rect(gfx::PointAtOffsetFromOrigin(page_offset_), plugin_size())
            .Contains(offset_location)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   size_t stride = image_data.rowBytes();
diff --git a/pdf/pdfium/pdfium_engine.h b/pdf/pdfium/pdfium_engine.h
index 663d5c4..b1740cd 100644
--- a/pdf/pdfium/pdfium_engine.h
+++ b/pdf/pdfium/pdfium_engine.h
@@ -13,6 +13,7 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/check.h"
 #include "base/containers/flat_map.h"
 #include "base/containers/span.h"
@@ -31,7 +32,6 @@
 #include "pdf/pdfium/pdfium_page.h"
 #include "pdf/pdfium/pdfium_print.h"
 #include "pdf/pdfium/pdfium_range.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/pdfium/public/cpp/fpdf_scopers.h"
 #include "third_party/pdfium/public/fpdf_formfill.h"
 #include "third_party/pdfium/public/fpdf_progressive.h"
@@ -140,7 +140,7 @@
   const DocumentMetadata& GetDocumentMetadata() const override;
   int GetNumberOfPages() const override;
   base::Value::List GetBookmarks() override;
-  absl::optional<PDFEngine::NamedDestination> GetNamedDestination(
+  std::optional<PDFEngine::NamedDestination> GetNamedDestination(
       const std::string& destination) override;
   int GetMostVisiblePage() override;
   gfx::Rect GetPageBoundsRect(int index) override;
@@ -151,7 +151,7 @@
   int GetCharCount(int page_index) override;
   gfx::RectF GetCharBounds(int page_index, int char_index) override;
   uint32_t GetCharUnicode(int page_index, int char_index) override;
-  absl::optional<AccessibilityTextRunInfo> GetTextRunInfo(
+  std::optional<AccessibilityTextRunInfo> GetTextRunInfo(
       int page_index,
       int start_char_index) override;
   std::vector<AccessibilityLinkInfo> GetLinkInfo(
@@ -170,7 +170,7 @@
   bool GetPrintScaling() override;
   int GetCopiesToPrint() override;
   printing::mojom::DuplexMode GetDuplexMode() override;
-  absl::optional<gfx::Size> GetUniformPageSizePoints() override;
+  std::optional<gfx::Size> GetUniformPageSizePoints() override;
   void AppendBlankPages(size_t num_pages) override;
   void AppendPage(PDFEngine* engine, int index) override;
   std::vector<uint8_t> GetSaveData() override;
@@ -393,9 +393,9 @@
                  gfx::Rect& rect) const;
 
   // If two-up view is enabled, returns the index of the page beside
-  // `page_index` page. Returns absl::nullopt if there is no adjacent page or
+  // `page_index` page. Returns std::nullopt if there is no adjacent page or
   // if two-up view is disabled.
-  absl::optional<size_t> GetAdjacentPageIndexForTwoUpView(
+  std::optional<size_t> GetAdjacentPageIndexForTwoUpView(
       size_t page_index,
       size_t num_of_pages) const;
 
@@ -558,8 +558,8 @@
                       const gfx::Rect& clip_rect,
                       SkBitmap& image_data);
 
-  absl::optional<RegionData> GetRegion(const gfx::Point& location,
-                                       SkBitmap& image_data) const;
+  std::optional<RegionData> GetRegion(const gfx::Point& location,
+                                      SkBitmap& image_data) const;
 
   // Called when the selection changes.
   void OnSelectionTextChanged();
@@ -680,7 +680,7 @@
   // The offset of the page into the viewport.
   gfx::Vector2d page_offset_;
   // The plugin size in screen coordinates.
-  absl::optional<gfx::Size> plugin_size_;
+  std::optional<gfx::Size> plugin_size_;
   double current_zoom_ = 1.0;
   // The caret position and bound in plugin viewport coordinates.
   gfx::Rect caret_rect_;
@@ -754,9 +754,9 @@
   int last_page_to_search_ = -1;
   int last_character_index_to_search_ = -1;  // -1 if search until end of page.
   // Which result the user has currently selected. (0-based)
-  absl::optional<size_t> current_find_index_;
+  std::optional<size_t> current_find_index_;
   // Where to resume searching. (0-based)
-  absl::optional<size_t> resume_find_index_;
+  std::optional<size_t> resume_find_index_;
 
   std::unique_ptr<PDFiumPermissions> permissions_;
 
@@ -797,7 +797,7 @@
 
   // Holds the page index requested by PDFium while the scroll operation
   // is being handled (asynchronously).
-  absl::optional<int> in_flight_visible_page_;
+  std::optional<int> in_flight_visible_page_;
 
   // Set to true after FORM_DoDocumentJSAction/FORM_DoDocumentOpenAction have
   // been called. Only after that can we call FORM_DoPageAAction.
diff --git a/pdf/pdfium/pdfium_engine_exports.cc b/pdf/pdfium/pdfium_engine_exports.cc
index 973241bc..94a3aa69 100644
--- a/pdf/pdfium/pdfium_engine_exports.cc
+++ b/pdf/pdfium/pdfium_engine_exports.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 #include <utility>
 
+#include <optional>
 #include "base/functional/bind.h"
 #include "base/no_destructor.h"
 #include "build/build_config.h"
@@ -16,7 +17,6 @@
 #include "pdf/pdfium/pdfium_unsupported_features.h"
 #include "printing/nup_parameters.h"
 #include "printing/units.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/pdfium/public/cpp/fpdf_scopers.h"
 #include "third_party/pdfium/public/fpdf_catalog.h"
 #include "third_party/pdfium/public/fpdf_ppo.h"
@@ -151,7 +151,7 @@
   if (children_count <= 0)
     return base::Value();
 
-  absl::optional<std::u16string> opt_type =
+  std::optional<std::u16string> opt_type =
       CallPDFiumWideStringBufferApiAndReturnOptional(
           base::BindRepeating(FPDF_StructElement_GetType, struct_elem), true);
   if (!opt_type)
@@ -160,14 +160,14 @@
   base::Value::Dict result;
   result.Set("type", *opt_type);
 
-  absl::optional<std::u16string> opt_alt =
+  std::optional<std::u16string> opt_alt =
       CallPDFiumWideStringBufferApiAndReturnOptional(
           base::BindRepeating(FPDF_StructElement_GetAltText, struct_elem),
           true);
   if (opt_alt)
     result.Set("alt", *opt_alt);
 
-  absl::optional<std::u16string> opt_lang =
+  std::optional<std::u16string> opt_lang =
       CallPDFiumWideStringBufferApiAndReturnOptional(
           base::BindRepeating(FPDF_StructElement_GetLang, struct_elem), true);
   if (opt_lang)
@@ -411,13 +411,13 @@
   return true;
 }
 
-absl::optional<bool> PDFiumEngineExports::IsPDFDocTagged(
+std::optional<bool> PDFiumEngineExports::IsPDFDocTagged(
     base::span<const uint8_t> pdf_buffer) {
   ScopedUnsupportedFeature scoped_unsupported_feature(
       ScopedUnsupportedFeature::kNoEngine);
   ScopedFPDFDocument doc = LoadPdfData(pdf_buffer);
   if (!doc)
-    return absl::nullopt;
+    return std::nullopt;
 
   return FPDFCatalog_IsTagged(doc.get());
 }
@@ -452,18 +452,18 @@
   return RecursiveGetStructTree(struct_root_elem);
 }
 
-absl::optional<gfx::SizeF> PDFiumEngineExports::GetPDFPageSizeByIndex(
+std::optional<gfx::SizeF> PDFiumEngineExports::GetPDFPageSizeByIndex(
     base::span<const uint8_t> pdf_buffer,
     int page_index) {
   ScopedUnsupportedFeature scoped_unsupported_feature(
       ScopedUnsupportedFeature::kNoEngine);
   ScopedFPDFDocument doc = LoadPdfData(pdf_buffer);
   if (!doc)
-    return absl::nullopt;
+    return std::nullopt;
 
   FS_SIZEF size;
   if (!FPDF_GetPageSizeByIndexF(doc.get(), page_index, &size))
-    return absl::nullopt;
+    return std::nullopt;
 
   return gfx::SizeF(size.width, size.height);
 }
diff --git a/pdf/pdfium/pdfium_engine_exports.h b/pdf/pdfium/pdfium_engine_exports.h
index c6cc7f6..c7e72548 100644
--- a/pdf/pdfium/pdfium_engine_exports.h
+++ b/pdf/pdfium/pdfium_engine_exports.h
@@ -49,11 +49,11 @@
   bool GetPDFDocInfo(base::span<const uint8_t> pdf_buffer,
                      int* page_count,
                      float* max_page_width) override;
-  absl::optional<bool> IsPDFDocTagged(
+  std::optional<bool> IsPDFDocTagged(
       base::span<const uint8_t> pdf_buffer) override;
   base::Value GetPDFStructTreeForPage(base::span<const uint8_t> pdf_buffer,
                                       int page_index) override;
-  absl::optional<gfx::SizeF> GetPDFPageSizeByIndex(
+  std::optional<gfx::SizeF> GetPDFPageSizeByIndex(
       base::span<const uint8_t> pdf_buffer,
       int page_index) override;
 };
diff --git a/pdf/pdfium/pdfium_engine_exports_unittest.cc b/pdf/pdfium/pdfium_engine_exports_unittest.cc
index 09fd4866..926e9be0 100644
--- a/pdf/pdfium/pdfium_engine_exports_unittest.cc
+++ b/pdf/pdfium/pdfium_engine_exports_unittest.cc
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <optional>
 #include "base/files/file_util.h"
 #include "base/path_service.h"
 #include "pdf/pdf.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/geometry/size_f.h"
@@ -67,7 +67,7 @@
   ASSERT_TRUE(GetPDFDocInfo(pdf_span, &page_count, nullptr));
   ASSERT_EQ(2, page_count);
   for (int page_index = 0; page_index < page_count; ++page_index) {
-    absl::optional<gfx::SizeF> page_size =
+    std::optional<gfx::SizeF> page_size =
         GetPDFPageSizeByIndex(pdf_span, page_index);
     ASSERT_TRUE(page_size.has_value());
     EXPECT_EQ(gfx::SizeF(200, 200), page_size.value());
@@ -109,7 +109,7 @@
   ASSERT_TRUE(GetPDFDocInfo(output_pdf_span, &page_count, nullptr));
   ASSERT_EQ(1, page_count);
 
-  absl::optional<gfx::SizeF> page_size =
+  std::optional<gfx::SizeF> page_size =
       GetPDFPageSizeByIndex(output_pdf_span, 0);
   ASSERT_TRUE(page_size.has_value());
   EXPECT_EQ(gfx::SizeF(792, 612), page_size.value());
@@ -137,7 +137,7 @@
   ASSERT_TRUE(GetPDFDocInfo(output_pdf_span, &page_count, nullptr));
   ASSERT_EQ(2, page_count);
   for (int page_index = 0; page_index < page_count; ++page_index) {
-    absl::optional<gfx::SizeF> page_size =
+    std::optional<gfx::SizeF> page_size =
         GetPDFPageSizeByIndex(output_pdf_span, page_index);
     ASSERT_TRUE(page_size.has_value());
     EXPECT_EQ(gfx::SizeF(612, 792), page_size.value());
diff --git a/pdf/pdfium/pdfium_engine_unittest.cc b/pdf/pdfium/pdfium_engine_unittest.cc
index c6bfc67c..972d23d 100644
--- a/pdf/pdfium/pdfium_engine_unittest.cc
+++ b/pdf/pdfium/pdfium_engine_unittest.cc
@@ -523,7 +523,7 @@
   ASSERT_EQ(2, engine->GetNumberOfPages());
 
   // A destination with a valid page object
-  absl::optional<PDFEngine::NamedDestination> valid_page_obj =
+  std::optional<PDFEngine::NamedDestination> valid_page_obj =
       engine->GetNamedDestination("ValidPageObj");
   ASSERT_TRUE(valid_page_obj.has_value());
   EXPECT_EQ(0u, valid_page_obj->page);
@@ -532,18 +532,18 @@
   EXPECT_EQ(1.2f, valid_page_obj->params[2]);
 
   // A destination with an invalid page object
-  absl::optional<PDFEngine::NamedDestination> invalid_page_obj =
+  std::optional<PDFEngine::NamedDestination> invalid_page_obj =
       engine->GetNamedDestination("InvalidPageObj");
   ASSERT_FALSE(invalid_page_obj.has_value());
 
   // A destination with a valid page number
-  absl::optional<PDFEngine::NamedDestination> valid_page_number =
+  std::optional<PDFEngine::NamedDestination> valid_page_number =
       engine->GetNamedDestination("ValidPageNumber");
   ASSERT_TRUE(valid_page_number.has_value());
   EXPECT_EQ(1u, valid_page_number->page);
 
   // A destination with an out-of-range page number
-  absl::optional<PDFEngine::NamedDestination> invalid_page_number =
+  std::optional<PDFEngine::NamedDestination> invalid_page_number =
       engine->GetNamedDestination("OutOfRangePageNumber");
   EXPECT_FALSE(invalid_page_number.has_value());
 }
diff --git a/pdf/pdfium/pdfium_page.cc b/pdf/pdfium/pdfium_page.cc
index 18e0c52..5b840a7 100644
--- a/pdf/pdfium/pdfium_page.cc
+++ b/pdf/pdfium/pdfium_page.cc
@@ -459,14 +459,14 @@
   }
 }
 
-absl::optional<AccessibilityTextRunInfo> PDFiumPage::GetTextRunInfo(
+std::optional<AccessibilityTextRunInfo> PDFiumPage::GetTextRunInfo(
     int start_char_index) {
   FPDF_PAGE page = GetPage();
   FPDF_TEXTPAGE text_page = GetTextPage();
   int chars_count = FPDFText_CountChars(text_page);
   // Check to make sure `start_char_index` is within bounds.
   if (start_char_index < 0 || start_char_index >= chars_count)
-    return absl::nullopt;
+    return std::nullopt;
 
   int actual_start_char_index = GetFirstNonUnicodeWhiteSpaceCharIndex(
       text_page, start_char_index, chars_count);
@@ -1053,8 +1053,8 @@
 
   target->page = page_index;
 
-  absl::optional<float> x;
-  absl::optional<float> y;
+  std::optional<float> x;
+  std::optional<float> y;
   GetPageDestinationTarget(destination, &x, &y, &target->zoom);
 
   // The page where a destination exists can be different from the page that it
@@ -1077,12 +1077,12 @@
 }
 
 void PDFiumPage::GetPageDestinationTarget(FPDF_DEST destination,
-                                          absl::optional<float>* dest_x,
-                                          absl::optional<float>* dest_y,
-                                          absl::optional<float>* zoom_value) {
-  *dest_x = absl::nullopt;
-  *dest_y = absl::nullopt;
-  *zoom_value = absl::nullopt;
+                                          std::optional<float>* dest_x,
+                                          std::optional<float>* dest_y,
+                                          std::optional<float>* zoom_value) {
+  *dest_x = std::nullopt;
+  *dest_y = std::nullopt;
+  *zoom_value = std::nullopt;
   if (!available_)
     return;
 
diff --git a/pdf/pdfium/pdfium_page.h b/pdf/pdfium/pdfium_page.h
index 67fe82f..31c2ffef 100644
--- a/pdf/pdfium/pdfium_page.h
+++ b/pdf/pdfium/pdfium_page.h
@@ -10,13 +10,13 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/functional/callback.h"
 #include "base/functional/callback_forward.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
 #include "pdf/page_orientation.h"
 #include "pdf/pdf_engine.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/pdfium/public/cpp/fpdf_scopers.h"
 #include "third_party/pdfium/public/fpdf_doc.h"
 #include "third_party/pdfium/public/fpdf_formfill.h"
@@ -69,7 +69,7 @@
   FPDF_TEXTPAGE GetTextPage();
 
   // See definition of PDFEngine::GetTextRunInfo().
-  absl::optional<AccessibilityTextRunInfo> GetTextRunInfo(int start_char_index);
+  std::optional<AccessibilityTextRunInfo> GetTextRunInfo(int start_char_index);
 
   // Get a unicode character from the page.
   uint32_t GetCharUnicode(int char_index);
@@ -135,10 +135,10 @@
     // Valid for DOCLINK_AREA only.
     int page;
     // Valid for DOCLINK_AREA only. From the top-left of the page.
-    absl::optional<float> x_in_pixels;
-    absl::optional<float> y_in_pixels;
+    std::optional<float> x_in_pixels;
+    std::optional<float> y_in_pixels;
     // Valid for DOCLINK_AREA only.
-    absl::optional<float> zoom;
+    std::optional<float> zoom;
   };
 
   // Given a `link_index`, returns the type of underlying area and the link
@@ -153,9 +153,9 @@
   // Fills the output params with the in-page coordinates and the zoom value of
   // the destination.
   void GetPageDestinationTarget(FPDF_DEST destination,
-                                absl::optional<float>* dest_x,
-                                absl::optional<float>* dest_y,
-                                absl::optional<float>* zoom_value);
+                                std::optional<float>* dest_x,
+                                std::optional<float>* dest_y,
+                                std::optional<float>* zoom_value);
 
   // For a named destination with "XYZ" view fit type, pre-processes the in-page
   // x/y coordinate in case it's out of the range of the page dimension. Then
diff --git a/pdf/pdfium/pdfium_page_unittest.cc b/pdf/pdfium/pdfium_page_unittest.cc
index 7ecf983..bb2c7e6 100644
--- a/pdf/pdfium/pdfium_page_unittest.cc
+++ b/pdf/pdfium/pdfium_page_unittest.cc
@@ -7,6 +7,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/check.h"
 #include "base/files/file_path.h"
 #include "base/strings/string_util.h"
@@ -21,7 +22,6 @@
 #include "pdf/test/test_helpers.h"
 #include "pdf/ui/thumbnail.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/pdfium/public/fpdf_formfill.h"
 #include "third_party/skia/include/core/SkImage.h"
 #include "third_party/skia/include/core/SkImageInfo.h"
@@ -631,7 +631,7 @@
   constexpr int kFirstRunStartIndex = 0;
   constexpr int kFirstRunEndIndex = 20;
   constexpr int kPageIndex = 0;
-  absl::optional<AccessibilityTextRunInfo> text_run_info_1 =
+  std::optional<AccessibilityTextRunInfo> text_run_info_1 =
       engine->GetTextRunInfo(kPageIndex, kFirstRunStartIndex);
   ASSERT_TRUE(text_run_info_1.has_value());
 
@@ -667,7 +667,7 @@
   // Test the properties of second text run.
   // Note: The leading spaces in second text run are accounted for in the end
   // of first text run. Hence we won't see a space leading the second text run.
-  absl::optional<AccessibilityTextRunInfo> text_run_info_2 =
+  std::optional<AccessibilityTextRunInfo> text_run_info_2 =
       engine->GetTextRunInfo(kPageIndex, kSecondRunStartIndex);
   ASSERT_TRUE(text_run_info_2.has_value());
 
@@ -748,7 +748,7 @@
   }
 
   // Test negative char index returns nullopt
-  absl::optional<AccessibilityTextRunInfo> text_run_info_result =
+  std::optional<AccessibilityTextRunInfo> text_run_info_result =
       engine->GetTextRunInfo(0, -1);
   ASSERT_FALSE(text_run_info_result.has_value());
 
@@ -802,7 +802,7 @@
 
   int current_char_index = 0;
   for (const auto& expected_text_run : expected_text_runs) {
-    absl::optional<AccessibilityTextRunInfo> text_run_info_result =
+    std::optional<AccessibilityTextRunInfo> text_run_info_result =
         engine->GetTextRunInfo(0, current_char_index);
     ASSERT_TRUE(text_run_info_result.has_value());
     const auto& actual_text_run = text_run_info_result.value();
diff --git a/pdf/pdfium/pdfium_print_unittest.cc b/pdf/pdfium/pdfium_print_unittest.cc
index 802d593..85c18ab 100644
--- a/pdf/pdfium/pdfium_print_unittest.cc
+++ b/pdf/pdfium/pdfium_print_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <memory>
 
+#include <optional>
 #include "base/files/file_path.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/stringprintf.h"
@@ -17,7 +18,6 @@
 #include "printing/pdf_render_settings.h"
 #include "printing/units.h"
 #include "testing/gmock/include/gmock/gmock.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/web/web_print_params.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkImage.h"
@@ -69,7 +69,7 @@
   ASSERT_EQ(expected_dimensions.size(), static_cast<size_t>(page_count));
 
   for (int i = 0; i < page_count; ++i) {
-    absl::optional<gfx::SizeF> page_size =
+    std::optional<gfx::SizeF> page_size =
         exports.GetPDFPageSizeByIndex(pdf_data, i);
     ASSERT_TRUE(page_size.has_value());
     EXPECT_EQ(expected_dimensions[i], page_size.value());
diff --git a/pdf/ui/document_properties.cc b/pdf/ui/document_properties.cc
index 23ad0d0..8239d472 100644
--- a/pdf/ui/document_properties.cc
+++ b/pdf/ui/document_properties.cc
@@ -6,13 +6,13 @@
 
 #include <string>
 
+#include <optional>
 #include "base/i18n/number_formatting.h"
 #include "base/i18n/rtl.h"
 #include "base/strings/string_number_conversions.h"
 #include "components/strings/grit/components_strings.h"
 #include "pdf/document_metadata.h"
 #include "printing/units.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/icu/source/i18n/unicode/ulocdata.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/geometry/size.h"
@@ -75,7 +75,7 @@
 
 }  // namespace
 
-std::u16string FormatPageSize(const absl::optional<gfx::Size>& size_points) {
+std::u16string FormatPageSize(const std::optional<gfx::Size>& size_points) {
   if (!size_points.has_value())
     return l10n_util::GetStringUTF16(IDS_PDF_PROPERTIES_PAGE_SIZE_VARIABLE);
 
diff --git a/pdf/ui/document_properties.h b/pdf/ui/document_properties.h
index b9868ea..9214b4a 100644
--- a/pdf/ui/document_properties.h
+++ b/pdf/ui/document_properties.h
@@ -7,8 +7,8 @@
 
 #include <string>
 
+#include <optional>
 #include "pdf/document_metadata.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace gfx {
 class Size;
@@ -23,8 +23,8 @@
 // ->  210 x 297 mm (portrait)
 // ->  11.00 x 8.50 in (landscape)
 //
-// Returns the string "Varies" if `size_points` is `absl::nullopt`.
-std::u16string FormatPageSize(const absl::optional<gfx::Size>& size_points);
+// Returns the string "Varies" if `size_points` is `std::nullopt`.
+std::u16string FormatPageSize(const std::optional<gfx::Size>& size_points);
 
 // Formats `version` to a string suitable for display to a user. Version numbers
 // do not require localization.
diff --git a/pdf/ui/document_properties_unittest.cc b/pdf/ui/document_properties_unittest.cc
index 3b020a8..a26d56a3a 100644
--- a/pdf/ui/document_properties_unittest.cc
+++ b/pdf/ui/document_properties_unittest.cc
@@ -6,12 +6,12 @@
 
 #include <string>
 
+#include <optional>
 #include "base/i18n/number_formatting.h"
 #include "base/i18n/rtl.h"
 #include "pdf/document_metadata.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/size.h"
 
 namespace chrome_pdf {
@@ -44,7 +44,7 @@
 }  // namespace
 
 TEST_F(FormatPageSizeTest, NoUniformSize) {
-  EXPECT_EQ(FormatPageSize(absl::nullopt), u"Varies");
+  EXPECT_EQ(FormatPageSize(std::nullopt), u"Varies");
 }
 
 class FormatPageSizeMillimetersTest : public FormatPageSizeTest {
diff --git a/printing/backend/cups_helper.cc b/printing/backend/cups_helper.cc
index 7d908c8..b9a407ae 100644
--- a/printing/backend/cups_helper.cc
+++ b/printing/backend/cups_helper.cc
@@ -13,6 +13,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_file.h"
@@ -27,7 +28,6 @@
 #include "printing/print_job_constants_cups.h"
 #include "printing/printing_utils.h"
 #include "printing/units.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
 #include "url/gurl.h"
@@ -115,11 +115,11 @@
   return std::make_pair(std::move(duplex_modes), duplex_default);
 }
 
-absl::optional<gfx::Size> ParseResolutionString(const char* input) {
+std::optional<gfx::Size> ParseResolutionString(const char* input) {
   int len = strlen(input);
   if (len == 0) {
     VLOG(1) << "Bad PPD resolution choice: null string";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   int n = 0;  // number of chars successfully parsed by sscanf()
@@ -132,12 +132,12 @@
     sscanf(input, "%dx%ddpi%n", &dpi_x, &dpi_y, &n);
     if (n != len) {
       VLOG(1) << "Bad PPD resolution choice: " << input;
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
   if (dpi_x <= 0 || dpi_y <= 0) {
     VLOG(1) << "Invalid PPD resolution dimensions: " << dpi_x << " " << dpi_y;
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return gfx::Size(dpi_x, dpi_y);
@@ -170,7 +170,7 @@
     for (int i = 0; i < res->num_choices; i++) {
       char* choice = res->choices[i].choice;
       CHECK(choice);
-      absl::optional<gfx::Size> parsed_size = ParseResolutionString(choice);
+      std::optional<gfx::Size> parsed_size = ParseResolutionString(choice);
       if (!parsed_size.has_value()) {
         continue;
       }
@@ -186,8 +186,7 @@
     ppd_attr_t* attr = ppdFindAttr(ppd, "DefaultResolution", nullptr);
     if (attr) {
       CHECK(attr->value);
-      absl::optional<gfx::Size> parsed_size =
-          ParseResolutionString(attr->value);
+      std::optional<gfx::Size> parsed_size = ParseResolutionString(attr->value);
       if (parsed_size.has_value()) {
         dpis.push_back(parsed_size.value());
         default_dpi = parsed_size.value();
diff --git a/printing/backend/cups_helper_unittest.cc b/printing/backend/cups_helper_unittest.cc
index 8b2774d5..a8d5864 100644
--- a/printing/backend/cups_helper_unittest.cc
+++ b/printing/backend/cups_helper_unittest.cc
@@ -29,7 +29,7 @@
 }
 
 void VerifyCapabilityColorModels(const PrinterSemanticCapsAndDefaults& caps) {
-  absl::optional<bool> maybe_color = IsColorModelSelected(caps.color_model);
+  std::optional<bool> maybe_color = IsColorModelSelected(caps.color_model);
   ASSERT_TRUE(maybe_color.has_value());
   EXPECT_TRUE(maybe_color.value());
   maybe_color = IsColorModelSelected(caps.bw_model);
diff --git a/printing/backend/cups_ipp_helper.cc b/printing/backend/cups_ipp_helper.cc
index 92c0689..e2c1c28 100644
--- a/printing/backend/cups_ipp_helper.cc
+++ b/printing/backend/cups_ipp_helper.cc
@@ -11,6 +11,7 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/containers/contains.h"
 #include "base/containers/fixed_flat_set.h"
 #include "base/containers/flat_map.h"
@@ -28,7 +29,6 @@
 #include "printing/mojom/print.mojom.h"
 #include "printing/printing_utils.h"
 #include "printing/units.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_CHROMEOS)
 #include "base/functional/callback.h"
@@ -192,7 +192,7 @@
 }
 
 // Reads resolution from `attr` and puts into `size` in dots per inch.
-absl::optional<gfx::Size> GetResolution(ipp_attribute_t* attr, int i) {
+std::optional<gfx::Size> GetResolution(ipp_attribute_t* attr, int i) {
   ipp_res_t units;
   int yres;
   int xres = ippGetResolution(attr, i, &yres, &units);
@@ -229,12 +229,12 @@
 
   int num_options = ippGetCount(attr);
   for (int i = 0; i < num_options; i++) {
-    absl::optional<gfx::Size> size = GetResolution(attr, i);
+    std::optional<gfx::Size> size = GetResolution(attr, i);
     if (size)
       printer_info->dpis.push_back(size.value());
   }
   ipp_attribute_t* def_attr = printer.GetDefaultOptionValue(kIppResolution);
-  absl::optional<gfx::Size> size = GetResolution(def_attr, 0);
+  std::optional<gfx::Size> size = GetResolution(def_attr, 0);
   if (size) {
     printer_info->default_dpi = size.value();
   } else if (!printer_info->dpis.empty()) {
@@ -248,20 +248,20 @@
   }
 }
 
-absl::optional<PrinterSemanticCapsAndDefaults::Paper>
+std::optional<PrinterSemanticCapsAndDefaults::Paper>
 PaperFromMediaColDatabaseEntry(ipp_t* db_entry) {
   DCHECK(db_entry);
 
-  absl::optional<MediaColData> size = ExtractMediaColData(db_entry);
+  std::optional<MediaColData> size = ExtractMediaColData(db_entry);
   if (!size) {
     LOG(WARNING) << "Unable to create Paper from media-col-database";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (size->HasVariableWidth()) {
     LOG(WARNING) << "Invalid media-col-database entry:"
                  << " variable widths are not supported.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Some PPDs (only ones with a custom height range) have a min height of 0,
@@ -290,7 +290,7 @@
                  << " media-left-margin=" << size->left_margin
                  << " media-right-margin=" << size->right_margin
                  << " media-top-margin=" << size->top_margin;
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   gfx::Size size_um(size->min_width * kMicronsPerPwgUnit,
@@ -330,7 +330,7 @@
   int count = ippGetCount(attr);
 
   for (int i = 0; i < count; i++) {
-    absl::optional<PrinterSemanticCapsAndDefaults::Paper> paper_opt =
+    std::optional<PrinterSemanticCapsAndDefaults::Paper> paper_opt =
         PaperFromMediaColDatabaseEntry(ippGetCollection(attr, i));
     if (!paper_opt.has_value()) {
       continue;
@@ -552,7 +552,7 @@
   for (int i = 0; i < count; i++) {
     ipp_t* db_entry = ippGetCollection(attr, i);
 
-    absl::optional<PrinterSemanticCapsAndDefaults::Paper> paper_opt =
+    std::optional<PrinterSemanticCapsAndDefaults::Paper> paper_opt =
         PaperFromMediaColDatabaseEntry(db_entry);
     if (!paper_opt.has_value()) {
       continue;
@@ -582,16 +582,16 @@
   ippDelete(ipp);
 }
 
-absl::optional<MediaColData> ExtractMediaColData(ipp_t* db_entry) {
+std::optional<MediaColData> ExtractMediaColData(ipp_t* db_entry) {
   if (!db_entry) {
     LOG(WARNING) << "Invalid media-col-database entry: empty entry.";
-    return absl::nullopt;
+    return std::nullopt;
   }
   ipp_t* media_size = ippGetCollection(
       ippFindAttribute(db_entry, kIppMediaSize, IPP_TAG_BEGIN_COLLECTION), 0);
   if (!media_size) {
     LOG(WARNING) << "Invalid media-col-database entry: empty media_size.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   ipp_attribute_t* bottom_attr =
@@ -605,7 +605,7 @@
   if (!bottom_attr || !left_attr || !right_attr || !top_attr) {
     LOG(WARNING) << "Invalid media-col-database entry:"
                  << " margins are not present.";
-    return absl::nullopt;
+    return std::nullopt;
   }
   int bottom_margin = ippGetInteger(bottom_attr, 0);
   int left_margin = ippGetInteger(left_attr, 0);
@@ -626,7 +626,7 @@
       (!height_attr && !height_range_attr)) {
     LOG(WARNING) << "Invalid media-col-database entry:"
                  << " media-size needs x and y (or x and y range).";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   int min_width = 0;
@@ -650,13 +650,13 @@
     LOG(WARNING) << "Invalid media-col-database entry:"
                  << " min_width (" << min_width << ") > max_width ("
                  << max_width << ").";
-    return absl::nullopt;
+    return std::nullopt;
   }
   if (min_height > max_height) {
     LOG(WARNING) << "Invalid media-col-database entry:"
                  << " min_height (" << min_height << ") > max_height ("
                  << max_height << ").";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
 #if BUILDFLAG(IS_MAC)
@@ -752,7 +752,7 @@
   // they can be added later (once all the fixed widths have been discovered).
   for (int i = 0; i < ippGetCount(media_col_db); i++) {
     ipp_t* db_entry = ippGetCollection(media_col_db, i);
-    absl::optional<MediaColData> size = ExtractMediaColData(db_entry);
+    std::optional<MediaColData> size = ExtractMediaColData(db_entry);
     if (!size.has_value()) {
       return;
     }
diff --git a/printing/backend/cups_ipp_helper.h b/printing/backend/cups_ipp_helper.h
index 753de6a..b7dc9644 100644
--- a/printing/backend/cups_ipp_helper.h
+++ b/printing/backend/cups_ipp_helper.h
@@ -61,7 +61,7 @@
 
 // Returns a MediaColData object by extracting necessary fields from `db_entry`.
 COMPONENT_EXPORT(PRINT_BACKEND)
-absl::optional<MediaColData> ExtractMediaColData(ipp_t* db_entry);
+std::optional<MediaColData> ExtractMediaColData(ipp_t* db_entry);
 
 // Creates a new media-col-database entry from `data`.  The caller is
 // responsible for the returned memory.
diff --git a/printing/backend/mojom/print_backend_mojom_traits.cc b/printing/backend/mojom/print_backend_mojom_traits.cc
index 25f55b0..3dcee63 100644
--- a/printing/backend/mojom/print_backend_mojom_traits.cc
+++ b/printing/backend/mojom/print_backend_mojom_traits.cc
@@ -116,7 +116,7 @@
   std::string display_name;
   std::string vendor_id;
   gfx::Size size_um;
-  absl::optional<gfx::Rect> maybe_printable_area_um;
+  std::optional<gfx::Rect> maybe_printable_area_um;
   if (!data.ReadDisplayName(&display_name) || !data.ReadVendorId(&vendor_id) ||
       !data.ReadSizeUm(&size_um) ||
       !data.ReadPrintableAreaUm(&maybe_printable_area_um)) {
@@ -253,9 +253,9 @@
                   printing::PrinterSemanticCapsAndDefaults>::
     Read(printing::mojom::PrinterSemanticCapsAndDefaultsDataView data,
          printing::PrinterSemanticCapsAndDefaults* out) {
-  absl::optional<printing::PrinterSemanticCapsAndDefaults::MediaTypes>
+  std::optional<printing::PrinterSemanticCapsAndDefaults::MediaTypes>
       media_types;
-  absl::optional<printing::PrinterSemanticCapsAndDefaults::MediaType>
+  std::optional<printing::PrinterSemanticCapsAndDefaults::MediaType>
       default_media_type;
 
   out->collate_capable = data.collate_capable();
@@ -322,7 +322,7 @@
   if (out->page_output_quality) {
     printing::PageOutputQualityAttributes qualities =
         out->page_output_quality->qualities;
-    absl::optional<std::string> default_quality =
+    std::optional<std::string> default_quality =
         out->page_output_quality->default_quality;
 
     // If non-null `default_quality`, there should be a matching element in
diff --git a/printing/backend/mojom/print_backend_mojom_traits.h b/printing/backend/mojom/print_backend_mojom_traits.h
index c128aaf..10fa830 100644
--- a/printing/backend/mojom/print_backend_mojom_traits.h
+++ b/printing/backend/mojom/print_backend_mojom_traits.h
@@ -172,7 +172,7 @@
     return p.qualities;
   }
 
-  static const absl::optional<std::string>& default_quality(
+  static const std::optional<std::string>& default_quality(
       const ::printing::PageOutputQuality& p) {
     return p.default_quality;
   }
@@ -259,7 +259,7 @@
 #endif  // BUILDFLAG(IS_CHROMEOS)
 
 #if BUILDFLAG(IS_WIN)
-  static const absl::optional<printing::PageOutputQuality>& page_output_quality(
+  static const std::optional<printing::PageOutputQuality>& page_output_quality(
       const printing::PrinterSemanticCapsAndDefaults& p) {
     return p.page_output_quality;
   }
diff --git a/printing/backend/mojom/print_backend_mojom_traits_unittest.cc b/printing/backend/mojom/print_backend_mojom_traits_unittest.cc
index 2f9f7cd8..1c75c12e 100644
--- a/printing/backend/mojom/print_backend_mojom_traits_unittest.cc
+++ b/printing/backend/mojom/print_backend_mojom_traits_unittest.cc
@@ -445,7 +445,7 @@
     PrintBackendMojomTraitsTest,
     TestSerializeAndDeserializePrinterSemanticCapsAndDefaultsAllowableEmptyArraysXpsCapabilities) {
   const PageOutputQualityAttributes kEmptyQualities;
-  PageOutputQuality quality(kEmptyQualities, /*default_quality=*/absl::nullopt);
+  PageOutputQuality quality(kEmptyQualities, /*default_quality=*/std::nullopt);
   PrinterSemanticCapsAndDefaults input =
       GenerateSamplePrinterSemanticCapsAndDefaults({});
   input.page_output_quality = quality;
@@ -499,7 +499,7 @@
   PageOutputQuality page_output_quality(
       {kPageOutputQualityAttribute1, kPageOutputQualityAttributePrime,
        kPageOutputQualityAttribute2},
-      /*default_quality=*/absl::nullopt);
+      /*default_quality=*/std::nullopt);
   PrinterSemanticCapsAndDefaults input =
       GenerateSamplePrinterSemanticCapsAndDefaults({});
   input.page_output_quality = page_output_quality;
diff --git a/printing/backend/print_backend.cc b/printing/backend/print_backend.cc
index 99cbcc61..03268b0 100644
--- a/printing/backend/print_backend.cc
+++ b/printing/backend/print_backend.cc
@@ -120,9 +120,8 @@
 
 PageOutputQuality::PageOutputQuality() = default;
 
-PageOutputQuality::PageOutputQuality(
-    PageOutputQualityAttributes qualities,
-    absl::optional<std::string> default_quality)
+PageOutputQuality::PageOutputQuality(PageOutputQualityAttributes qualities,
+                                     std::optional<std::string> default_quality)
     : qualities(std::move(qualities)),
       default_quality(std::move(default_quality)) {}
 
diff --git a/printing/backend/print_backend.h b/printing/backend/print_backend.h
index defdcc5..21b9e43 100644
--- a/printing/backend/print_backend.h
+++ b/printing/backend/print_backend.h
@@ -11,12 +11,12 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_refptr.h"
 #include "build/build_config.h"
 #include "printing/mojom/print.mojom.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
 
@@ -133,7 +133,7 @@
 struct COMPONENT_EXPORT(PRINT_BACKEND) PageOutputQuality {
   PageOutputQuality();
   PageOutputQuality(PageOutputQualityAttributes qualities,
-                    absl::optional<std::string> default_quality);
+                    std::optional<std::string> default_quality);
   PageOutputQuality(const PageOutputQuality& other);
   ~PageOutputQuality();
 
@@ -142,7 +142,7 @@
 
   // Default option of page output quality.
   // TODO(crbug.com/1291257): Need populate this option in the next CLs.
-  absl::optional<std::string> default_quality;
+  std::optional<std::string> default_quality;
 };
 
 #if defined(UNIT_TEST)
@@ -161,7 +161,7 @@
   XpsCapabilities& operator=(XpsCapabilities&& other) noexcept;
   ~XpsCapabilities();
 
-  absl::optional<PageOutputQuality> page_output_quality;
+  std::optional<PageOutputQuality> page_output_quality;
 };
 
 #endif  // BUILDFLAG(IS_WIN)
@@ -289,7 +289,7 @@
 #endif  // BUILDFLAG(IS_CHROMEOS)
 
 #if BUILDFLAG(IS_WIN)
-  absl::optional<PageOutputQuality> page_output_quality;
+  std::optional<PageOutputQuality> page_output_quality;
 #endif  // BUILDFLAG(IS_WIN)
 };
 
@@ -365,7 +365,7 @@
   // there is any error in retrieving this data.
   // TODO(crbug.com/1424368):  Remove this if the printable areas can be made
   // fully available from `GetPrinterSemanticCapsAndDefaults()`.
-  virtual absl::optional<gfx::Rect> GetPaperPrintableArea(
+  virtual std::optional<gfx::Rect> GetPaperPrintableArea(
       const std::string& printer_name,
       const std::string& paper_vendor_id,
       const gfx::Size& paper_size_um) = 0;
diff --git a/printing/backend/print_backend_test_constants.cc b/printing/backend/print_backend_test_constants.cc
index c87954e..82d87c1 100644
--- a/printing/backend/print_backend_test_constants.cc
+++ b/printing/backend/print_backend_test_constants.cc
@@ -4,8 +4,8 @@
 
 #include "printing/backend/print_backend_test_constants.h"
 
+#include <optional>
 #include "printing/backend/print_backend.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace printing {
 
diff --git a/printing/backend/print_backend_test_constants.h b/printing/backend/print_backend_test_constants.h
index 2152b48..8e76e27 100644
--- a/printing/backend/print_backend_test_constants.h
+++ b/printing/backend/print_backend_test_constants.h
@@ -9,10 +9,10 @@
 
 #include <vector>
 
+#include <optional>
 #include "build/build_config.h"
 #include "printing/backend/mojom/print_backend.mojom-forward.h"
 #include "printing/backend/print_backend.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/size.h"
 
 namespace printing {
@@ -34,7 +34,7 @@
   AdvancedCapabilities advanced_capabilities;
 #endif  // BUILDFLAG(IS_CHROMEOS)
 #if BUILDFLAG(IS_WIN)
-  absl::optional<PageOutputQuality> page_output_quality;
+  std::optional<PageOutputQuality> page_output_quality;
 #endif  // BUILDFLAG(IS_WIN)
 };
 
@@ -116,7 +116,7 @@
     kPageOutputQualityAttribute3};
 inline const PageOutputQuality kPageOutputQuality(
     kPageOutputQualityAttributes,
-    /*default_quality=*/absl::nullopt);
+    /*default_quality=*/std::nullopt);
 inline constexpr char kDefaultQuality[] = "ns000:Draft";
 #endif  // BUILDFLAG(IS_WIN)
 
diff --git a/printing/backend/print_backend_win.cc b/printing/backend/print_backend_win.cc
index b425924..e8f6907e 100644
--- a/printing/backend/print_backend_win.cc
+++ b/printing/backend/print_backend_win.cc
@@ -304,7 +304,7 @@
   mojom::ResultCode GetPrinterCapsAndDefaults(
       const std::string& printer_name,
       PrinterCapsAndDefaults* printer_info) override;
-  absl::optional<gfx::Rect> GetPaperPrintableArea(
+  std::optional<gfx::Rect> GetPaperPrintableArea(
       const std::string& printer_name,
       const std::string& paper_vendor_id,
       const gfx::Size& paper_size_um) override;
@@ -555,19 +555,19 @@
   return mojom::ResultCode::kSuccess;
 }
 
-absl::optional<gfx::Rect> PrintBackendWin::GetPaperPrintableArea(
+std::optional<gfx::Rect> PrintBackendWin::GetPaperPrintableArea(
     const std::string& printer_name,
     const std::string& paper_vendor_id,
     const gfx::Size& paper_size_um) {
   ScopedPrinterHandle printer_handle = GetPrinterHandle(printer_name);
   if (!printer_handle.IsValid()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   std::unique_ptr<DEVMODE, base::FreeDeleter> devmode =
       CreateDevMode(printer_handle.Get(), nullptr);
   if (!devmode) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   unsigned id = 0;
diff --git a/printing/backend/test_print_backend.cc b/printing/backend/test_print_backend.cc
index 6eae2f6..4de96bc4 100644
--- a/printing/backend/test_print_backend.cc
+++ b/printing/backend/test_print_backend.cc
@@ -145,23 +145,23 @@
   return ReportErrorNotImplemented(FROM_HERE);
 }
 
-absl::optional<gfx::Rect> TestPrintBackend::GetPaperPrintableArea(
+std::optional<gfx::Rect> TestPrintBackend::GetPaperPrintableArea(
     const std::string& printer_name,
     const std::string& paper_vendor_id,
     const gfx::Size& paper_size_um) {
   auto found = printer_map_.find(printer_name);
   if (found == printer_map_.end()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   const std::unique_ptr<PrinterData>& data = found->second;
   if (data->blocked_by_permissions) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Capabilities might not have been provided.
   if (!data->caps) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Windows uses non-zero IDs to represent specific standard paper sizes.
@@ -175,7 +175,7 @@
     }
 
     // No match for the specified paper identification.
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Custom paper size.  For testing just treat as match to paper size.
diff --git a/printing/backend/test_print_backend.h b/printing/backend/test_print_backend.h
index e598e896..0b938f1 100644
--- a/printing/backend/test_print_backend.h
+++ b/printing/backend/test_print_backend.h
@@ -39,7 +39,7 @@
   mojom::ResultCode GetPrinterCapsAndDefaults(
       const std::string& printer_name,
       PrinterCapsAndDefaults* printer_info) override;
-  absl::optional<gfx::Rect> GetPaperPrintableArea(
+  std::optional<gfx::Rect> GetPaperPrintableArea(
       const std::string& printer_name,
       const std::string& paper_vendor_id,
       const gfx::Size& paper_size_um) override;
diff --git a/printing/backend/xps_utils_win_unittest.cc b/printing/backend/xps_utils_win_unittest.cc
index 8477679c..5dd65fb 100644
--- a/printing/backend/xps_utils_win_unittest.cc
+++ b/printing/backend/xps_utils_win_unittest.cc
@@ -293,7 +293,7 @@
             kPageOutputQuality);
 
   // Expect that non-XPS capabilities remain unmodified.
-  printer_capabilities.page_output_quality = absl::nullopt;
+  printer_capabilities.page_output_quality = std::nullopt;
   EXPECT_EQ(printer_capabilities,
             GenerateSamplePrinterSemanticCapsAndDefaults({}));
 }
diff --git a/printing/client_info_helpers_unittest.cc b/printing/client_info_helpers_unittest.cc
index 2f28fa3..552d77f 100644
--- a/printing/client_info_helpers_unittest.cc
+++ b/printing/client_info_helpers_unittest.cc
@@ -6,12 +6,12 @@
 
 #include <string>
 
+#include <optional>
 #include "base/strings/string_piece.h"
 #include "base/strings/string_split.h"
 #include "printing/mojom/print.mojom.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace printing {
 
@@ -28,8 +28,8 @@
 TEST(ClientInfoHelpersTest, ValidateClientInfoItemValidWithMissingFields) {
   mojom::IppClientInfo::ClientType type =
       mojom::IppClientInfo::ClientType::kApplication;
-  mojom::IppClientInfo client_info(type, "a-", absl::nullopt, "1.",
-                                   absl::nullopt);
+  mojom::IppClientInfo client_info(type, "a-", std::nullopt, "1.",
+                                   std::nullopt);
 
   EXPECT_TRUE(ValidateClientInfoItem(client_info));
 }
@@ -37,7 +37,7 @@
 TEST(ClientInfoHelpersTest, ValidateClientInfoItemInvalidChars) {
   mojom::IppClientInfo valid_client_info(
       mojom::IppClientInfo::ClientType::kOther, "name", "patch", "version",
-      absl::nullopt);
+      std::nullopt);
 
   mojom::IppClientInfo client_info;
 
@@ -61,7 +61,7 @@
 TEST(ClientInfoHelpersTest, ValidateClientInfoItemInvalidRange) {
   mojom::IppClientInfo valid_client_info(
       mojom::IppClientInfo::ClientType::kOther, "name", "patch", "version",
-      absl::nullopt);
+      std::nullopt);
 
   mojom::IppClientInfo client_info;
 
diff --git a/printing/common/metafile_utils.cc b/printing/common/metafile_utils.cc
index e420456..d7a0c453 100644
--- a/printing/common/metafile_utils.cc
+++ b/printing/common/metafile_utils.cc
@@ -184,13 +184,13 @@
   }
 
   if (ui::IsCellOrTableHeader(ax_node->GetRole())) {
-    absl::optional<int> row_span = ax_node->GetTableCellRowSpan();
+    std::optional<int> row_span = ax_node->GetTableCellRowSpan();
     if (row_span.has_value()) {
       tag->fAttributes.appendInt(kPDFTableAttributeOwner,
                                  kPDFTableCellRowSpanAttribute,
                                  row_span.value());
     }
-    absl::optional<int> col_span = ax_node->GetTableCellColSpan();
+    std::optional<int> col_span = ax_node->GetTableCellColSpan();
     if (col_span.has_value()) {
       tag->fAttributes.appendInt(kPDFTableAttributeOwner,
                                  kPDFTableCellColSpanAttribute,
diff --git a/printing/mojom/printing_context_mojom_traits.cc b/printing/mojom/printing_context_mojom_traits.cc
index 42dea5f..f6c58fd 100644
--- a/printing/mojom/printing_context_mojom_traits.cc
+++ b/printing/mojom/printing_context_mojom_traits.cc
@@ -191,7 +191,7 @@
 #if BUILDFLAG(IS_MAC)
     // The dictionary must contain the destination type, page format, and
     // print settings.
-    absl::optional<int> destination_type = system_print_dialog_data.FindInt(
+    std::optional<int> destination_type = system_print_dialog_data.FindInt(
         printing::kMacSystemPrintDialogDataDestinationType);
     if (!destination_type.has_value()) {
       return false;
diff --git a/printing/print_settings.cc b/printing/print_settings.cc
index 3277874..d8599dd 100644
--- a/printing/print_settings.cc
+++ b/printing/print_settings.cc
@@ -219,7 +219,7 @@
 }
 #endif  // BUILDFLAG(USE_CUPS_IPP)
 
-absl::optional<bool> IsColorModelSelected(mojom::ColorModel color_model) {
+std::optional<bool> IsColorModelSelected(mojom::ColorModel color_model) {
   switch (color_model) {
     case mojom::ColorModel::kColor:
     case mojom::ColorModel::kCMYK:
@@ -267,7 +267,7 @@
       return false;
     case mojom::ColorModel::kUnknownColorModel:
       NOTREACHED();
-      return absl::nullopt;
+      return std::nullopt;
   }
   // The default case is excluded from the above switch statement to ensure that
   // all ColorModel values are determinantly handled.
diff --git a/printing/print_settings.h b/printing/print_settings.h
index 5e9cbf5a..bddd437 100644
--- a/printing/print_settings.h
+++ b/printing/print_settings.h
@@ -10,6 +10,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/component_export.h"
 #include "build/build_config.h"
 #include "printing/buildflags/buildflags.h"
@@ -17,7 +18,6 @@
 #include "printing/page_range.h"
 #include "printing/page_setup.h"
 #include "printing/print_job_constants.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
 
@@ -67,9 +67,9 @@
 
 // Returns true if `color_model` is color and false if it is B&W.  Callers
 // are not supposed to pass in `mojom::ColorModel::kUnknownColorModel`, but
-// if they do then the result will be absl::nullopt.
+// if they do then the result will be std::nullopt.
 COMPONENT_EXPORT(PRINTING)
-absl::optional<bool> IsColorModelSelected(mojom::ColorModel color_model);
+std::optional<bool> IsColorModelSelected(mojom::ColorModel color_model);
 
 #if BUILDFLAG(USE_CUPS)
 // Get the color model setting name and value for the `color_model`.
@@ -316,7 +316,7 @@
       crosapi::mojom::StatusReason::Reason printer_status_reason) {
     printer_status_reason_ = printer_status_reason;
   }
-  absl::optional<crosapi::mojom::StatusReason::Reason> printer_status_reason()
+  std::optional<crosapi::mojom::StatusReason::Reason> printer_status_reason()
       const {
     return printer_status_reason_;
   }
@@ -457,7 +457,7 @@
 
   // The printer status reason shown for the selected printer at the time print
   // is requested. Only local CrOS printers set printer statuses.
-  absl::optional<crosapi::mojom::StatusReason::Reason> printer_status_reason_;
+  std::optional<crosapi::mojom::StatusReason::Reason> printer_status_reason_;
 #endif  // BUILDFLAG(IS_CHROMEOS)
 };
 
diff --git a/printing/print_settings_conversion.cc b/printing/print_settings_conversion.cc
index 8e882f0..9878e55 100644
--- a/printing/print_settings_conversion.cc
+++ b/printing/print_settings_conversion.cc
@@ -12,6 +12,7 @@
 #include <string>
 #include <utility>
 
+#include <optional>
 #include "base/containers/contains.h"
 #include "base/containers/fixed_flat_set.h"
 #include "base/strings/string_number_conversions.h"
@@ -25,7 +26,6 @@
 #include "printing/print_job_constants.h"
 #include "printing/print_settings.h"
 #include "printing/units.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
 
@@ -87,13 +87,13 @@
 void SetPrintableAreaIfValid(PrintSettings& settings,
                              const gfx::Size& size_microns,
                              const base::Value::Dict& media_size) {
-  absl::optional<int> left_microns =
+  std::optional<int> left_microns =
       media_size.FindInt(kSettingsImageableAreaLeftMicrons);
-  absl::optional<int> bottom_microns =
+  std::optional<int> bottom_microns =
       media_size.FindInt(kSettingsImageableAreaBottomMicrons);
-  absl::optional<int> right_microns =
+  std::optional<int> right_microns =
       media_size.FindInt(kSettingsImageableAreaRightMicrons);
-  absl::optional<int> top_microns =
+  std::optional<int> top_microns =
       media_size.FindInt(kSettingsImageableAreaTopMicrons);
   if (!bottom_microns.has_value() || !left_microns.has_value() ||
       !right_microns.has_value() || !top_microns.has_value()) {
@@ -140,8 +140,8 @@
     }
 
     const auto& dict = page_range.GetDict();
-    absl::optional<int> from = dict.FindInt(kSettingPageRangeFrom);
-    absl::optional<int> to = dict.FindInt(kSettingPageRangeTo);
+    std::optional<int> from = dict.FindInt(kSettingPageRangeFrom);
+    std::optional<int> to = dict.FindInt(kSettingPageRangeTo);
     if (!from.has_value() || !to.has_value()) {
       continue;
     }
@@ -157,7 +157,7 @@
 std::unique_ptr<PrintSettings> PrintSettingsFromJobSettings(
     const base::Value::Dict& job_settings) {
   auto settings = std::make_unique<PrintSettings>();
-  absl::optional<bool> display_header_footer =
+  std::optional<bool> display_header_footer =
       job_settings.FindBool(kSettingHeaderFooterEnabled);
   if (!display_header_footer.has_value()) {
     return nullptr;
@@ -176,9 +176,9 @@
     settings->set_url(base::UTF8ToUTF16(*url));
   }
 
-  absl::optional<bool> backgrounds =
+  std::optional<bool> backgrounds =
       job_settings.FindBool(kSettingShouldPrintBackgrounds);
-  absl::optional<bool> selection_only =
+  std::optional<bool> selection_only =
       job_settings.FindBool(kSettingShouldPrintSelectionOnly);
   if (!backgrounds.has_value() || !selection_only.has_value()) {
     return nullptr;
@@ -187,16 +187,16 @@
   settings->set_should_print_backgrounds(backgrounds.value());
   settings->set_selection_only(selection_only.value());
 
-  absl::optional<bool> collate = job_settings.FindBool(kSettingCollate);
-  absl::optional<int> copies = job_settings.FindInt(kSettingCopies);
-  absl::optional<int> color = job_settings.FindInt(kSettingColor);
-  absl::optional<int> duplex_mode = job_settings.FindInt(kSettingDuplexMode);
-  absl::optional<bool> landscape = job_settings.FindBool(kSettingLandscape);
+  std::optional<bool> collate = job_settings.FindBool(kSettingCollate);
+  std::optional<int> copies = job_settings.FindInt(kSettingCopies);
+  std::optional<int> color = job_settings.FindInt(kSettingColor);
+  std::optional<int> duplex_mode = job_settings.FindInt(kSettingDuplexMode);
+  std::optional<bool> landscape = job_settings.FindBool(kSettingLandscape);
   const std::string* device_name = job_settings.FindString(kSettingDeviceName);
-  absl::optional<int> scale_factor = job_settings.FindInt(kSettingScaleFactor);
-  absl::optional<bool> rasterize_pdf =
+  std::optional<int> scale_factor = job_settings.FindInt(kSettingScaleFactor);
+  std::optional<bool> rasterize_pdf =
       job_settings.FindBool(kSettingRasterizePdf);
-  absl::optional<int> pages_per_sheet =
+  std::optional<int> pages_per_sheet =
       job_settings.FindInt(kSettingPagesPerSheet);
   if (!collate.has_value() || !copies.has_value() || !color.has_value() ||
       !duplex_mode.has_value() || !landscape.has_value() || !device_name ||
@@ -215,16 +215,16 @@
   settings->set_rasterize_pdf(rasterize_pdf.value());
   settings->set_pages_per_sheet(pages_per_sheet.value());
 
-  absl::optional<int> dpi_horizontal =
+  std::optional<int> dpi_horizontal =
       job_settings.FindInt(kSettingDpiHorizontal);
-  absl::optional<int> dpi_vertical = job_settings.FindInt(kSettingDpiVertical);
+  std::optional<int> dpi_vertical = job_settings.FindInt(kSettingDpiVertical);
   if (!dpi_horizontal.has_value() || !dpi_vertical.has_value()) {
     return nullptr;
   }
 
   settings->set_dpi_xy(dpi_horizontal.value(), dpi_vertical.value());
 
-  absl::optional<int> rasterize_pdf_dpi =
+  std::optional<int> rasterize_pdf_dpi =
       job_settings.FindInt(kSettingRasterizePdfDpi);
   if (rasterize_pdf_dpi.has_value()) {
     settings->set_rasterize_pdf_dpi(rasterize_pdf_dpi.value());
@@ -250,9 +250,9 @@
   const base::Value::Dict* media_size_value =
       job_settings.FindDict(kSettingMediaSize);
   if (media_size_value) {
-    absl::optional<int> width_microns =
+    std::optional<int> width_microns =
         media_size_value->FindInt(kSettingMediaSizeWidthMicrons);
-    absl::optional<int> height_microns =
+    std::optional<int> height_microns =
         media_size_value->FindInt(kSettingMediaSizeHeightMicrons);
     if (width_microns.has_value() && height_microns.has_value()) {
       requested_media.size_microns =
@@ -269,7 +269,7 @@
   }
   settings->set_requested_media(requested_media);
 
-  absl::optional<bool> borderless = job_settings.FindBool(kSettingBorderless);
+  std::optional<bool> borderless = job_settings.FindBool(kSettingBorderless);
   if (borderless.has_value()) {
     settings->set_borderless(borderless.value());
   }
@@ -281,7 +281,7 @@
 
   settings->set_ranges(GetPageRangesFromJobSettings(job_settings));
 
-  absl::optional<bool> is_modifiable =
+  std::optional<bool> is_modifiable =
       job_settings.FindBool(kSettingPreviewModifiable);
   if (is_modifiable.has_value()) {
     settings->set_is_modifiable(is_modifiable.value());
@@ -335,8 +335,7 @@
   settings->set_printer_manually_selected(
       job_settings.FindBool(kSettingPrinterManuallySelected).value_or(false));
 
-  absl::optional<int> reason =
-      job_settings.FindInt(kSettingPrinterStatusReason);
+  std::optional<int> reason = job_settings.FindInt(kSettingPrinterStatusReason);
   if (reason.has_value()) {
     settings->set_printer_status_reason(
         static_cast<crosapi::mojom::StatusReason::Reason>(reason.value()));
diff --git a/printing/print_settings_conversion_chromeos_unittest.cc b/printing/print_settings_conversion_chromeos_unittest.cc
index 92c4a2e6..f7d2009 100644
--- a/printing/print_settings_conversion_chromeos_unittest.cc
+++ b/printing/print_settings_conversion_chromeos_unittest.cc
@@ -6,10 +6,10 @@
 
 #include <string>
 
+#include <optional>
 #include "base/test/values_test_util.h"
 #include "base/values.h"
 #include "printing/mojom/print.mojom.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace printing {
 
@@ -38,9 +38,9 @@
                          "version"),
     mojom::IppClientInfo(mojom::IppClientInfo::ClientType::kOther,
                          "chromebook-{DEVICE_ASSET_ID}",
-                         absl::nullopt,
+                         std::nullopt,
                          "",
-                         absl::nullopt)};
+                         std::nullopt)};
 
 TEST(PrintSettingsConversionChromeosTest, ConvertClientInfoToJobSetting) {
   base::Value::List job_setting = ConvertClientInfoToJobSetting(kClientInfo);
diff --git a/printing/printing_context_chromeos_unittest.cc b/printing/printing_context_chromeos_unittest.cc
index 2b74ba7..ef53af0 100644
--- a/printing/printing_context_chromeos_unittest.cc
+++ b/printing/printing_context_chromeos_unittest.cc
@@ -367,7 +367,7 @@
   EXPECT_FALSE(HasAttribute(kIppClientInfo));
 
   mojom::IppClientInfo invalid_client_info(
-      mojom::IppClientInfo::ClientType::kOther, "$", " ", "{}", absl::nullopt);
+      mojom::IppClientInfo::ClientType::kOther, "$", " ", "{}", std::nullopt);
 
   settings_.set_client_infos({invalid_client_info});
   EXPECT_FALSE(HasAttribute(kIppClientInfo));
diff --git a/printing/printing_context_mac.mm b/printing/printing_context_mac.mm
index b051381..f402566 100644
--- a/printing/printing_context_mac.mm
+++ b/printing/printing_context_mac.mm
@@ -293,7 +293,7 @@
                             const base::Value::Dict& system_print_dialog_data,
                             PMPrintSession& print_session,
                             PMPrintSettings& print_settings) {
-  absl::optional<int> destination_type = system_print_dialog_data.FindInt(
+  std::optional<int> destination_type = system_print_dialog_data.FindInt(
       kMacSystemPrintDialogDataDestinationType);
 
   CHECK(destination_type.has_value());
diff --git a/printing/test_printing_context.h b/printing/test_printing_context.h
index 494a45c7..108364b 100644
--- a/printing/test_printing_context.h
+++ b/printing/test_printing_context.h
@@ -16,7 +16,7 @@
 #include "printing/printing_context.h"
 
 #if BUILDFLAG(IS_WIN)
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include <optional>
 #endif
 
 namespace printing {
@@ -130,7 +130,7 @@
   base::flat_map<std::string, std::unique_ptr<PrintSettings>> device_settings_;
 
   // Settings to apply to mimic a user's choices in `AskUserForSettings()`.
-  absl::optional<PrintSettings> user_settings_;
+  std::optional<PrintSettings> user_settings_;
 
   // Platform implementations of `PrintingContext` apply PrintSettings to the
   // respective device contexts.  Once the upper printing layers call
@@ -155,7 +155,7 @@
   bool new_document_blocked_by_permissions_ = false;
 #if BUILDFLAG(IS_WIN)
   bool render_page_blocked_by_permissions_ = false;
-  absl::optional<uint32_t> render_page_fail_for_page_number_;
+  std::optional<uint32_t> render_page_fail_for_page_number_;
 #endif
   bool render_document_blocked_by_permissions_ = false;
   bool document_done_blocked_by_permissions_ = false;
diff --git a/remoting/base/chromoting_event.cc b/remoting/base/chromoting_event.cc
index e7a09f7..e0efc9b 100644
--- a/remoting/base/chromoting_event.cc
+++ b/remoting/base/chromoting_event.cc
@@ -178,7 +178,7 @@
 }
 
 bool ChromotingEvent::IsDataValid() {
-  absl::optional<int> auth_method = values_map_->FindInt(kAuthMethodKey);
+  std::optional<int> auth_method = values_map_->FindInt(kAuthMethodKey);
   if (auth_method &&
       auth_method.value() == static_cast<int>(AuthMethod::NOT_SET)) {
     return false;
@@ -228,21 +228,21 @@
 apis::v1::ChromotingEvent ChromotingEvent::CreateProto() const {
   apis::v1::ChromotingEvent event_proto;
 
-  if (absl::optional<int> auth_method = values_map_->FindInt(kAuthMethodKey)) {
+  if (std::optional<int> auth_method = values_map_->FindInt(kAuthMethodKey)) {
     event_proto.set_auth_method(
         static_cast<apis::v1::ChromotingEvent_AuthMethod>(auth_method.value()));
   }
-  if (absl::optional<double> capture_latency =
+  if (std::optional<double> capture_latency =
           values_map_->FindDouble(kCaptureLatencyKey)) {
     event_proto.set_capture_latency(capture_latency.value());
   }
-  if (absl::optional<int> connection_error =
+  if (std::optional<int> connection_error =
           values_map_->FindInt(kConnectionErrorKey)) {
     event_proto.set_connection_error(
         static_cast<apis::v1::ChromotingEvent_ConnectionError>(
             connection_error.value()));
   }
-  if (absl::optional<int> connection_type =
+  if (std::optional<int> connection_type =
           values_map_->FindInt(kConnectionTypeKey)) {
     event_proto.set_connection_type(
         static_cast<apis::v1::ChromotingEvent_ConnectionType>(
@@ -251,15 +251,15 @@
   if (const std::string* cpu = values_map_->FindString(kCpuKey)) {
     event_proto.set_cpu(*cpu);
   }
-  if (absl::optional<double> decode_latency =
+  if (std::optional<double> decode_latency =
           values_map_->FindDouble(kDecodeLatencyKey)) {
     event_proto.set_decode_latency(decode_latency.value());
   }
-  if (absl::optional<double> encode_latency =
+  if (std::optional<double> encode_latency =
           values_map_->FindDouble(kEncodeLatencyKey)) {
     event_proto.set_encode_latency(encode_latency.value());
   }
-  if (absl::optional<int> host_os = values_map_->FindInt(kHostOsKey)) {
+  if (std::optional<int> host_os = values_map_->FindInt(kHostOsKey)) {
     event_proto.set_host_os(
         static_cast<apis::v1::ChromotingEvent_Os>(host_os.value()));
   }
@@ -271,59 +271,59 @@
           values_map_->FindString(kHostVersionKey)) {
     event_proto.set_host_version(*host_version);
   }
-  if (absl::optional<double> max_capture_latency =
+  if (std::optional<double> max_capture_latency =
           values_map_->FindDouble(kMaxCaptureLatencyKey)) {
     event_proto.set_max_capture_latency(max_capture_latency.value());
   }
-  if (absl::optional<double> max_decode_latency =
+  if (std::optional<double> max_decode_latency =
           values_map_->FindDouble(kMaxDecodeLatencyKey)) {
     event_proto.set_max_decode_latency(max_decode_latency.value());
   }
-  if (absl::optional<double> max_encode_latency =
+  if (std::optional<double> max_encode_latency =
           values_map_->FindDouble(kMaxEncodeLatencyKey)) {
     event_proto.set_max_encode_latency(max_encode_latency.value());
   }
-  if (absl::optional<double> max_render_latency =
+  if (std::optional<double> max_render_latency =
           values_map_->FindDouble(kMaxRenderLatencyKey)) {
     event_proto.set_max_render_latency(max_render_latency.value());
   }
-  if (absl::optional<double> max_roundtrip_latency =
+  if (std::optional<double> max_roundtrip_latency =
           values_map_->FindDouble(kMaxRoundtripLatencyKey)) {
     event_proto.set_max_roundtrip_latency(max_roundtrip_latency.value());
   }
-  if (absl::optional<int> mode = values_map_->FindInt(kModeKey)) {
+  if (std::optional<int> mode = values_map_->FindInt(kModeKey)) {
     event_proto.set_mode(
         static_cast<apis::v1::ChromotingEvent_Mode>(mode.value()));
   }
-  if (absl::optional<int> os = values_map_->FindInt(kOsKey)) {
+  if (std::optional<int> os = values_map_->FindInt(kOsKey)) {
     event_proto.set_os(static_cast<apis::v1::ChromotingEvent_Os>(os.value()));
   }
   if (const std::string* os_version = values_map_->FindString(kOsVersionKey)) {
     event_proto.set_os_version(*os_version);
   }
-  if (absl::optional<int> previous_session_state =
+  if (std::optional<int> previous_session_state =
           values_map_->FindInt(kPreviousSessionStateKey)) {
     event_proto.set_previous_session_state(
         static_cast<apis::v1::ChromotingEvent_SessionState>(
             previous_session_state.value()));
   }
-  if (absl::optional<double> render_latency =
+  if (std::optional<double> render_latency =
           values_map_->FindDouble(kRenderLatencyKey)) {
     event_proto.set_render_latency(render_latency.value());
   }
-  if (absl::optional<int> role = values_map_->FindInt(kRoleKey)) {
+  if (std::optional<int> role = values_map_->FindInt(kRoleKey)) {
     event_proto.set_role(
         static_cast<apis::v1::ChromotingEvent_Role>(role.value()));
   }
-  if (absl::optional<double> roundtrip_latency =
+  if (std::optional<double> roundtrip_latency =
           values_map_->FindDouble(kRoundtripLatencyKey)) {
     event_proto.set_roundtrip_latency(roundtrip_latency.value());
   }
-  if (absl::optional<double> session_duration =
+  if (std::optional<double> session_duration =
           values_map_->FindDouble(kSessionDurationKey)) {
     event_proto.set_session_duration(session_duration.value());
   }
-  if (absl::optional<int> session_entry_point =
+  if (std::optional<int> session_entry_point =
           values_map_->FindInt(kSessionEntryPointKey)) {
     event_proto.set_session_entry_point(
         static_cast<apis::v1::ChromotingEvent_SessionEntryPoint>(
@@ -332,23 +332,23 @@
   if (const std::string* session_id = values_map_->FindString(kSessionIdKey)) {
     event_proto.set_session_id(*session_id);
   }
-  if (absl::optional<int> session_state =
+  if (std::optional<int> session_state =
           values_map_->FindInt(kSessionStateKey)) {
     event_proto.set_session_state(
         static_cast<apis::v1::ChromotingEvent_SessionState>(
             session_state.value()));
   }
-  if (absl::optional<int> signal_strategy_type =
+  if (std::optional<int> signal_strategy_type =
           values_map_->FindInt(kSignalStrategyTypeKey)) {
     event_proto.set_signal_strategy_type(
         static_cast<apis::v1::ChromotingEvent_SignalStrategyType>(
             signal_strategy_type.value()));
   }
-  if (absl::optional<int> type = values_map_->FindInt(kTypeKey)) {
+  if (std::optional<int> type = values_map_->FindInt(kTypeKey)) {
     event_proto.set_type(
         static_cast<apis::v1::ChromotingEvent_Type>(type.value()));
   }
-  if (absl::optional<double> video_bandwidth =
+  if (std::optional<double> video_bandwidth =
           values_map_->FindDouble(kVideoBandwidthKey)) {
     event_proto.set_video_bandwidth(video_bandwidth.value());
   }
diff --git a/remoting/base/corp_service_client.cc b/remoting/base/corp_service_client.cc
index 930c5ee..0b23a44 100644
--- a/remoting/base/corp_service_client.cc
+++ b/remoting/base/corp_service_client.cc
@@ -40,7 +40,7 @@
     const std::string& owner_email,
     const std::string& fqdn,
     const std::string& public_key,
-    absl::optional<std::string> existing_host_id,
+    std::optional<std::string> existing_host_id,
     ProvisionCorpMachineCallback callback) {
   constexpr net::NetworkTrafficAnnotationTag traffic_annotation =
       net::DefineNetworkTrafficAnnotation("remoting_provision_corp_machine",
diff --git a/remoting/base/corp_service_client.h b/remoting/base/corp_service_client.h
index 9a073528..f4a6b57 100644
--- a/remoting/base/corp_service_client.h
+++ b/remoting/base/corp_service_client.h
@@ -8,12 +8,12 @@
 #include <memory>
 #include <string>
 
+#include <optional>
 #include "base/functional/callback_forward.h"
 #include "base/memory/scoped_refptr.h"
 #include "remoting/base/buildflags.h"
 #include "remoting/base/protobuf_http_client.h"
 #include "remoting/proto/empty.pb.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(REMOTING_INTERNAL)
 #include "remoting/internal/proto/helpers.h"
@@ -53,7 +53,7 @@
   void ProvisionCorpMachine(const std::string& owner_email,
                             const std::string& fqdn,
                             const std::string& public_key,
-                            absl::optional<std::string> existing_host_id,
+                            std::optional<std::string> existing_host_id,
                             ProvisionCorpMachineCallback callback);
 
   void ReportProvisioningError(const std::string& host_id,
diff --git a/remoting/base/file_host_settings.h b/remoting/base/file_host_settings.h
index 26cebb1..38b401a 100644
--- a/remoting/base/file_host_settings.h
+++ b/remoting/base/file_host_settings.h
@@ -42,7 +42,7 @@
 
   // TODO(yuweih): This needs to be guarded with a lock if we detect changes of
   // the settings file.
-  absl::optional<base::Value::Dict> settings_;
+  std::optional<base::Value::Dict> settings_;
 };
 
 }  // namespace remoting
diff --git a/remoting/base/protobuf_http_client.h b/remoting/base/protobuf_http_client.h
index b71965e..4db70f5 100644
--- a/remoting/base/protobuf_http_client.h
+++ b/remoting/base/protobuf_http_client.h
@@ -9,6 +9,7 @@
 #include <memory>
 #include <string>
 
+#include <optional>
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
@@ -16,7 +17,6 @@
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "remoting/base/oauth_token_getter.h"
 #include "remoting/base/url_loader_network_service_observer.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace network {
 class SharedURLLoaderFactory;
@@ -67,7 +67,7 @@
 
   std::string server_endpoint_;
   raw_ptr<OAuthTokenGetter> token_getter_;
-  absl::optional<UrlLoaderNetworkServiceObserver> service_observer_;
+  std::optional<UrlLoaderNetworkServiceObserver> service_observer_;
   scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
   PendingRequestList pending_requests_;
 
diff --git a/remoting/base/result.h b/remoting/base/result.h
index 80a36d9..d9a5d67 100644
--- a/remoting/base/result.h
+++ b/remoting/base/result.h
@@ -8,8 +8,8 @@
 #include <type_traits>
 #include <utility>
 
+#include <optional>
 #include "base/check.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
 
 // Result<SuccessType, ErrorType> represents the success or failure of an
@@ -132,7 +132,7 @@
 class ErrorTag {};
 // absl::monostate can be used for SuccessType or ErrorType to indicate that
 // there is no data for that state. Thus, Result<SomeType, monostate> is
-// somewhat analogous to absl::optional<SomeType>, and Result<monostate,
+// somewhat analogous to std::optional<SomeType>, and Result<monostate,
 // monostate> is effectively a (2-byte) boolean. Result<monostate, ErrorType>
 // can be useful for cases where an operation can fail, but there is no return
 // value in the success case.
diff --git a/remoting/base/session_options.cc b/remoting/base/session_options.cc
index df2f649..7981ecd 100644
--- a/remoting/base/session_options.cc
+++ b/remoting/base/session_options.cc
@@ -53,18 +53,18 @@
   options_[key] = value;
 }
 
-absl::optional<std::string> SessionOptions::Get(const std::string& key) const {
+std::optional<std::string> SessionOptions::Get(const std::string& key) const {
   auto it = options_.find(key);
   if (it == options_.end()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return it->second;
 }
 
-absl::optional<bool> SessionOptions::GetBool(const std::string& key) const {
-  absl::optional<std::string> value = Get(key);
+std::optional<bool> SessionOptions::GetBool(const std::string& key) const {
+  std::optional<std::string> value = Get(key);
   if (!value) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   const std::string lowercase_value = base::ToLowerASCII(*value);
@@ -77,17 +77,17 @@
   }
   LOG(WARNING) << "Unexpected option received " << *value
                << " which cannot be converted to bool.";
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool SessionOptions::GetBoolValue(const std::string& key) const {
   return GetBool(key).value_or(false);
 }
 
-absl::optional<int> SessionOptions::GetInt(const std::string& key) const {
-  absl::optional<std::string> value = Get(key);
+std::optional<int> SessionOptions::GetInt(const std::string& key) const {
+  std::optional<std::string> value = Get(key);
   if (!value) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   int result;
@@ -96,7 +96,7 @@
   }
   LOG(WARNING) << "Unexpected option received " << *value
                << " which cannot be converted to integer.";
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 std::string SessionOptions::Export() const {
diff --git a/remoting/base/session_options.h b/remoting/base/session_options.h
index 99ee551..6d53993 100644
--- a/remoting/base/session_options.h
+++ b/remoting/base/session_options.h
@@ -7,8 +7,8 @@
 
 #include <string>
 
+#include <optional>
 #include "base/containers/flat_map.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -32,20 +32,20 @@
 
   // Retrieves the value of |key|. Returns a true Optional if |key| has been
   // found, value of the Optional will be set to corresponding value.
-  absl::optional<std::string> Get(const std::string& key) const;
+  std::optional<std::string> Get(const std::string& key) const;
 
   // Retrieves the value of |key|. Returns a true Optional if |key| has been
   // found and the corresponding value can be converted to a boolean value.
   // "true", "1" or empty will be converted to true, "false" or "0" will be
   // converted to false.
-  absl::optional<bool> GetBool(const std::string& key) const;
+  std::optional<bool> GetBool(const std::string& key) const;
 
   // Equivalent to GetBool(key).value_or(false).
   bool GetBoolValue(const std::string& key) const;
 
   // Retrieves the value of |key|. Returns a true Optional if |key| has been
   // found and the corresponding value can be converted to an integer.
-  absl::optional<int> GetInt(const std::string& key) const;
+  std::optional<int> GetInt(const std::string& key) const;
 
   // Returns a string to represent current instance. Consumers can rebuild an
   // exactly same instance with Import() function.
diff --git a/remoting/base/url_loader_network_service_observer.cc b/remoting/base/url_loader_network_service_observer.cc
index 8913372..630b9e3 100644
--- a/remoting/base/url_loader_network_service_observer.cc
+++ b/remoting/base/url_loader_network_service_observer.cc
@@ -90,7 +90,7 @@
 }
 
 void UrlLoaderNetworkServiceObserver::OnCertificateRequested(
-    const absl::optional<base::UnguessableToken>& window_id,
+    const std::optional<base::UnguessableToken>& window_id,
     const scoped_refptr<net::SSLCertRequestInfo>& cert_info,
     mojo::PendingRemote<network::mojom::ClientCertificateResponder>
         client_cert_responder) {
@@ -110,7 +110,7 @@
 }
 
 void UrlLoaderNetworkServiceObserver::OnAuthRequired(
-    const absl::optional<base::UnguessableToken>& window_id,
+    const std::optional<base::UnguessableToken>& window_id,
     uint32_t request_id,
     const GURL& url,
     bool first_auth_attempt,
@@ -122,15 +122,15 @@
 void UrlLoaderNetworkServiceObserver::OnPrivateNetworkAccessPermissionRequired(
     const GURL& url,
     const net::IPAddress& ip_address,
-    const absl::optional<std::string>& private_network_device_id,
-    const absl::optional<std::string>& private_network_device_name,
+    const std::optional<std::string>& private_network_device_id,
+    const std::optional<std::string>& private_network_device_name,
     OnPrivateNetworkAccessPermissionRequiredCallback callback) {}
 
 void UrlLoaderNetworkServiceObserver::OnClearSiteData(
     const GURL& url,
     const std::string& header_value,
     int32_t load_flags,
-    const absl::optional<net::CookiePartitionKey>& cookie_partition_key,
+    const std::optional<net::CookiePartitionKey>& cookie_partition_key,
     bool partitioned_state_allowed_only,
     OnClearSiteDataCallback callback) {
   std::move(callback).Run();
diff --git a/remoting/base/url_loader_network_service_observer.h b/remoting/base/url_loader_network_service_observer.h
index 359a973..b8f27b5 100644
--- a/remoting/base/url_loader_network_service_observer.h
+++ b/remoting/base/url_loader_network_service_observer.h
@@ -43,12 +43,12 @@
                              bool fatal,
                              OnSSLCertificateErrorCallback response) override;
   void OnCertificateRequested(
-      const absl::optional<base::UnguessableToken>& window_id,
+      const std::optional<base::UnguessableToken>& window_id,
       const scoped_refptr<net::SSLCertRequestInfo>& cert_info,
       mojo::PendingRemote<network::mojom::ClientCertificateResponder>
           cert_responder) override;
   void OnAuthRequired(
-      const absl::optional<base::UnguessableToken>& window_id,
+      const std::optional<base::UnguessableToken>& window_id,
       uint32_t request_id,
       const GURL& url,
       bool first_auth_attempt,
@@ -59,14 +59,14 @@
   void OnPrivateNetworkAccessPermissionRequired(
       const GURL& url,
       const net::IPAddress& ip_address,
-      const absl::optional<std::string>& private_network_device_id,
-      const absl::optional<std::string>& private_network_device_name,
+      const std::optional<std::string>& private_network_device_id,
+      const std::optional<std::string>& private_network_device_name,
       OnPrivateNetworkAccessPermissionRequiredCallback callback) override;
   void OnClearSiteData(
       const GURL& url,
       const std::string& header_value,
       int load_flags,
-      const absl::optional<net::CookiePartitionKey>& cookie_partition_key,
+      const std::optional<net::CookiePartitionKey>& cookie_partition_key,
       bool partitioned_state_allowed_only,
       OnClearSiteDataCallback callback) override;
   void OnLoadingStateUpdate(network::mojom::LoadInfoPtr info,
diff --git a/remoting/client/display/gl_renderer.h b/remoting/client/display/gl_renderer.h
index 334e353..a6341d7a 100644
--- a/remoting/client/display/gl_renderer.h
+++ b/remoting/client/display/gl_renderer.h
@@ -7,6 +7,7 @@
 
 #include <vector>
 
+#include <optional>
 #include "base/containers/queue.h"
 #include "base/functional/callback.h"
 #include "base/memory/weak_ptr.h"
@@ -15,7 +16,6 @@
 #include "remoting/client/display/gl_cursor_feedback.h"
 #include "remoting/client/display/gl_desktop.h"
 #include "remoting/proto/control.pb.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace webrtc {
 class DesktopFrame;
@@ -139,7 +139,7 @@
   std::unique_ptr<Canvas> canvas_;
 
   // Used to recover the transformation matrix when the canvas is recreated.
-  absl::optional<std::array<float, 9>> transformation_matrix_;
+  std::optional<std::array<float, 9>> transformation_matrix_;
 
   GlCursor cursor_;
   GlCursorFeedback cursor_feedback_;
diff --git a/remoting/client/jni/jni_notification_presenter.cc b/remoting/client/jni/jni_notification_presenter.cc
index 87d8381..3ac3ef8 100644
--- a/remoting/client/jni/jni_notification_presenter.cc
+++ b/remoting/client/jni/jni_notification_presenter.cc
@@ -49,7 +49,7 @@
 }
 
 void JniNotificationPresenter::OnNotificationFetched(
-    absl::optional<NotificationMessage> notification) {
+    std::optional<NotificationMessage> notification) {
   DCHECK(sequence_->RunsTasksInCurrentSequence());
   JNIEnv* env = base::android::AttachCurrentThread();
   auto java_presenter = java_presenter_.get(env);
diff --git a/remoting/client/jni/jni_notification_presenter.h b/remoting/client/jni/jni_notification_presenter.h
index cfb35ddd..a30d3c0 100644
--- a/remoting/client/jni/jni_notification_presenter.h
+++ b/remoting/client/jni/jni_notification_presenter.h
@@ -7,11 +7,11 @@
 
 #include <jni.h>
 
+#include <optional>
 #include "base/android/jni_weak_ref.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/task/sequenced_task_runner.h"
 #include "remoting/client/notification/notification_client.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -31,7 +31,7 @@
   void Destroy(JNIEnv* env);
 
  private:
-  void OnNotificationFetched(absl::optional<NotificationMessage> notification);
+  void OnNotificationFetched(std::optional<NotificationMessage> notification);
 
   JavaObjectWeakGlobalRef java_presenter_;
   NotificationClient notification_client_;
diff --git a/remoting/client/notification/gstatic_json_fetcher.cc b/remoting/client/notification/gstatic_json_fetcher.cc
index 5213dd31..47c2bfe 100644
--- a/remoting/client/notification/gstatic_json_fetcher.cc
+++ b/remoting/client/notification/gstatic_json_fetcher.cc
@@ -20,9 +20,9 @@
 
 constexpr char kGstaticUrlPrefix[] = "https://www.gstatic.com/chromoting/";
 
-absl::optional<base::Value> GetResponse(std::unique_ptr<std::string> body) {
+std::optional<base::Value> GetResponse(std::unique_ptr<std::string> body) {
   if (!body)
-    return absl::nullopt;
+    return std::nullopt;
 
   return base::JSONReader::Read(*body);
 }
diff --git a/remoting/client/notification/json_fetcher.h b/remoting/client/notification/json_fetcher.h
index 0475344..7dfbf86 100644
--- a/remoting/client/notification/json_fetcher.h
+++ b/remoting/client/notification/json_fetcher.h
@@ -7,8 +7,8 @@
 
 #include <string>
 
+#include <optional>
 #include "base/functional/callback_forward.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class Value;
@@ -24,14 +24,14 @@
 class JsonFetcher {
  public:
   using FetchJsonFileCallback =
-      base::OnceCallback<void(absl::optional<base::Value>)>;
+      base::OnceCallback<void(std::optional<base::Value>)>;
 
   JsonFetcher() = default;
   virtual ~JsonFetcher() = default;
 
   // |relative_path| is relative to https://www.gstatic.com/chromoting/.
   // Runs |done| with the decoded value if the file is successfully fetched,
-  // otherwise runs |done| with absl::nullopt.
+  // otherwise runs |done| with std::nullopt.
   //
   // Note that the implementation MUST be able to handle concurrent requests and
   // MUST NOT keep |done| after its destructor is called.
diff --git a/remoting/client/notification/notification_client.cc b/remoting/client/notification/notification_client.cc
index 94fbe60..5c9da0b 100644
--- a/remoting/client/notification/notification_client.cc
+++ b/remoting/client/notification/notification_client.cc
@@ -151,12 +151,12 @@
         out_message_translation_(out_message_translation),
         out_link_translation_(out_link_translation) {}
 
-  void OnMessageTranslationsFetched(absl::optional<base::Value> translations) {
+  void OnMessageTranslationsFetched(std::optional<base::Value> translations) {
     is_message_translation_fetched_ = true;
     OnTranslationsFetched(std::move(translations), out_message_translation_);
   }
 
-  void OnLinkTranslationsFetched(absl::optional<base::Value> translations) {
+  void OnLinkTranslationsFetched(std::optional<base::Value> translations) {
     is_link_translation_fetched_ = true;
     OnTranslationsFetched(std::move(translations), out_link_translation_);
   }
@@ -166,7 +166,7 @@
 
   ~MessageAndLinkTextResults() = default;
 
-  void OnTranslationsFetched(absl::optional<base::Value> translations,
+  void OnTranslationsFetched(std::optional<base::Value> translations,
                              std::string* string_to_update) {
     if (!done_) {
       LOG(WARNING) << "Received new translations after some translations have "
@@ -287,16 +287,16 @@
 
 void NotificationClient::OnRulesFetched(const std::string& user_email,
                                         NotificationCallback callback,
-                                        absl::optional<base::Value> rules) {
+                                        std::optional<base::Value> rules) {
   if (!rules) {
     LOG(ERROR) << "Rules not found";
-    std::move(callback).Run(absl::nullopt);
+    std::move(callback).Run(std::nullopt);
     return;
   }
 
   if (!rules->is_list()) {
     LOG(ERROR) << "Rules should be list";
-    std::move(callback).Run(absl::nullopt);
+    std::move(callback).Run(std::nullopt);
     return;
   }
 
@@ -314,10 +314,10 @@
     }
   }
   // No matching rule is found.
-  std::move(callback).Run(absl::nullopt);
+  std::move(callback).Run(std::nullopt);
 }
 
-absl::optional<NotificationMessage> NotificationClient::ParseAndMatchRule(
+std::optional<NotificationMessage> NotificationClient::ParseAndMatchRule(
     const base::Value::Dict& rule,
     const std::string& user_email,
     std::string* out_message_text_filename,
@@ -336,32 +336,32 @@
       !FindKeyAndGet(rule, "link_text", &link_text_filename) ||
       !FindKeyAndGet(rule, "link_url", &link_url) ||
       !FindKeyAndGet(rule, "percent", &percent)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (should_ignore_dev_messages_) {
     bool is_dev_mode;
     if (FindKeyAndGet(rule, "dev_mode", &is_dev_mode) && is_dev_mode) {
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
 
   if (target_platform != current_platform_) {
     VLOG(1) << "Notification ignored. Target platform: " << target_platform
             << "; current platform: " << current_platform_;
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   VersionRange version_range(version_spec_string);
   if (!version_range.IsValid()) {
     LOG(ERROR) << "Invalid version range: " << version_spec_string;
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (!version_range.ContainsVersion(current_version_)) {
     VLOG(1) << "Current version " << current_version_ << " not in range "
             << version_spec_string;
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // OS version check is not performed if |os_version| is not specified.
@@ -370,21 +370,21 @@
     VersionRange os_version_range(os_version_spec_string);
     if (!os_version_range.IsValid()) {
       LOG(ERROR) << "Invalid OS version range: " << os_version_spec_string;
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (!os_version_range.ContainsVersion(current_os_version_)) {
       VLOG(1) << "Current OS version " << current_os_version_
               << " not in range " << os_version_spec_string;
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
 
   if (!ShouldShowNotificationForUser(user_email, percent)) {
     VLOG(1) << "User is not selected for notification";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  auto message = absl::make_optional<NotificationMessage>();
+  auto message = std::make_optional<NotificationMessage>();
   message->message_id = message_id;
   message->link_url = link_url;
   message->allow_silence = false;
@@ -397,9 +397,9 @@
 void NotificationClient::FetchTranslatedTexts(
     const std::string& message_text_filename,
     const std::string& link_text_filename,
-    absl::optional<NotificationMessage> partial_message,
+    std::optional<NotificationMessage> partial_message,
     NotificationCallback done) {
-  // Copy the message into a unique_ptr since moving absl::optional does not
+  // Copy the message into a unique_ptr since moving std::optional does not
   // move the internal storage.
   auto message_copy = std::make_unique<NotificationMessage>(*partial_message);
   std::string* message_text_ptr = &message_copy->message_text;
@@ -408,8 +408,8 @@
       [](std::unique_ptr<NotificationMessage> message,
          NotificationCallback done, bool is_successful) {
         std::move(done).Run(
-            is_successful ? absl::make_optional<NotificationMessage>(*message)
-                          : absl::nullopt);
+            is_successful ? std::make_optional<NotificationMessage>(*message)
+                          : std::nullopt);
       },
       std::move(message_copy), std::move(done));
   auto results = base::MakeRefCounted<MessageAndLinkTextResults>(
diff --git a/remoting/client/notification/notification_client.h b/remoting/client/notification/notification_client.h
index 6d334cd..149dd787 100644
--- a/remoting/client/notification/notification_client.h
+++ b/remoting/client/notification/notification_client.h
@@ -8,10 +8,10 @@
 #include <memory>
 #include <string>
 
+#include <optional>
 #include "base/functional/callback_forward.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -23,7 +23,7 @@
 class NotificationClient final {
  public:
   using NotificationCallback =
-      base::OnceCallback<void(absl::optional<NotificationMessage>)>;
+      base::OnceCallback<void(std::optional<NotificationMessage>)>;
 
   explicit NotificationClient(
       scoped_refptr<base::SingleThreadTaskRunner> network_task_runner);
@@ -35,7 +35,7 @@
 
   // Fetches notifications from the server and calls |callback| with the
   // best matched notification. If notifications failed to fetch or no matching
-  // notification is found then absl::nullopt will be returned. |callback| will
+  // notification is found then std::nullopt will be returned. |callback| will
   // be silently dropped if |this| is deleted before the notification is
   // fetched.
   // |user_email| is used to determine if the notification is available to the
@@ -58,12 +58,12 @@
 
   void OnRulesFetched(const std::string& user_email,
                       NotificationCallback callback,
-                      absl::optional<base::Value> rules);
+                      std::optional<base::Value> rules);
 
   // Returns non-empty NotificationMessage if the rule is parsed successfully
   // and the rule should apply to the user. |message_text| and |link_text| will
   // not be set and caller needs to call FetchTranslatedText to fill them up.
-  absl::optional<NotificationMessage> ParseAndMatchRule(
+  std::optional<NotificationMessage> ParseAndMatchRule(
       const base::Value::Dict& rule,
       const std::string& user_email,
       std::string* out_message_text_filename,
@@ -71,7 +71,7 @@
 
   void FetchTranslatedTexts(const std::string& message_text_filename,
                             const std::string& link_text_filename,
-                            absl::optional<NotificationMessage> partial_message,
+                            std::optional<NotificationMessage> partial_message,
                             NotificationCallback done);
 
   std::unique_ptr<JsonFetcher> fetcher_;
diff --git a/remoting/client/notification/notification_client_unittest.cc b/remoting/client/notification/notification_client_unittest.cc
index 671b2060..1013010ab 100644
--- a/remoting/client/notification/notification_client_unittest.cc
+++ b/remoting/client/notification/notification_client_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <memory>
 
+#include <optional>
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/test/mock_callback.h"
@@ -14,7 +15,6 @@
 #include "remoting/client/notification/notification_message.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -33,7 +33,7 @@
  public:
   // GMock doesn't work with rvalue parameters. This works around it.
   MOCK_CONST_METHOD1(FetchJsonFile,
-                     absl::optional<base::Value>(const std::string&));
+                     std::optional<base::Value>(const std::string&));
   void FetchJsonFile(const std::string& relative_path,
                      FetchJsonFileCallback done,
                      const net::NetworkTrafficAnnotationTag&) override {
@@ -250,9 +250,9 @@
   base::Value translation = CreateDefaultTranslations("message");
 
   EXPECT_CALL(*fetcher_, FetchJsonFile("notification/message_text.json"))
-      .WillOnce(ReturnByMove(absl::nullopt));
+      .WillOnce(ReturnByMove(std::nullopt));
   EXPECT_CALL(*fetcher_, FetchJsonFile("notification/link_text.json"))
-      .WillOnce(ReturnByMove(absl::nullopt));
+      .WillOnce(ReturnByMove(std::nullopt));
 
   base::MockCallback<NotificationClient::NotificationCallback> callback;
   EXPECT_CALL(callback, Run(NoMessage()));
diff --git a/remoting/client/notification/version_range.cc b/remoting/client/notification/version_range.cc
index 00fd81e..efec5ac 100644
--- a/remoting/client/notification/version_range.cc
+++ b/remoting/client/notification/version_range.cc
@@ -30,8 +30,8 @@
   size_t dash_pos = range_spec.find('-');
   if (dash_pos == std::string::npos) {
     // May be a single version string.
-    min_version_ = absl::make_optional<base::Version>(range_spec);
-    max_version_ = absl::make_optional<base::Version>(*min_version_);
+    min_version_ = std::make_optional<base::Version>(range_spec);
+    max_version_ = std::make_optional<base::Version>(*min_version_);
     is_min_version_inclusive_ = true;
     is_max_version_inclusive_ = true;
     return;
@@ -60,9 +60,9 @@
     // Unbound min version.
     std::vector<uint32_t> version_components{kUnboundMinVersionNumber};
     min_version_ =
-        absl::make_optional<base::Version>(std::move(version_components));
+        std::make_optional<base::Version>(std::move(version_components));
   } else {
-    min_version_ = absl::make_optional<base::Version>(min_version_string);
+    min_version_ = std::make_optional<base::Version>(min_version_string);
   }
 
   std::string max_version_string = range_spec.substr(dash_pos + 1);
@@ -71,9 +71,9 @@
     // Unbound max version.
     std::vector<uint32_t> version_components{kUnboundMaxVersionNumber};
     max_version_ =
-        absl::make_optional<base::Version>(std::move(version_components));
+        std::make_optional<base::Version>(std::move(version_components));
   } else {
-    max_version_ = absl::make_optional<base::Version>(max_version_string);
+    max_version_ = std::make_optional<base::Version>(max_version_string);
   }
 }
 
diff --git a/remoting/client/notification/version_range.h b/remoting/client/notification/version_range.h
index e61f0f3..ab93fe9 100644
--- a/remoting/client/notification/version_range.h
+++ b/remoting/client/notification/version_range.h
@@ -7,8 +7,8 @@
 
 #include <string>
 
+#include <optional>
 #include "base/version.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -41,8 +41,8 @@
   bool ContainsVersion(const std::string& version_string) const;
 
  private:
-  absl::optional<base::Version> min_version_;
-  absl::optional<base::Version> max_version_;
+  std::optional<base::Version> min_version_;
+  std::optional<base::Version> max_version_;
 
   bool is_min_version_inclusive_ = false;
   bool is_max_version_inclusive_ = false;
diff --git a/remoting/host/base/desktop_environment_options.cc b/remoting/host/base/desktop_environment_options.cc
index 8cedf64..541ef0f 100644
--- a/remoting/host/base/desktop_environment_options.cc
+++ b/remoting/host/base/desktop_environment_options.cc
@@ -7,8 +7,8 @@
 #include <string>
 #include <utility>
 
+#include <optional>
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -105,13 +105,12 @@
   enable_remote_webauthn_ = enabled;
 }
 
-const absl::optional<size_t>& DesktopEnvironmentOptions::clipboard_size()
-    const {
+const std::optional<size_t>& DesktopEnvironmentOptions::clipboard_size() const {
   return clipboard_size_;
 }
 
 void DesktopEnvironmentOptions::set_clipboard_size(
-    absl::optional<size_t> clipboard_size) {
+    std::optional<size_t> clipboard_size) {
   clipboard_size_ = std::move(clipboard_size);
 }
 
@@ -134,12 +133,12 @@
 void DesktopEnvironmentOptions::ApplySessionOptions(
     const SessionOptions& options) {
   // This field is for test purpose. Usually it should not be set to false.
-  absl::optional<bool> detect_updated_region =
+  std::optional<bool> detect_updated_region =
       options.GetBool("Detect-Updated-Region");
   if (detect_updated_region.has_value()) {
     desktop_capture_options_.set_detect_updated_region(*detect_updated_region);
   }
-  absl::optional<bool> capture_video_on_dedicated_thread =
+  std::optional<bool> capture_video_on_dedicated_thread =
       options.GetBool("Capture-Video-On-Dedicated-Thread");
   if (capture_video_on_dedicated_thread.has_value()) {
     set_capture_video_on_dedicated_thread(*capture_video_on_dedicated_thread);
diff --git a/remoting/host/base/desktop_environment_options.h b/remoting/host/base/desktop_environment_options.h
index d695d1f..3176586 100644
--- a/remoting/host/base/desktop_environment_options.h
+++ b/remoting/host/base/desktop_environment_options.h
@@ -5,9 +5,9 @@
 #ifndef REMOTING_HOST_BASE_DESKTOP_ENVIRONMENT_OPTIONS_H_
 #define REMOTING_HOST_BASE_DESKTOP_ENVIRONMENT_OPTIONS_H_
 
+#include <optional>
 #include "base/memory/weak_ptr.h"
 #include "remoting/base/session_options.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
 
 namespace remoting {
@@ -50,8 +50,8 @@
   bool enable_remote_webauthn() const;
   void set_enable_remote_webauthn(bool enabled);
 
-  const absl::optional<size_t>& clipboard_size() const;
-  void set_clipboard_size(absl::optional<size_t> clipboard_size);
+  const std::optional<size_t>& clipboard_size() const;
+  void set_clipboard_size(std::optional<size_t> clipboard_size);
 
   const webrtc::DesktopCaptureOptions* desktop_capture_options() const;
   webrtc::DesktopCaptureOptions* desktop_capture_options();
@@ -93,7 +93,7 @@
   // If set, this value is used to constrain the amount of data that can be
   // transferred using ClipboardEvents. A value of 0 will effectively disable
   // clipboard sharing.
-  absl::optional<size_t> clipboard_size_;
+  std::optional<size_t> clipboard_size_;
 
   // True if the video capturer should be run on a dedicated thread.
   bool capture_video_on_dedicated_thread_ = false;
diff --git a/remoting/host/base/screen_controls.h b/remoting/host/base/screen_controls.h
index e339093..4772bda1 100644
--- a/remoting/host/base/screen_controls.h
+++ b/remoting/host/base/screen_controls.h
@@ -5,7 +5,7 @@
 #ifndef REMOTING_HOST_BASE_SCREEN_CONTROLS_H_
 #define REMOTING_HOST_BASE_SCREEN_CONTROLS_H_
 
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include <optional>
 #include "third_party/webrtc/modules/desktop_capture/desktop_capture_types.h"
 
 namespace remoting {
@@ -34,7 +34,7 @@
   // resized).
   virtual void SetScreenResolution(
       const ScreenResolution& resolution,
-      absl::optional<webrtc::ScreenId> screen_id) = 0;
+      std::optional<webrtc::ScreenId> screen_id) = 0;
 
   virtual void SetVideoLayout(const protocol::VideoLayout& video_layout) = 0;
 };
diff --git a/remoting/host/chromeos/file_session_storage.cc b/remoting/host/chromeos/file_session_storage.cc
index 84c458e..4571641 100644
--- a/remoting/host/chromeos/file_session_storage.cc
+++ b/remoting/host/chromeos/file_session_storage.cc
@@ -4,6 +4,7 @@
 
 #include "remoting/host/chromeos/file_session_storage.h"
 
+#include <optional>
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/functional/callback.h"
@@ -15,7 +16,6 @@
 #include "base/task/thread_pool.h"
 #include "base/values.h"
 #include "chrome/common/chrome_paths.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -24,8 +24,8 @@
 constexpr char kStoredSessionFileName[] = "session";
 
 template <class T>
-absl::optional<T> make_nullopt() {
-  return absl::nullopt;
+std::optional<T> make_nullopt() {
+  return std::nullopt;
 }
 
 base::TaskTraits GetFileTaskTraits() {
@@ -61,19 +61,19 @@
 
 // Wrapper around base::ReadFileToString that returns the result as an optional
 // string.
-absl::optional<std::string> ReadFileToString(const base::FilePath& file) {
+std::optional<std::string> ReadFileToString(const base::FilePath& file) {
   std::string result;
   bool success = base::ReadFileToString(file, &result);
   if (success) {
     return result;
   } else {
-    return absl::nullopt;
+    return std::nullopt;
   }
 }
 
 void ReadFileAsync(
     const base::FilePath& file,
-    base::OnceCallback<void(absl::optional<std::string>)> on_done) {
+    base::OnceCallback<void(std::optional<std::string>)> on_done) {
   base::ThreadPool::PostTaskAndReplyWithResult(
       FROM_HERE, GetFileTaskTraits(), base::BindOnce(&ReadFileToString, file),
       std::move(on_done));
@@ -111,9 +111,9 @@
 }
 
 void FileSessionStorage::RetrieveSession(
-    base::OnceCallback<void(absl::optional<base::Value::Dict>)> on_done) {
+    base::OnceCallback<void(std::optional<base::Value::Dict>)> on_done) {
   ReadFileAsync(session_file(),
-                base::BindOnce([](absl::optional<std::string> content) {
+                base::BindOnce([](std::optional<std::string> content) {
                   if (!content.has_value()) {
                     LOG(ERROR) << "Failed to read CRD session information file";
                     return make_nullopt<base::Value::Dict>();
diff --git a/remoting/host/chromeos/file_session_storage.h b/remoting/host/chromeos/file_session_storage.h
index 5fcafd8a..f04ccdc3 100644
--- a/remoting/host/chromeos/file_session_storage.h
+++ b/remoting/host/chromeos/file_session_storage.h
@@ -31,7 +31,7 @@
                     base::OnceClosure on_done) override;
   void DeleteSession(base::OnceClosure on_done) override;
   void RetrieveSession(
-      base::OnceCallback<void(absl::optional<base::Value::Dict>)> on_done)
+      base::OnceCallback<void(std::optional<base::Value::Dict>)> on_done)
       override;
   void HasSession(base::OnceCallback<void(bool)> on_done) const override;
 
diff --git a/remoting/host/chromeos/file_session_storage_unittest.cc b/remoting/host/chromeos/file_session_storage_unittest.cc
index 752e6e9..89be890a 100644
--- a/remoting/host/chromeos/file_session_storage_unittest.cc
+++ b/remoting/host/chromeos/file_session_storage_unittest.cc
@@ -4,12 +4,12 @@
 
 #include "remoting/host/chromeos/file_session_storage.h"
 
+#include <optional>
 #include "base/files/scoped_temp_dir.h"
 #include "base/test/task_environment.h"
 #include "base/test/test_future.h"
 #include "base/test/values_test_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -44,8 +44,8 @@
     ASSERT_TRUE(done_signal.Wait());
   }
 
-  absl::optional<base::Value::Dict> RetrieveSession() {
-    TestFuture<absl::optional<base::Value::Dict>> done_signal;
+  std::optional<base::Value::Dict> RetrieveSession() {
+    TestFuture<std::optional<base::Value::Dict>> done_signal;
     storage().RetrieveSession(done_signal.GetCallback());
     return done_signal.Take();
   }
@@ -80,7 +80,7 @@
 
 TEST_F(FileSessionStorageTest,
        RetrieveSessionShouldReturnNullIfNoSessionIsStored) {
-  EXPECT_EQ(RetrieveSession(), absl::nullopt);
+  EXPECT_EQ(RetrieveSession(), std::nullopt);
 }
 
 TEST_F(FileSessionStorageTest,
@@ -90,7 +90,7 @@
 
   StoreSession(session_information);
 
-  absl::optional<base::Value::Dict> result = RetrieveSession();
+  std::optional<base::Value::Dict> result = RetrieveSession();
   ASSERT_TRUE(result.has_value());
   EXPECT_THAT(result.value(), base::test::IsJson(session_information));
 }
diff --git a/remoting/host/chromeos/frame_sink_desktop_capturer.h b/remoting/host/chromeos/frame_sink_desktop_capturer.h
index cedb377..da59c5d 100644
--- a/remoting/host/chromeos/frame_sink_desktop_capturer.h
+++ b/remoting/host/chromeos/frame_sink_desktop_capturer.h
@@ -5,12 +5,12 @@
 #ifndef REMOTING_HOST_CHROMEOS_FRAME_SINK_DESKTOP_CAPTURER_H_
 #define REMOTING_HOST_CHROMEOS_FRAME_SINK_DESKTOP_CAPTURER_H_
 
+#include <optional>
 #include "base/memory/raw_ref.h"
 #include "base/memory/weak_ptr.h"
 #include "components/viz/host/client_frame_sink_video_capturer.h"
 #include "remoting/host/chromeos/ash_mojom_video_consumer.h"
 #include "remoting/host/chromeos/ash_proxy.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
 #include "ui/aura/scoped_window_capture_request.h"
 #include "ui/display/display.h"
@@ -43,7 +43,7 @@
   const display::Display* GetSourceDisplay();
 
  private:
-  absl::optional<viz::ClientFrameSinkVideoCapturer> video_capturer_;
+  std::optional<viz::ClientFrameSinkVideoCapturer> video_capturer_;
   const raw_ref<AshProxy, ExperimentalAsh> ash_;
   AshMojomVideoConsumer video_consumer_;
   raw_ptr<DesktopCapturer::Callback> callback_ = nullptr;
diff --git a/remoting/host/chromeos/frame_sink_desktop_capturer_unittest.cc b/remoting/host/chromeos/frame_sink_desktop_capturer_unittest.cc
index f7a92eb..0d97f85 100644
--- a/remoting/host/chromeos/frame_sink_desktop_capturer_unittest.cc
+++ b/remoting/host/chromeos/frame_sink_desktop_capturer_unittest.cc
@@ -203,7 +203,7 @@
 
   MOCK_METHOD(void,
               ChangeTarget,
-              (const absl::optional<viz::VideoCaptureTarget>& target,
+              (const std::optional<viz::VideoCaptureTarget>& target,
                uint32_t sub_capture_target_version));
 
   MOCK_METHOD(void,
@@ -416,7 +416,7 @@
   AddMultipleDisplays();
 
   DisplayId primary_display_id = ash_proxy().GetPrimaryDisplayId();
-  const auto expected_target = absl::optional<viz::VideoCaptureTarget>(
+  const auto expected_target = std::optional<viz::VideoCaptureTarget>(
       ash_proxy().GetFrameSinkId(primary_display_id));
 
   EXPECT_CALL(video_capturer_, ChangeTarget(expected_target, 0));
@@ -574,7 +574,7 @@
   Size size(234, 56);
 
   StartCapturerForTesting();
-  const absl::optional<viz::VideoCaptureTarget> expected_target(
+  const std::optional<viz::VideoCaptureTarget> expected_target(
       ash_proxy().GetFrameSinkId(new_display_id));
 
   EXPECT_CALL(video_capturer_, ChangeTarget(expected_target, 0));
diff --git a/remoting/host/chromeos/mouse_cursor_monitor_aura.cc b/remoting/host/chromeos/mouse_cursor_monitor_aura.cc
index 14e2ea6..f52f463 100644
--- a/remoting/host/chromeos/mouse_cursor_monitor_aura.cc
+++ b/remoting/host/chromeos/mouse_cursor_monitor_aura.cc
@@ -6,12 +6,12 @@
 
 #include <utility>
 
+#include <optional>
 #include "ash/shell.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
 #include "base/location.h"
 #include "remoting/host/chromeos/skia_bitmap_desktop_frame.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/webrtc/modules/desktop_capture/mouse_cursor.h"
 #include "ui/aura/client/cursor_shape_client.h"
@@ -74,7 +74,7 @@
     return;
   }
 
-  absl::optional<ui::CursorData> cursor_data =
+  std::optional<ui::CursorData> cursor_data =
       aura::client::GetCursorShapeClient().GetCursorData(cursor);
   if (!cursor_data) {
     LOG(ERROR) << "Failed to load bitmap for cursor type: " << cursor.type();
diff --git a/remoting/host/chromeos/remote_support_host_ash.cc b/remoting/host/chromeos/remote_support_host_ash.cc
index 00787d55..7e61755 100644
--- a/remoting/host/chromeos/remote_support_host_ash.cc
+++ b/remoting/host/chromeos/remote_support_host_ash.cc
@@ -7,6 +7,7 @@
 #include <stddef.h>
 #include <utility>
 
+#include <optional>
 #include "base/feature_list.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
@@ -24,7 +25,6 @@
 #include "remoting/host/it2me/it2me_native_messaging_host_ash.h"
 #include "remoting/host/it2me/reconnect_params.h"
 #include "remoting/host/policy_watcher.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -123,15 +123,15 @@
 
 void RemoteSupportHostAsh::StartSession(
     const mojom::SupportSessionParams& params,
-    const absl::optional<ChromeOsEnterpriseParams>& enterprise_params,
+    const std::optional<ChromeOsEnterpriseParams>& enterprise_params,
     StartSessionCallback callback) {
-  StartSession(params, enterprise_params, absl::nullopt, std::move(callback));
+  StartSession(params, enterprise_params, std::nullopt, std::move(callback));
 }
 
 void RemoteSupportHostAsh::StartSession(
     const mojom::SupportSessionParams& params,
-    const absl::optional<ChromeOsEnterpriseParams>& enterprise_params,
-    const absl::optional<ReconnectParams>& reconnect_params,
+    const std::optional<ChromeOsEnterpriseParams>& enterprise_params,
+    const std::optional<ReconnectParams>& reconnect_params,
     StartSessionCallback callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
@@ -230,8 +230,8 @@
 
 void RemoteSupportHostAsh::OnHostStateConnected(
     mojom::SupportSessionParams session_params,
-    absl::optional<ChromeOsEnterpriseParams> enterprise_params,
-    absl::optional<ReconnectParams> reconnect_params) {
+    std::optional<ChromeOsEnterpriseParams> enterprise_params,
+    std::optional<ReconnectParams> reconnect_params) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (!base::FeatureList::IsEnabled(kEnableCrdAdminRemoteAccessV2)) {
diff --git a/remoting/host/chromeos/remote_support_host_ash.h b/remoting/host/chromeos/remote_support_host_ash.h
index e56c507c..28fbe7e 100644
--- a/remoting/host/chromeos/remote_support_host_ash.h
+++ b/remoting/host/chromeos/remote_support_host_ash.h
@@ -6,6 +6,7 @@
 #define REMOTING_HOST_CHROMEOS_REMOTE_SUPPORT_HOST_ASH_H_
 
 #include <memory>
+#include <optional>
 #include "base/functional/callback.h"
 #include "base/memory/raw_ref.h"
 #include "base/memory/scoped_refptr.h"
@@ -14,7 +15,6 @@
 #include "remoting/host/chromeos/session_id.h"
 #include "remoting/host/it2me/it2me_native_messaging_host_ash.h"
 #include "remoting/host/mojom/remote_support.mojom-forward.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -56,7 +56,7 @@
   // called with the result.
   void StartSession(
       const mojom::SupportSessionParams& params,
-      const absl::optional<ChromeOsEnterpriseParams>& enterprise_params,
+      const std::optional<ChromeOsEnterpriseParams>& enterprise_params,
       StartSessionCallback callback);
 
   // Allows the caller to resume the given remote support session.
@@ -68,13 +68,13 @@
  private:
   void StartSession(
       const mojom::SupportSessionParams& params,
-      const absl::optional<ChromeOsEnterpriseParams>& enterprise_params,
-      const absl::optional<ReconnectParams>& reconnect_params,
+      const std::optional<ChromeOsEnterpriseParams>& enterprise_params,
+      const std::optional<ReconnectParams>& reconnect_params,
       StartSessionCallback callback);
 
   void OnHostStateConnected(mojom::SupportSessionParams,
-                            absl::optional<ChromeOsEnterpriseParams>,
-                            absl::optional<ReconnectParams>);
+                            std::optional<ChromeOsEnterpriseParams>,
+                            std::optional<ReconnectParams>);
   void OnHostStateDisconnected();
   void OnSessionDisconnected();
 
diff --git a/remoting/host/chromeos/remote_support_host_ash_unittest.cc b/remoting/host/chromeos/remote_support_host_ash_unittest.cc
index 76f9e59..8828101 100644
--- a/remoting/host/chromeos/remote_support_host_ash_unittest.cc
+++ b/remoting/host/chromeos/remote_support_host_ash_unittest.cc
@@ -188,12 +188,12 @@
     std::move(on_done).Run();
   }
   void RetrieveSession(
-      base::OnceCallback<void(absl::optional<base::Value::Dict>)> on_done)
+      base::OnceCallback<void(std::optional<base::Value::Dict>)> on_done)
       override {
     if (session_.has_value()) {
       std::move(on_done).Run(session_.value().Clone());
     } else {
-      std::move(on_done).Run(absl::nullopt);
+      std::move(on_done).Run(std::nullopt);
     }
   }
   void HasSession(base::OnceCallback<void(bool)> on_done) const override {
@@ -201,7 +201,7 @@
   }
 
  private:
-  absl::optional<base::Value::Dict> session_;
+  std::optional<base::Value::Dict> session_;
 };
 
 bool HasSession(SessionStorage& storage) {
@@ -231,13 +231,13 @@
   }
 
   mojom::StartSupportSessionResponsePtr StartSession(
-      absl::optional<ChromeOsEnterpriseParams> enterprise_params) {
+      std::optional<ChromeOsEnterpriseParams> enterprise_params) {
     return StartSession(GetSupportSessionParams(), enterprise_params);
   }
 
   mojom::StartSupportSessionResponsePtr StartSession(
       const mojom::SupportSessionParams& params,
-      absl::optional<ChromeOsEnterpriseParams> enterprise_params) {
+      std::optional<ChromeOsEnterpriseParams> enterprise_params) {
     TestFuture<mojom::StartSupportSessionResponsePtr> connect_result;
     support_host().StartSession(params, enterprise_params,
                                 connect_result.GetCallback());
@@ -468,7 +468,7 @@
        ShouldNotStoreSessionInfoIfEnterpriseParamsAreUnset) {
   EnableFeature(kEnableCrdAdminRemoteAccessV2);
 
-  StartSession(absl::nullopt);
+  StartSession(std::nullopt);
   SignalHostStateConnected();
 
   ASSERT_FALSE(HasSession(session_storage()));
@@ -681,7 +681,7 @@
   it2me_host().WaitForConnectCall();
   ASSERT_TRUE(HasSession(session_storage()));
 
-  StartSession(/*enterprise_params=*/absl::nullopt);
+  StartSession(/*enterprise_params=*/std::nullopt);
 
   EXPECT_FALSE(HasSession(session_storage()));
 }
diff --git a/remoting/host/chromeos/remoting_service.cc b/remoting/host/chromeos/remoting_service.cc
index 5d02251..72c2bbc 100644
--- a/remoting/host/chromeos/remoting_service.cc
+++ b/remoting/host/chromeos/remoting_service.cc
@@ -7,11 +7,11 @@
 #include <memory>
 #include <utility>
 
+#include <optional>
 #include "base/no_destructor.h"
 #include "base/sequence_checker.h"
 #include "remoting/host/chromeos/file_session_storage.h"
 #include "remoting/host/chromeos/remote_support_host_ash.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -62,8 +62,8 @@
 
   session_storage_.HasSession(  //
       base::BindOnce([](bool has_session) {
-        return has_session ? absl::make_optional(kEnterpriseSessionId)
-                           : absl::nullopt;
+        return has_session ? std::make_optional(kEnterpriseSessionId)
+                           : std::nullopt;
       }).Then(std::move(callback)));
 }
 
diff --git a/remoting/host/chromeos/remoting_service.h b/remoting/host/chromeos/remoting_service.h
index 5ea9fc32..f5b0a28c 100644
--- a/remoting/host/chromeos/remoting_service.h
+++ b/remoting/host/chromeos/remoting_service.h
@@ -5,9 +5,9 @@
 #ifndef REMOTING_HOST_CHROMEOS_REMOTING_SERVICE_H_
 #define REMOTING_HOST_CHROMEOS_REMOTING_SERVICE_H_
 
+#include <optional>
 #include "base/functional/callback_forward.h"
 #include "remoting/host/chromeos/session_id.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class FilePath;
@@ -24,7 +24,7 @@
 // which is bound to the Main/UI sequence in production code.
 class RemotingService {
  public:
-  using SessionIdCallback = base::OnceCallback<void(absl::optional<SessionId>)>;
+  using SessionIdCallback = base::OnceCallback<void(std::optional<SessionId>)>;
 
   static RemotingService& Get();
   virtual ~RemotingService() = default;
@@ -33,7 +33,7 @@
   virtual RemoteSupportHostAsh& GetSupportHost() = 0;
 
   // Allows the caller to query if information about a reconnectable session is
-  // stored. Invokes `callback` with the id of this session (or absl::nullopt if
+  // stored. Invokes `callback` with the id of this session (or std::nullopt if
   // there is no reconnectable session).
   virtual void GetReconnectableEnterpriseSessionId(
       SessionIdCallback callback) = 0;
diff --git a/remoting/host/chromeos/remoting_service_unittest.cc b/remoting/host/chromeos/remoting_service_unittest.cc
index ac9b42dd..7f9b590a 100644
--- a/remoting/host/chromeos/remoting_service_unittest.cc
+++ b/remoting/host/chromeos/remoting_service_unittest.cc
@@ -57,19 +57,19 @@
        ShouldReturnNoSessionIdIdIfThereIsNoReconnectableSession) {
   EnsureNoReconnectableSession();
 
-  TestFuture<absl::optional<SessionId>> future;
+  TestFuture<std::optional<SessionId>> future;
   remoting_service().GetReconnectableEnterpriseSessionId(future.GetCallback());
-  absl::optional<SessionId> result = future.Take();
+  std::optional<SessionId> result = future.Take();
 
-  EXPECT_EQ(result, absl::nullopt);
+  EXPECT_EQ(result, std::nullopt);
 }
 
 TEST_F(RemotingServiceTest, ShouldReturnEnterpriseSessionIdIfSessionIsStored) {
   CreateReconnectableSession();
 
-  TestFuture<absl::optional<SessionId>> future;
+  TestFuture<std::optional<SessionId>> future;
   remoting_service().GetReconnectableEnterpriseSessionId(future.GetCallback());
-  absl::optional<SessionId> result = future.Take();
+  std::optional<SessionId> result = future.Take();
 
   EXPECT_EQ(result, kEnterpriseSessionId);
 }
diff --git a/remoting/host/chromeos/session_storage.h b/remoting/host/chromeos/session_storage.h
index 1bb84041..eb8492d 100644
--- a/remoting/host/chromeos/session_storage.h
+++ b/remoting/host/chromeos/session_storage.h
@@ -5,9 +5,9 @@
 #ifndef REMOTING_HOST_CHROMEOS_SESSION_STORAGE_H_
 #define REMOTING_HOST_CHROMEOS_SESSION_STORAGE_H_
 
+#include <optional>
 #include "base/functional/callback_forward.h"
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -21,7 +21,7 @@
                             base::OnceClosure on_done) = 0;
   virtual void DeleteSession(base::OnceClosure on_done) = 0;
   virtual void RetrieveSession(
-      base::OnceCallback<void(absl::optional<base::Value::Dict>)> on_done) = 0;
+      base::OnceCallback<void(std::optional<base::Value::Dict>)> on_done) = 0;
 
   virtual void HasSession(base::OnceCallback<void(bool)> on_done) const = 0;
 };
diff --git a/remoting/host/client_session.cc b/remoting/host/client_session.cc
index a4036921..ed97e946 100644
--- a/remoting/host/client_session.cc
+++ b/remoting/host/client_session.cc
@@ -8,6 +8,7 @@
 #include <memory>
 #include <utility>
 
+#include <optional>
 #include "base/command_line.h"
 #include "base/containers/contains.h"
 #include "base/containers/cxx20_erase_map.h"
@@ -54,7 +55,6 @@
 #include "remoting/protocol/session.h"
 #include "remoting/protocol/session_config.h"
 #include "remoting/protocol/video_frame_pump.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
 
 #if defined(WEBRTC_USE_GIO)
@@ -165,7 +165,7 @@
 
   // Try to match the client's resolution.
   ScreenResolution screen_resolution(client_size, dpi_vector);
-  absl::optional<webrtc::ScreenId> screen_id;
+  std::optional<webrtc::ScreenId> screen_id;
   if (resolution.has_screen_id()) {
     screen_id = resolution.screen_id();
   }
@@ -462,8 +462,8 @@
   if (!connection_->peer_connection_controls()) {
     return;
   }
-  absl::optional<int> min_bitrate_bps;
-  absl::optional<int> max_bitrate_bps;
+  std::optional<int> min_bitrate_bps;
+  std::optional<int> max_bitrate_bps;
   bool set_preferred_bitrates = false;
   if (parameters.has_preferred_min_bitrate_bps()) {
     min_bitrate_bps = parameters.preferred_min_bitrate_bps();
diff --git a/remoting/host/crash/crash_file_uploader.cc b/remoting/host/crash/crash_file_uploader.cc
index f6af87d..5b7edc0 100644
--- a/remoting/host/crash/crash_file_uploader.cc
+++ b/remoting/host/crash/crash_file_uploader.cc
@@ -127,7 +127,7 @@
     return false;
   }
 
-  absl::optional<base::Value::Dict> opt_metadata =
+  std::optional<base::Value::Dict> opt_metadata =
       base::JSONReader::ReadDict(metadata_file_contents);
   if (!opt_metadata.has_value()) {
     error_reason = "Failed to parse metadata file contents";
diff --git a/remoting/host/daemon_process_win.cc b/remoting/host/daemon_process_win.cc
index 55a62c2..8208d1a 100644
--- a/remoting/host/daemon_process_win.cc
+++ b/remoting/host/daemon_process_win.cc
@@ -10,6 +10,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/base_switches.h"
 #include "base/command_line.h"
 #include "base/functional/bind.h"
@@ -51,7 +52,6 @@
 #include "remoting/host/win/security_descriptor.h"
 #include "remoting/host/win/unprivileged_process_delegate.h"
 #include "remoting/host/win/worker_process_launcher.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using base::win::ScopedHandle;
 
@@ -296,7 +296,7 @@
   LOG_IF(ERROR, !remoting_host_control_.is_connected())
       << "IPC channel not connected. HostConfig message will be dropped.";
 
-  absl::optional<base::Value::Dict> config(
+  std::optional<base::Value::Dict> config(
       HostConfigFromJson(serialized_config));
   if (!config.has_value()) {
     LOG(ERROR) << "Invalid host config, shutting down.";
diff --git a/remoting/host/desktop_display_layout_util_unittest.cc b/remoting/host/desktop_display_layout_util_unittest.cc
index a0ae4be..cc79480e3 100644
--- a/remoting/host/desktop_display_layout_util_unittest.cc
+++ b/remoting/host/desktop_display_layout_util_unittest.cc
@@ -6,10 +6,10 @@
 
 #include <vector>
 
+#include <optional>
 #include "build/build_config.h"
 #include "remoting/proto/control.pb.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_capture_types.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
 
@@ -49,7 +49,7 @@
     int height,
     int x_dpi,
     int y_dpi,
-    absl::optional<webrtc::ScreenId> screen_id) {
+    std::optional<webrtc::ScreenId> screen_id) {
   protocol::VideoTrackLayout layout;
   if (screen_id) {
     layout.set_screen_id(*screen_id);
diff --git a/remoting/host/desktop_session_agent.cc b/remoting/host/desktop_session_agent.cc
index 99534c2f..485e6b9 100644
--- a/remoting/host/desktop_session_agent.cc
+++ b/remoting/host/desktop_session_agent.cc
@@ -729,7 +729,7 @@
   CHECK(started_);
 
   if (screen_controls_) {
-    screen_controls_->SetScreenResolution(resolution, absl::nullopt);
+    screen_controls_->SetScreenResolution(resolution, std::nullopt);
   }
 }
 
diff --git a/remoting/host/desktop_session_agent.h b/remoting/host/desktop_session_agent.h
index bf71e19..f150027 100644
--- a/remoting/host/desktop_session_agent.h
+++ b/remoting/host/desktop_session_agent.h
@@ -11,6 +11,7 @@
 #include <map>
 #include <memory>
 
+#include <optional>
 #include "base/compiler_specific.h"
 #include "base/functional/callback.h"
 #include "base/memory/read_only_shared_memory_region.h"
@@ -30,7 +31,6 @@
 #include "remoting/host/mojom/remoting_mojom_traits.h"
 #include "remoting/proto/url_forwarder_control.pb.h"
 #include "remoting/protocol/clipboard_stub.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
 #include "third_party/webrtc/modules/desktop_capture/mouse_cursor_monitor.h"
@@ -252,7 +252,7 @@
 
   // Routes file-transfer messages to the corresponding reader/writer to be
   // executed.
-  absl::optional<SessionFileOperationsHandler> session_file_operations_handler_;
+  std::optional<SessionFileOperationsHandler> session_file_operations_handler_;
 
   mojo::AssociatedRemote<mojom::DesktopSessionEventHandler>
       desktop_session_event_handler_;
diff --git a/remoting/host/desktop_session_proxy.cc b/remoting/host/desktop_session_proxy.cc
index be54372..caaffff 100644
--- a/remoting/host/desktop_session_proxy.cc
+++ b/remoting/host/desktop_session_proxy.cc
@@ -413,7 +413,7 @@
   keyboard_layout_monitor_ = std::move(keyboard_layout_monitor);
 }
 
-const absl::optional<protocol::KeyboardLayout>&
+const std::optional<protocol::KeyboardLayout>&
 DesktopSessionProxy::GetKeyboardCurrentLayout() const {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
 
diff --git a/remoting/host/desktop_session_proxy.h b/remoting/host/desktop_session_proxy.h
index a2a3a97..7705719 100644
--- a/remoting/host/desktop_session_proxy.h
+++ b/remoting/host/desktop_session_proxy.h
@@ -10,6 +10,7 @@
 #include <memory>
 #include <vector>
 
+#include <optional>
 #include "base/callback_list.h"
 #include "base/functional/callback.h"
 #include "base/memory/read_only_shared_memory_region.h"
@@ -36,7 +37,6 @@
 #include "remoting/protocol/clipboard_stub.h"
 #include "remoting/protocol/desktop_capturer.h"
 #include "remoting/protocol/errors.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
 
 namespace base {
@@ -155,7 +155,7 @@
   // changes. Called on the |caller_task_runner_| thread.
   void SetKeyboardLayoutMonitor(
       const base::WeakPtr<IpcKeyboardLayoutMonitor>& keyboard_layout_monitor);
-  const absl::optional<protocol::KeyboardLayout>& GetKeyboardCurrentLayout()
+  const std::optional<protocol::KeyboardLayout>& GetKeyboardCurrentLayout()
       const;
 
   // APIs used to implement the InputInjector interface.
@@ -302,7 +302,7 @@
 
   // Caches the last keyboard layout received so it can be provided when Start
   // is called on IpcKeyboardLayoutMonitor.
-  absl::optional<protocol::KeyboardLayout> keyboard_layout_;
+  std::optional<protocol::KeyboardLayout> keyboard_layout_;
 
   // Used to notify registered handlers when the IPC channel is disconnected.
   base::OnceClosureList disconnect_handlers_;
diff --git a/remoting/host/fake_desktop_environment.cc b/remoting/host/fake_desktop_environment.cc
index 246a4e9..af1e2dcc 100644
--- a/remoting/host/fake_desktop_environment.cc
+++ b/remoting/host/fake_desktop_environment.cc
@@ -65,7 +65,7 @@
 
 void FakeScreenControls::SetScreenResolution(
     const ScreenResolution& resolution,
-    absl::optional<webrtc::ScreenId> screen_id) {}
+    std::optional<webrtc::ScreenId> screen_id) {}
 
 void FakeScreenControls::SetVideoLayout(
     const protocol::VideoLayout& video_layout) {}
diff --git a/remoting/host/fake_desktop_environment.h b/remoting/host/fake_desktop_environment.h
index 5aa4012..8ef609af 100644
--- a/remoting/host/fake_desktop_environment.h
+++ b/remoting/host/fake_desktop_environment.h
@@ -76,7 +76,7 @@
 
   // ScreenControls implementation.
   void SetScreenResolution(const ScreenResolution& resolution,
-                           absl::optional<webrtc::ScreenId> screen_id) override;
+                           std::optional<webrtc::ScreenId> screen_id) override;
   void SetVideoLayout(const protocol::VideoLayout& video_layout) override;
 };
 
diff --git a/remoting/host/file_transfer/buffered_file_writer_unittest.cc b/remoting/host/file_transfer/buffered_file_writer_unittest.cc
index 0a269d1..9dce784 100644
--- a/remoting/host/file_transfer/buffered_file_writer_unittest.cc
+++ b/remoting/host/file_transfer/buffered_file_writer_unittest.cc
@@ -35,7 +35,7 @@
   void OnError(protocol::FileTransfer_Error error);
 
   bool complete_called_ = false;
-  absl::optional<protocol::FileTransfer_Error> error_ = absl::nullopt;
+  std::optional<protocol::FileTransfer_Error> error_ = std::nullopt;
 
   base::test::TaskEnvironment task_environment_;
 };
diff --git a/remoting/host/file_transfer/fake_file_operations.cc b/remoting/host/file_transfer/fake_file_operations.cc
index cbd2690..f3be31b 100644
--- a/remoting/host/file_transfer/fake_file_operations.cc
+++ b/remoting/host/file_transfer/fake_file_operations.cc
@@ -93,7 +93,7 @@
 FakeFileOperations::InputFile::InputFile(
     base::FilePath filename,
     std::vector<std::uint8_t> data,
-    absl::optional<protocol::FileTransfer_Error> io_error)
+    std::optional<protocol::FileTransfer_Error> io_error)
     : filename(std::move(filename)),
       data(std::move(data)),
       io_error(std::move(io_error)) {}
diff --git a/remoting/host/file_transfer/fake_file_operations.h b/remoting/host/file_transfer/fake_file_operations.h
index 024e3ee..e619060 100644
--- a/remoting/host/file_transfer/fake_file_operations.h
+++ b/remoting/host/file_transfer/fake_file_operations.h
@@ -9,11 +9,11 @@
 #include <memory>
 #include <vector>
 
+#include <optional>
 #include "base/files/file_path.h"
 #include "base/memory/raw_ptr.h"
 #include "remoting/host/file_transfer/file_operations.h"
 #include "remoting/proto/file_transfer.pb.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -46,7 +46,7 @@
     InputFile();
     InputFile(base::FilePath filename,
               std::vector<std::uint8_t> data,
-              absl::optional<protocol::FileTransfer_Error> io_error);
+              std::optional<protocol::FileTransfer_Error> io_error);
     InputFile(const InputFile& other);
     InputFile(InputFile&& other);
     InputFile& operator=(const InputFile&);
@@ -61,7 +61,7 @@
 
     // If set, this error will be returned instead of EOF once the provided data
     // has been read.
-    absl::optional<protocol::FileTransfer_Error> io_error;
+    std::optional<protocol::FileTransfer_Error> io_error;
   };
 
   // Used to interact with FakeFileOperations after ownership is passed
@@ -79,7 +79,7 @@
     std::vector<OutputFile> files_written;
 
     // If set, file operations will return this error.
-    absl::optional<protocol::FileTransfer_Error> io_error = absl::nullopt;
+    std::optional<protocol::FileTransfer_Error> io_error = std::nullopt;
   };
 
   explicit FakeFileOperations(TestIo* test_io);
diff --git a/remoting/host/file_transfer/file_transfer_message_handler.h b/remoting/host/file_transfer/file_transfer_message_handler.h
index 118a454..66356864 100644
--- a/remoting/host/file_transfer/file_transfer_message_handler.h
+++ b/remoting/host/file_transfer/file_transfer_message_handler.h
@@ -10,13 +10,13 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/containers/queue.h"
 #include "base/memory/weak_ptr.h"
 #include "remoting/host/file_transfer/buffered_file_writer.h"
 #include "remoting/host/file_transfer/file_operations.h"
 #include "remoting/protocol/file_transfer_helpers.h"
 #include "remoting/protocol/named_message_pipe_handler.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -84,7 +84,7 @@
 
   State state_ = kConnected;
   std::unique_ptr<FileOperations> file_operations_;
-  absl::optional<BufferedFileWriter> buffered_file_writer_;
+  std::optional<BufferedFileWriter> buffered_file_writer_;
   std::unique_ptr<FileOperations::Reader> file_reader_;
   std::size_t queued_chunks_ = 0;
   base::WeakPtrFactory<FileTransferMessageHandler> weak_ptr_factory_{this};
diff --git a/remoting/host/file_transfer/file_transfer_message_handler_unittest.cc b/remoting/host/file_transfer/file_transfer_message_handler_unittest.cc
index 6e8475f4..606223e 100644
--- a/remoting/host/file_transfer/file_transfer_message_handler_unittest.cc
+++ b/remoting/host/file_transfer/file_transfer_message_handler_unittest.cc
@@ -350,7 +350,7 @@
 
   test_io.input_file = FakeFileOperations::InputFile(
       base::FilePath::FromASCII(kTestFilename),
-      ByteArrayFrom(kTestDataOne, kTestDataTwo, kTestDataThree), absl::nullopt);
+      ByteArrayFrom(kTestDataOne, kTestDataTwo, kTestDataThree), std::nullopt);
 
   // This will delete itself when fake_pipe_->ClosePipe() is called.
   new FileTransferMessageHandler(kTestDatachannelName, fake_pipe_->Wrap(),
diff --git a/remoting/host/file_transfer/ipc_file_operations.cc b/remoting/host/file_transfer/ipc_file_operations.cc
index 78f36ad..d2aa8ea 100644
--- a/remoting/host/file_transfer/ipc_file_operations.cc
+++ b/remoting/host/file_transfer/ipc_file_operations.cc
@@ -135,9 +135,9 @@
  private:
   void OnOpenResult(mojom::BeginFileWriteResultPtr result);
   void OnOperationResult(
-      const absl::optional<::remoting::protocol::FileTransfer_Error>& error);
+      const std::optional<::remoting::protocol::FileTransfer_Error>& error);
   void OnCloseResult(
-      const absl::optional<::remoting::protocol::FileTransfer_Error>& error);
+      const std::optional<::remoting::protocol::FileTransfer_Error>& error);
 
   State state_ GUARDED_BY_CONTEXT(sequence_checker_) = kCreated;
   Callback pending_callback_ GUARDED_BY_CONTEXT(sequence_checker_);
@@ -403,7 +403,7 @@
 }
 
 void IpcFileOperations::IpcWriter::OnOperationResult(
-    const absl::optional<::remoting::protocol::FileTransfer_Error>& error) {
+    const std::optional<::remoting::protocol::FileTransfer_Error>& error) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (error) {
@@ -418,7 +418,7 @@
 }
 
 void IpcFileOperations::IpcWriter::OnCloseResult(
-    const absl::optional<::remoting::protocol::FileTransfer_Error>& error) {
+    const std::optional<::remoting::protocol::FileTransfer_Error>& error) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   // We're done with the remote regardless of the result.
diff --git a/remoting/host/file_transfer/ipc_file_operations_unittest.cc b/remoting/host/file_transfer/ipc_file_operations_unittest.cc
index a8527883..cb698f95f 100644
--- a/remoting/host/file_transfer/ipc_file_operations_unittest.cc
+++ b/remoting/host/file_transfer/ipc_file_operations_unittest.cc
@@ -72,7 +72,7 @@
   std::vector<base::CallbackListSubscription> disconnect_subscriptions_;
 
   // If set, this will be returned on the next file transfer operation request.
-  absl::optional<protocol::FileTransfer_Error> request_error_;
+  std::optional<protocol::FileTransfer_Error> request_error_;
 
   // Remote end of the DesktopSessionControl channel, the receiver is owned by
   // a FakeDesktopSessionAgent instance.
@@ -170,7 +170,7 @@
   bool disconnect_on_next_request_ = false;
 
   // If set, |response_error_| will be returned in the next IPC response.
-  absl::optional<protocol::FileTransfer_Error> response_error_;
+  std::optional<protocol::FileTransfer_Error> response_error_;
 
   // Handles file transfer requests over Mojo and manages receiver lifetimes.
   SessionFileOperationsHandler session_file_operations_handler_;
@@ -349,7 +349,7 @@
       file_operations_->CreateWriter();
   ASSERT_EQ(FileOperations::kCreated, writer->state());
 
-  absl::optional<FileOperations::Writer::Result> open_result;
+  std::optional<FileOperations::Writer::Result> open_result;
   writer->Open(kTestFilename, base::BindLambdaForTesting(
                                   [&](FileOperations::Writer::Result result) {
                                     open_result = std::move(result);
@@ -362,7 +362,7 @@
   ASSERT_EQ(session_file_writer_count(), size_t{1});
 
   for (const auto& chunk : {kTestDataOne, kTestDataTwo, kTestDataThree}) {
-    absl::optional<FileOperations::Writer::Result> write_result;
+    std::optional<FileOperations::Writer::Result> write_result;
     writer->WriteChunk(chunk, base::BindLambdaForTesting(
                                   [&](FileOperations::Writer::Result result) {
                                     write_result = std::move(result);
@@ -374,7 +374,7 @@
     ASSERT_TRUE(*write_result);
   }
 
-  absl::optional<FileOperations::Writer::Result> close_result;
+  std::optional<FileOperations::Writer::Result> close_result;
   writer->Close(
       base::BindLambdaForTesting([&](FileOperations::Writer::Result result) {
         close_result = std::move(result);
@@ -397,7 +397,7 @@
   std::unique_ptr<FileOperations::Writer> writer =
       file_operations_->CreateWriter();
 
-  absl::optional<FileOperations::Writer::Result> open_result;
+  std::optional<FileOperations::Writer::Result> open_result;
   writer->Open(kTestFilename, base::BindLambdaForTesting(
                                   [&](FileOperations::Writer::Result result) {
                                     open_result = std::move(result);
@@ -408,7 +408,7 @@
   ASSERT_EQ(session_file_writer_count(), size_t{1});
 
   for (const auto& chunk : {kTestDataOne, kTestDataTwo, kTestDataThree}) {
-    absl::optional<FileOperations::Writer::Result> write_result;
+    std::optional<FileOperations::Writer::Result> write_result;
     writer->WriteChunk(chunk, base::BindLambdaForTesting(
                                   [&](FileOperations::Writer::Result result) {
                                     write_result = std::move(result);
@@ -432,7 +432,7 @@
   std::unique_ptr<FileOperations::Writer> writer =
       file_operations_->CreateWriter();
 
-  absl::optional<FileOperations::Writer::Result> open_result;
+  std::optional<FileOperations::Writer::Result> open_result;
   writer->Open(kTestFilename, base::BindLambdaForTesting(
                                   [&](FileOperations::Writer::Result result) {
                                     open_result = std::move(result);
@@ -442,7 +442,7 @@
   ASSERT_TRUE(*open_result);
   ASSERT_EQ(session_file_writer_count(), size_t{1});
 
-  absl::optional<FileOperations::Writer::Result> write_result;
+  std::optional<FileOperations::Writer::Result> write_result;
   writer->WriteChunk(
       kTestDataOne,
       base::BindLambdaForTesting([&](FileOperations::Writer::Result result) {
@@ -472,7 +472,7 @@
   ASSERT_EQ(FileOperations::kCreated, reader->state());
 
   FakeFileChooser::SetResult(path);
-  absl::optional<FileOperations::Reader::OpenResult> open_result;
+  std::optional<FileOperations::Reader::OpenResult> open_result;
   reader->Open(base::BindLambdaForTesting(
       [&](FileOperations::Reader::OpenResult result) {
         open_result = std::move(result);
@@ -485,7 +485,7 @@
   ASSERT_EQ(session_file_reader_count(), size_t{1});
 
   for (const auto& chunk : {kTestDataOne, kTestDataTwo, kTestDataThree}) {
-    absl::optional<FileOperations::Reader::ReadResult> read_result;
+    std::optional<FileOperations::Reader::ReadResult> read_result;
     reader->ReadChunk(chunk.size(),
                       base::BindLambdaForTesting(
                           [&](FileOperations::Reader::ReadResult result) {
@@ -519,7 +519,7 @@
       file_operations_->CreateReader();
 
   FakeFileChooser::SetResult(path);
-  absl::optional<FileOperations::Reader::OpenResult> open_result;
+  std::optional<FileOperations::Reader::OpenResult> open_result;
   reader->Open(base::BindLambdaForTesting(
       [&](FileOperations::Reader::OpenResult result) {
         open_result = std::move(result);
@@ -529,7 +529,7 @@
   ASSERT_TRUE(*open_result);
   ASSERT_EQ(session_file_reader_count(), size_t{1});
 
-  absl::optional<FileOperations::Reader::ReadResult> read_result;
+  std::optional<FileOperations::Reader::ReadResult> read_result;
   reader->ReadChunk(
       contents.size() +
           kOverreadAmount,  // Attempt to read more than is in file.
@@ -570,7 +570,7 @@
       file_operations_->CreateReader();
 
   FakeFileChooser::SetResult(path);
-  absl::optional<FileOperations::Reader::OpenResult> open_result;
+  std::optional<FileOperations::Reader::OpenResult> open_result;
   reader->Open(base::BindLambdaForTesting(
       [&](FileOperations::Reader::OpenResult result) {
         open_result = std::move(result);
@@ -580,7 +580,7 @@
   ASSERT_TRUE(*open_result);
   ASSERT_EQ(session_file_reader_count(), size_t{1});
 
-  absl::optional<FileOperations::Reader::ReadResult> read_result;
+  std::optional<FileOperations::Reader::ReadResult> read_result;
   reader->ReadChunk(kChunkSize,
                     base::BindLambdaForTesting(
                         [&](FileOperations::Reader::ReadResult result) {
@@ -620,7 +620,7 @@
   int reader_count = static_cast<int>(readers.size());
   for (int i = 0; i < reader_count; i++) {
     FakeFileChooser::SetResult(paths[i]);
-    absl::optional<FileOperations::Reader::OpenResult> open_result;
+    std::optional<FileOperations::Reader::OpenResult> open_result;
     readers[i]->Open(base::BindLambdaForTesting(
         [&](FileOperations::Reader::OpenResult result) {
           open_result = std::move(result);
@@ -634,7 +634,7 @@
 
   for (int i = 0; i < reader_count; i++) {
     for (const auto& chunk : {kTestDataOne, kTestDataTwo, kTestDataThree}) {
-      absl::optional<FileOperations::Reader::ReadResult> read_result;
+      std::optional<FileOperations::Reader::ReadResult> read_result;
       readers[i]->ReadChunk(chunk.size(),
                             base::BindLambdaForTesting(
                                 [&](FileOperations::Reader::ReadResult result) {
@@ -651,7 +651,7 @@
   ASSERT_EQ(session_file_reader_count(), readers.size());
 
   for (int i = reader_count - 1; i >= 0; i--) {
-    absl::optional<FileOperations::Reader::ReadResult> read_result;
+    std::optional<FileOperations::Reader::ReadResult> read_result;
     // Simulate EOF by reading 1 additional byte.
     readers[i]->ReadChunk(1,
                           base::BindLambdaForTesting(
@@ -689,7 +689,7 @@
 
   int writer_count = static_cast<int>(writers.size());
   for (int i = 0; i < writer_count; i++) {
-    absl::optional<FileOperations::Writer::Result> open_result;
+    std::optional<FileOperations::Writer::Result> open_result;
     writers[i]->Open(paths[i], base::BindLambdaForTesting(
                                    [&](FileOperations::Writer::Result result) {
                                      open_result = std::move(result);
@@ -703,7 +703,7 @@
 
   for (const auto& chunk : {kTestDataOne, kTestDataTwo, kTestDataThree}) {
     for (int i = 0; i < writer_count; i++) {
-      absl::optional<FileOperations::Writer::Result> write_result;
+      std::optional<FileOperations::Writer::Result> write_result;
       writers[i]->WriteChunk(chunk,
                              base::BindLambdaForTesting(
                                  [&](FileOperations::Writer::Result result) {
@@ -720,7 +720,7 @@
   ASSERT_EQ(session_file_writer_count(), writers.size());
 
   for (int i = writer_count - 1; i >= 0; i--) {
-    absl::optional<FileOperations::Writer::Result> close_result;
+    std::optional<FileOperations::Writer::Result> close_result;
     writers[i]->Close(
         base::BindLambdaForTesting([&](FileOperations::Writer::Result result) {
           close_result = std::move(result);
@@ -757,14 +757,14 @@
   ASSERT_TRUE(base::WriteFile(read_path, contents));
 
   // Pending open file operations.
-  absl::optional<FileOperations::Writer::Result> open_for_write_result;
+  std::optional<FileOperations::Writer::Result> open_for_write_result;
   writer->Open(
       base_path.InsertBeforeExtension(FILE_PATH_LITERAL("(write)")),
       base::BindLambdaForTesting([&](FileOperations::Writer::Result result) {
         open_for_write_result = std::move(result);
       }));
   FakeFileChooser::SetResult(read_path);
-  absl::optional<FileOperations::Reader::OpenResult> open_for_read_result;
+  std::optional<FileOperations::Reader::OpenResult> open_for_read_result;
   reader->Open(base::BindLambdaForTesting(
       [&](FileOperations::Reader::OpenResult result) {
         open_for_read_result = std::move(result);
@@ -784,13 +784,13 @@
   ASSERT_EQ(session_file_reader_count(), size_t{1});
 
   // Pending write operation.
-  absl::optional<FileOperations::Writer::Result> write_result;
+  std::optional<FileOperations::Writer::Result> write_result;
   writer->WriteChunk(contents, base::BindLambdaForTesting(
                                    [&](FileOperations::Writer::Result result) {
                                      write_result = std::move(result);
                                    }));
   // Pending read operation.
-  absl::optional<FileOperations::Reader::ReadResult> read_result;
+  std::optional<FileOperations::Reader::ReadResult> read_result;
   reader->ReadChunk(contents.size(),
                     base::BindLambdaForTesting(
                         [&](FileOperations::Reader::ReadResult result) {
@@ -811,7 +811,7 @@
   ASSERT_EQ(session_file_reader_count(), size_t{1});
 
   // Close the writer.
-  absl::optional<FileOperations::Writer::Result> close_result;
+  std::optional<FileOperations::Writer::Result> close_result;
   writer->Close(
       base::BindLambdaForTesting([&](FileOperations::Writer::Result result) {
         close_result = std::move(result);
@@ -851,7 +851,7 @@
 
   // Currently non-existent file.
   FakeFileChooser::SetResult(TestDir().Append(kTestFilename));
-  absl::optional<FileOperations::Reader::OpenResult> open_result;
+  std::optional<FileOperations::Reader::OpenResult> open_result;
   reader->Open(base::BindLambdaForTesting(
       [&](FileOperations::Reader::OpenResult result) {
         open_result = std::move(result);
@@ -871,7 +871,7 @@
   fake_desktop_session_proxy_.SetErrorForNextRequest(
       protocol::MakeFileTransferError(
           FROM_HERE, protocol::FileTransfer_Error_Type_UNEXPECTED_ERROR));
-  absl::optional<FileOperations::Reader::OpenResult> open_result;
+  std::optional<FileOperations::Reader::OpenResult> open_result;
   reader->Open(base::BindLambdaForTesting(
       [&](FileOperations::Reader::OpenResult result) {
         open_result = std::move(result);
@@ -889,7 +889,7 @@
   fake_desktop_session_proxy_.SetErrorForNextRequest(
       protocol::MakeFileTransferError(
           FROM_HERE, protocol::FileTransfer_Error_Type_UNEXPECTED_ERROR));
-  absl::optional<FileOperations::Writer::Result> open_result;
+  std::optional<FileOperations::Writer::Result> open_result;
   writer->Open(
       TestDir().Append(kTestFilename),
       base::BindLambdaForTesting([&](FileOperations::Writer::Result result) {
@@ -909,7 +909,7 @@
   fake_desktop_session_agent_.SetErrorForNextResponse(
       protocol::MakeFileTransferError(
           FROM_HERE, protocol::FileTransfer_Error_Type_UNEXPECTED_ERROR));
-  absl::optional<FileOperations::Reader::OpenResult> open_result;
+  std::optional<FileOperations::Reader::OpenResult> open_result;
   reader->Open(base::BindLambdaForTesting(
       [&](FileOperations::Reader::OpenResult result) {
         open_result = std::move(result);
@@ -928,7 +928,7 @@
   fake_desktop_session_agent_.SetErrorForNextResponse(
       protocol::MakeFileTransferError(
           FROM_HERE, protocol::FileTransfer_Error_Type_UNEXPECTED_ERROR));
-  absl::optional<FileOperations::Writer::Result> open_result;
+  std::optional<FileOperations::Writer::Result> open_result;
   writer->Open(
       TestDir().Append(kTestFilename),
       base::BindLambdaForTesting([&](FileOperations::Writer::Result result) {
@@ -947,7 +947,7 @@
       file_operations_->CreateReader();
   // This will trigger the DesktopSessionControl remote disconnect handler.
   fake_desktop_session_agent_.DisconnectReceiverOnNextRequest();
-  absl::optional<FileOperations::Reader::OpenResult> open_result;
+  std::optional<FileOperations::Reader::OpenResult> open_result;
   reader->Open(base::BindLambdaForTesting(
       [&](FileOperations::Reader::OpenResult result) {
         open_result = std::move(result);
@@ -965,7 +965,7 @@
       file_operations_->CreateWriter();
   // This will trigger the DesktopSessionControl remote disconnect handler.
   fake_desktop_session_agent_.DisconnectReceiverOnNextRequest();
-  absl::optional<FileOperations::Writer::Result> open_result;
+  std::optional<FileOperations::Writer::Result> open_result;
   writer->Open(
       TestDir().Append(kTestFilename),
       base::BindLambdaForTesting([&](FileOperations::Writer::Result result) {
@@ -984,7 +984,7 @@
   constexpr std::size_t kChunkSize = 5;
   std::unique_ptr<FileOperations::Reader> reader =
       file_operations_->CreateReader();
-  absl::optional<FileOperations::Reader::ReadResult> read_result;
+  std::optional<FileOperations::Reader::ReadResult> read_result;
   reader->ReadChunk(kChunkSize,
                     base::BindLambdaForTesting(
                         [&](FileOperations::Reader::ReadResult result) {
@@ -1002,7 +1002,7 @@
 TEST_F(IpcFileOperationsTest, ErrorWhenWriteChunkCalledBeforeOpen) {
   std::unique_ptr<FileOperations::Writer> writer =
       file_operations_->CreateWriter();
-  absl::optional<FileOperations::Writer::Result> write_result;
+  std::optional<FileOperations::Writer::Result> write_result;
   writer->WriteChunk(
       std::vector<uint8_t>{16, 16, 16, 16, 16},
       base::BindLambdaForTesting([&](FileOperations::Writer::Result result) {
@@ -1020,7 +1020,7 @@
 TEST_F(IpcFileOperationsTest, ErrorWhenCloseCalledBeforeOpen) {
   std::unique_ptr<FileOperations::Writer> writer =
       file_operations_->CreateWriter();
-  absl::optional<FileOperations::Writer::Result> close_result;
+  std::optional<FileOperations::Writer::Result> close_result;
   writer->Close(
       base::BindLambdaForTesting([&](FileOperations::Writer::Result result) {
         close_result = std::move(result);
@@ -1043,7 +1043,7 @@
       file_operations_->CreateReader();
 
   FakeFileChooser::SetResult(path);
-  absl::optional<FileOperations::Reader::OpenResult> open_result;
+  std::optional<FileOperations::Reader::OpenResult> open_result;
   reader->Open(base::BindLambdaForTesting(
       [&](FileOperations::Reader::OpenResult result) {
         open_result = std::move(result);
@@ -1058,7 +1058,7 @@
   ASSERT_EQ(session_file_reader_count(), size_t{0});
   task_environment_.RunUntilIdle();
 
-  absl::optional<FileOperations::Reader::ReadResult> read_result;
+  std::optional<FileOperations::Reader::ReadResult> read_result;
   reader->ReadChunk(kChunkSize,
                     base::BindLambdaForTesting(
                         [&](FileOperations::Reader::ReadResult result) {
@@ -1076,7 +1076,7 @@
   std::unique_ptr<FileOperations::Writer> writer =
       file_operations_->CreateWriter();
 
-  absl::optional<FileOperations::Writer::Result> open_result;
+  std::optional<FileOperations::Writer::Result> open_result;
   writer->Open(kTestFilename, base::BindLambdaForTesting(
                                   [&](FileOperations::Writer::Result result) {
                                     open_result = std::move(result);
@@ -1090,7 +1090,7 @@
   ASSERT_EQ(session_file_writer_count(), size_t{0});
   task_environment_.RunUntilIdle();
 
-  absl::optional<FileOperations::Writer::Result> write_result;
+  std::optional<FileOperations::Writer::Result> write_result;
   writer->WriteChunk(
       std::vector<uint8_t>{16, 16, 16, 16, 16},
       base::BindLambdaForTesting([&](FileOperations::Writer::Result result) {
@@ -1108,7 +1108,7 @@
   std::unique_ptr<FileOperations::Writer> writer =
       file_operations_->CreateWriter();
 
-  absl::optional<FileOperations::Writer::Result> open_result;
+  std::optional<FileOperations::Writer::Result> open_result;
   writer->Open(kTestFilename, base::BindLambdaForTesting(
                                   [&](FileOperations::Writer::Result result) {
                                     open_result = std::move(result);
@@ -1122,7 +1122,7 @@
   ASSERT_EQ(session_file_writer_count(), size_t{0});
   task_environment_.RunUntilIdle();
 
-  absl::optional<FileOperations::Writer::Result> close_result;
+  std::optional<FileOperations::Writer::Result> close_result;
   writer->Close(
       base::BindLambdaForTesting([&](FileOperations::Writer::Result result) {
         close_result = std::move(result);
@@ -1149,7 +1149,7 @@
 
   ipc_file_operations_factory.reset();
 
-  absl::optional<FileOperations::Writer::Result> writer_open_result;
+  std::optional<FileOperations::Writer::Result> writer_open_result;
   writer->Open(kTestFilename, base::BindLambdaForTesting(
                                   [&](FileOperations::Writer::Result result) {
                                     writer_open_result = std::move(result);
@@ -1158,7 +1158,7 @@
   ASSERT_EQ(writer->state(), FileOperations::kFailed);
   ASSERT_TRUE(writer_open_result->is_error());
 
-  absl::optional<FileOperations::Reader::OpenResult> reader_open_result;
+  std::optional<FileOperations::Reader::OpenResult> reader_open_result;
   reader->Open(base::BindLambdaForTesting(
       [&](FileOperations::Reader::OpenResult result) {
         reader_open_result = std::move(result);
@@ -1182,7 +1182,7 @@
   std::unique_ptr<FileOperations::Reader> reader =
       file_operations->CreateReader();
 
-  absl::optional<FileOperations::Writer::Result> writer_open_result;
+  std::optional<FileOperations::Writer::Result> writer_open_result;
   writer->Open(kTestFilename, base::BindLambdaForTesting(
                                   [&](FileOperations::Writer::Result result) {
                                     writer_open_result = std::move(result);
@@ -1191,7 +1191,7 @@
   ASSERT_EQ(writer->state(), FileOperations::kFailed);
   ASSERT_TRUE(writer_open_result->is_error());
 
-  absl::optional<FileOperations::Reader::OpenResult> reader_open_result;
+  std::optional<FileOperations::Reader::OpenResult> reader_open_result;
   reader->Open(base::BindLambdaForTesting(
       [&](FileOperations::Reader::OpenResult result) {
         reader_open_result = std::move(result);
diff --git a/remoting/host/file_transfer/local_file_operations.cc b/remoting/host/file_transfer/local_file_operations.cc
index 5618379..2760e51 100644
--- a/remoting/host/file_transfer/local_file_operations.cc
+++ b/remoting/host/file_transfer/local_file_operations.cc
@@ -6,6 +6,7 @@
 
 #include <cstdint>
 
+#include <optional>
 #include "base/files/file_path.h"
 #include "base/files/file_proxy.h"
 #include "base/files/file_util.h"
@@ -22,7 +23,6 @@
 #include "remoting/host/file_transfer/ensure_user.h"
 #include "remoting/host/file_transfer/file_chooser.h"
 #include "remoting/protocol/file_transfer_helpers.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -97,7 +97,7 @@
   scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
   scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
   std::unique_ptr<FileChooser> file_chooser_;
-  absl::optional<base::FileProxy> file_proxy_;
+  std::optional<base::FileProxy> file_proxy_;
   SEQUENCE_CHECKER(sequence_checker_);
   base::WeakPtrFactory<LocalFileReader> weak_ptr_factory_{this};
 };
@@ -148,7 +148,7 @@
   std::uint64_t bytes_written_ = 0;
 
   scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
-  absl::optional<base::FileProxy> file_proxy_;
+  std::optional<base::FileProxy> file_proxy_;
   SEQUENCE_CHECKER(sequence_checker_);
   base::WeakPtrFactory<LocalFileWriter> weak_ptr_factory_{this};
 };
diff --git a/remoting/host/file_transfer/local_file_operations_unittest.cc b/remoting/host/file_transfer/local_file_operations_unittest.cc
index 7a915a7..ed5524f 100644
--- a/remoting/host/file_transfer/local_file_operations_unittest.cc
+++ b/remoting/host/file_transfer/local_file_operations_unittest.cc
@@ -245,7 +245,7 @@
       file_operations_->CreateReader();
 
   FakeFileChooser::SetResult(path);
-  absl::optional<FileOperations::Reader::OpenResult> open_result;
+  std::optional<FileOperations::Reader::OpenResult> open_result;
   ASSERT_EQ(FileOperations::kCreated, reader->state());
   reader->Open(BindLambda([&](FileOperations::Reader::OpenResult result) {
     open_result = std::move(result);
@@ -270,7 +270,7 @@
       file_operations_->CreateReader();
 
   FakeFileChooser::SetResult(path);
-  absl::optional<FileOperations::Reader::OpenResult> open_result;
+  std::optional<FileOperations::Reader::OpenResult> open_result;
   reader->Open(BindLambda([&](FileOperations::Reader::OpenResult result) {
     open_result = std::move(result);
   }));
@@ -278,7 +278,7 @@
   ASSERT_TRUE(open_result && *open_result);
 
   for (const auto& chunk : {kTestDataOne, kTestDataTwo, kTestDataThree}) {
-    absl::optional<FileOperations::Reader::ReadResult> read_result;
+    std::optional<FileOperations::Reader::ReadResult> read_result;
     reader->ReadChunk(
         chunk.size(),
         BindLambda([&](FileOperations::Reader::ReadResult result) {
@@ -304,14 +304,14 @@
       file_operations_->CreateReader();
 
   FakeFileChooser::SetResult(path);
-  absl::optional<FileOperations::Reader::OpenResult> open_result;
+  std::optional<FileOperations::Reader::OpenResult> open_result;
   reader->Open(BindLambda([&](FileOperations::Reader::OpenResult result) {
     open_result = std::move(result);
   }));
   task_environment_.RunUntilIdle();
   ASSERT_TRUE(open_result && *open_result);
 
-  absl::optional<FileOperations::Reader::ReadResult> read_result;
+  std::optional<FileOperations::Reader::ReadResult> read_result;
   reader->ReadChunk(
       contents.size() + 5,  // Attempt to read more than is in file.
       BindLambda([&](FileOperations::Reader::ReadResult result) {
@@ -340,7 +340,7 @@
 
   FakeFileChooser::SetResult(protocol::MakeFileTransferError(
       FROM_HERE, protocol::FileTransfer_Error_Type_CANCELED));
-  absl::optional<FileOperations::Reader::OpenResult> open_result;
+  std::optional<FileOperations::Reader::OpenResult> open_result;
   reader->Open(BindLambda([&](FileOperations::Reader::OpenResult result) {
     open_result = std::move(result);
   }));
@@ -359,7 +359,7 @@
 
   // Currently non-existent file.
   FakeFileChooser::SetResult(TestDir().Append(kTestFilename));
-  absl::optional<FileOperations::Reader::OpenResult> open_result;
+  std::optional<FileOperations::Reader::OpenResult> open_result;
   reader->Open(BindLambda([&](FileOperations::Reader::OpenResult result) {
     open_result = std::move(result);
   }));
diff --git a/remoting/host/file_transfer/rtc_log_file_operations_unittest.cc b/remoting/host/file_transfer/rtc_log_file_operations_unittest.cc
index ade7bd7..2e05dac 100644
--- a/remoting/host/file_transfer/rtc_log_file_operations_unittest.cc
+++ b/remoting/host/file_transfer/rtc_log_file_operations_unittest.cc
@@ -52,8 +52,8 @@
   std::unique_ptr<FileOperations::Reader> reader_;
 
   // These are the most-recent results from the callbacks.
-  absl::optional<FileOperations::Reader::OpenResult> open_result_;
-  absl::optional<FileOperations::Reader::ReadResult> read_result_;
+  std::optional<FileOperations::Reader::OpenResult> open_result_;
+  std::optional<FileOperations::Reader::ReadResult> read_result_;
 
   FileOperations::Reader::OpenCallback MakeOpenCallback() {
     return base::BindOnce(&RtcLogFileOperationsTest::OnOpenResult,
diff --git a/remoting/host/file_transfer/session_file_operations_handler.cc b/remoting/host/file_transfer/session_file_operations_handler.cc
index 1bc7b8a..44948d6 100644
--- a/remoting/host/file_transfer/session_file_operations_handler.cc
+++ b/remoting/host/file_transfer/session_file_operations_handler.cc
@@ -6,12 +6,12 @@
 
 #include <memory>
 
+#include <optional>
 #include "base/files/file_path.h"
 #include "base/functional/bind.h"
 #include "base/memory/weak_ptr.h"
 #include "remoting/host/mojom/desktop_session.mojom.h"
 #include "remoting/protocol/file_transfer_helpers.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -158,7 +158,7 @@
 // methods which expect a Writer::Callback.
 template <class T>
 void FileWriterCallbackWrapper(T callback, remoting::Writer::Result result) {
-  absl::optional<protocol::FileTransfer_Error> error;
+  std::optional<protocol::FileTransfer_Error> error;
   if (result.is_error()) {
     error = std::move(result.error());
   }
diff --git a/remoting/host/host_config.cc b/remoting/host/host_config.cc
index b99c9c0..26dfb75b 100644
--- a/remoting/host/host_config.cc
+++ b/remoting/host/host_config.cc
@@ -28,17 +28,17 @@
 const char kDeprecatedHostOwnerEmailConfigPath[] = "host_owner_email";
 const char kDeprecatedXmppLoginConfigPath[] = "xmpp_login";
 
-absl::optional<base::Value::Dict> HostConfigFromJson(const std::string& json) {
-  absl::optional<base::Value> value =
+std::optional<base::Value::Dict> HostConfigFromJson(const std::string& json) {
+  std::optional<base::Value> value =
       base::JSONReader::Read(json, base::JSON_ALLOW_TRAILING_COMMAS);
   if (!value.has_value()) {
     LOG(ERROR) << "Failed to parse host config from JSON";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (!value->is_dict()) {
     LOG(ERROR) << "Parsed host config returned was not a dictionary";
-    return absl::nullopt;
+    return std::nullopt;
   }
   auto config = std::move(value->GetDict());
 
@@ -76,12 +76,12 @@
   return data;
 }
 
-absl::optional<base::Value::Dict> HostConfigFromJsonFile(
+std::optional<base::Value::Dict> HostConfigFromJsonFile(
     const base::FilePath& config_file) {
   std::string serialized;
   if (!base::ReadFileToString(config_file, &serialized)) {
     LOG(ERROR) << "Failed to read " << config_file.value();
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return HostConfigFromJson(serialized);
diff --git a/remoting/host/host_config.h b/remoting/host/host_config.h
index 5c490e3..45339699 100644
--- a/remoting/host/host_config.h
+++ b/remoting/host/host_config.h
@@ -8,8 +8,8 @@
 #include <memory>
 #include <string>
 
+#include <optional>
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class FilePath;
@@ -59,12 +59,12 @@
 extern const char kDeprecatedXmppLoginConfigPath[];
 
 // Helpers for serializing/deserializing Host configuration dictionaries.
-absl::optional<base::Value::Dict> HostConfigFromJson(
+std::optional<base::Value::Dict> HostConfigFromJson(
     const std::string& serialized);
 std::string HostConfigToJson(const base::Value::Dict& host_config);
 
 // Helpers for loading/saving host configurations from/to files.
-absl::optional<base::Value::Dict> HostConfigFromJsonFile(
+std::optional<base::Value::Dict> HostConfigFromJsonFile(
     const base::FilePath& config_file);
 bool HostConfigToJsonFile(const base::Value::Dict& host_config,
                           const base::FilePath& config_file);
diff --git a/remoting/host/host_config_unittest.cc b/remoting/host/host_config_unittest.cc
index 3a4ebe0b..0e0631e5 100644
--- a/remoting/host/host_config_unittest.cc
+++ b/remoting/host/host_config_unittest.cc
@@ -4,13 +4,13 @@
 
 #include "remoting/host/host_config.h"
 
+#include <optional>
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/json/json_writer.h"
 #include "base/memory/ref_counted.h"
 #include "base/values.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
diff --git a/remoting/host/input_injector_win.cc b/remoting/host/input_injector_win.cc
index 4b4cfce8..52bcb8b 100644
--- a/remoting/host/input_injector_win.cc
+++ b/remoting/host/input_injector_win.cc
@@ -12,6 +12,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/compiler_specific.h"
 #include "base/functional/bind.h"
 #include "base/location.h"
@@ -24,7 +25,6 @@
 #include "remoting/host/clipboard.h"
 #include "remoting/host/touch_injector_win.h"
 #include "remoting/proto/event.pb.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/events/keycodes/dom/keycode_converter.h"
 
 namespace remoting {
@@ -168,8 +168,8 @@
 }
 
 // Sets the keyboard lock states to those provided.
-void SetLockStates(absl::optional<bool> caps_lock,
-                   absl::optional<bool> num_lock) {
+void SetLockStates(std::optional<bool> caps_lock,
+                   std::optional<bool> num_lock) {
   if (caps_lock) {
     bool client_capslock_state = *caps_lock;
     bool host_capslock_state = (GetKeyState(VK_CAPITAL) & 1) != 0;
@@ -393,8 +393,8 @@
   }
 
   if (event.pressed() && !IsLockKey(scancode)) {
-    absl::optional<bool> caps_lock;
-    absl::optional<bool> num_lock;
+    std::optional<bool> caps_lock;
+    std::optional<bool> num_lock;
 
     // For caps lock, check both the new caps_lock field and the old lock_states
     // field.
diff --git a/remoting/host/input_injector_x11.cc b/remoting/host/input_injector_x11.cc
index c7de2a8..994a19d 100644
--- a/remoting/host/input_injector_x11.cc
+++ b/remoting/host/input_injector_x11.cc
@@ -8,6 +8,7 @@
 #include <set>
 #include <utility>
 
+#include <optional>
 #include "base/compiler_specific.h"
 #include "base/functional/bind.h"
 #include "base/location.h"
@@ -25,7 +26,6 @@
 #include "remoting/host/linux/x11_keyboard_impl.h"
 #include "remoting/host/linux/x11_util.h"
 #include "remoting/proto/internal.pb.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
 #include "ui/events/keycodes/dom/dom_code.h"
 #include "ui/events/keycodes/dom/keycode_converter.h"
@@ -172,8 +172,8 @@
     }
 
     if (!IsLockKey(static_cast<x11::KeyCode>(keycode))) {
-      absl::optional<bool> caps_lock;
-      absl::optional<bool> num_lock;
+      std::optional<bool> caps_lock;
+      std::optional<bool> num_lock;
 
       // For caps lock, check both the new caps_lock field and the old
       // lock_states field.
@@ -280,8 +280,8 @@
   }
 }
 
-void InputInjectorX11::Core::SetLockStates(absl::optional<bool> caps_lock,
-                                           absl::optional<bool> num_lock) {
+void InputInjectorX11::Core::SetLockStates(std::optional<bool> caps_lock,
+                                           std::optional<bool> num_lock) {
   // The lock bits associated with each lock key.
   auto caps_lock_mask = static_cast<unsigned int>(x11::ModMask::Lock);
   auto num_lock_mask = static_cast<unsigned int>(x11::ModMask::c_2);
diff --git a/remoting/host/input_injector_x11.h b/remoting/host/input_injector_x11.h
index 4d90e3b..58b05d4 100644
--- a/remoting/host/input_injector_x11.h
+++ b/remoting/host/input_injector_x11.h
@@ -11,6 +11,7 @@
 #include <set>
 #include <utility>
 
+#include <optional>
 #include "base/compiler_specific.h"
 #include "base/functional/bind.h"
 #include "base/location.h"
@@ -26,7 +27,6 @@
 #include "remoting/host/linux/x11_keyboard_impl.h"
 #include "remoting/host/linux/x11_util.h"
 #include "remoting/proto/internal.pb.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
 #include "ui/gfx/x/xproto.h"
 
@@ -99,8 +99,8 @@
     bool IsLockKey(x11::KeyCode keycode);
 
     // Sets the keyboard lock states to those provided.
-    void SetLockStates(absl::optional<bool> caps_lock,
-                       absl::optional<bool> num_lock);
+    void SetLockStates(std::optional<bool> caps_lock,
+                       std::optional<bool> num_lock);
 
     void InjectScrollWheelClicks(int button, int count);
 
diff --git a/remoting/host/ipc_desktop_environment_unittest.cc b/remoting/host/ipc_desktop_environment_unittest.cc
index 0617ba5..4b8b273 100644
--- a/remoting/host/ipc_desktop_environment_unittest.cc
+++ b/remoting/host/ipc_desktop_environment_unittest.cc
@@ -798,7 +798,7 @@
   screen_controls_->SetScreenResolution(
       ScreenResolution(webrtc::DesktopSize(100, 100),
                        webrtc::DesktopVector(96, 96)),
-      absl::nullopt);
+      std::nullopt);
 }
 
 TEST_F(IpcDesktopEnvironmentTest, CheckUrlForwarderState) {
diff --git a/remoting/host/ipc_screen_controls.cc b/remoting/host/ipc_screen_controls.cc
index 6a43236f..669e8f37 100644
--- a/remoting/host/ipc_screen_controls.cc
+++ b/remoting/host/ipc_screen_controls.cc
@@ -17,7 +17,7 @@
 
 void IpcScreenControls::SetScreenResolution(
     const ScreenResolution& resolution,
-    absl::optional<webrtc::ScreenId> screen_id) {
+    std::optional<webrtc::ScreenId> screen_id) {
   // TODO(crbug.com/1326339): Pass |screen_id| over IPC.
   desktop_session_proxy_->SetScreenResolution(resolution);
 }
diff --git a/remoting/host/ipc_screen_controls.h b/remoting/host/ipc_screen_controls.h
index 7ccaaeb..8ae1138 100644
--- a/remoting/host/ipc_screen_controls.h
+++ b/remoting/host/ipc_screen_controls.h
@@ -25,7 +25,7 @@
 
   // ScreenControls interface.
   void SetScreenResolution(const ScreenResolution& resolution,
-                           absl::optional<webrtc::ScreenId> screen_id) override;
+                           std::optional<webrtc::ScreenId> screen_id) override;
   void SetVideoLayout(const protocol::VideoLayout& video_layout) override;
 
  private:
diff --git a/remoting/host/it2me/it2me_confirmation_dialog_chromeos.cc b/remoting/host/it2me/it2me_confirmation_dialog_chromeos.cc
index 827f0bd8..dbe5fe7 100644
--- a/remoting/host/it2me/it2me_confirmation_dialog_chromeos.cc
+++ b/remoting/host/it2me/it2me_confirmation_dialog_chromeos.cc
@@ -63,7 +63,7 @@
  private:
   void ShowConfirmationNotification(const std::string& remote_user_email);
 
-  void OnConfirmationNotificationResult(absl::optional<int> button_index);
+  void OnConfirmationNotificationResult(std::optional<int> button_index);
 
   const gfx::VectorIcon& GetIcon() const {
     switch (style_) {
@@ -136,7 +136,7 @@
 }
 
 void It2MeConfirmationDialogChromeOS::OnConfirmationNotificationResult(
-    absl::optional<int> button_index) {
+    std::optional<int> button_index) {
   if (!button_index.has_value()) {
     return;  // This happens when the user clicks the notification itself.
   }
diff --git a/remoting/host/it2me/it2me_confirmation_dialog_chromeos_unittest.cc b/remoting/host/it2me/it2me_confirmation_dialog_chromeos_unittest.cc
index cc591e3..cf95286 100644
--- a/remoting/host/it2me/it2me_confirmation_dialog_chromeos_unittest.cc
+++ b/remoting/host/it2me/it2me_confirmation_dialog_chromeos_unittest.cc
@@ -8,6 +8,7 @@
 #include <memory>
 #include <string>
 
+#include <optional>
 #include "base/i18n/message_formatter.h"
 #include "base/ranges/algorithm.h"
 #include "base/strings/utf_string_conversions.h"
@@ -16,7 +17,6 @@
 #include "remoting/base/string_resources.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/message_center/lock_screen/fake_lock_screen_controller.h"
 #include "ui/message_center/message_center.h"
@@ -90,7 +90,7 @@
     ASSERT_NE(notification, nullptr);
     const int button_index = FindButtonIndex(*notification, button_title);
     ASSERT_GE(button_index, 0);
-    notification->delegate()->Click(button_index, absl::nullopt);
+    notification->delegate()->Click(button_index, std::nullopt);
   }
 
   std::u16string FormatMessage(const std::string& remote_user_email,
diff --git a/remoting/host/it2me/it2me_confirmation_dialog_win.cc b/remoting/host/it2me/it2me_confirmation_dialog_win.cc
index f4016ff..1e4748c 100644
--- a/remoting/host/it2me/it2me_confirmation_dialog_win.cc
+++ b/remoting/host/it2me/it2me_confirmation_dialog_win.cc
@@ -98,7 +98,7 @@
   task_dialog.set_message_text(message_text);
   task_dialog.set_default_button(IDNO);
   task_dialog.set_dialog_timeout(kDialogTimeout);
-  absl::optional<int> button_result = task_dialog.Show();
+  std::optional<int> button_result = task_dialog.Show();
 
   if (!button_result.has_value()) {
     std::move(callback).Run(result);
diff --git a/remoting/host/it2me/it2me_host.cc b/remoting/host/it2me/it2me_host.cc
index 7c37e0a..413e968 100644
--- a/remoting/host/it2me/it2me_host.cc
+++ b/remoting/host/it2me/it2me_host.cc
@@ -467,13 +467,13 @@
            << enterprise_file_transfer_allowed_;
 #endif
 
-  absl::optional<bool> nat_policy_value =
+  std::optional<bool> nat_policy_value =
       policies.FindBool(policy::key::kRemoteAccessHostFirewallTraversal);
   if (!nat_policy_value.has_value()) {
     HOST_LOG << "Failed to read kRemoteAccessHostFirewallTraversal policy";
     nat_policy_value = nat_traversal_enabled_;
   }
-  absl::optional<bool> relay_policy_value =
+  std::optional<bool> relay_policy_value =
       policies.FindBool(policy::key::kRemoteAccessHostAllowRelayedConnection);
   if (!relay_policy_value.has_value()) {
     HOST_LOG << "Failed to read kRemoteAccessHostAllowRelayedConnection policy";
@@ -507,7 +507,7 @@
     UpdateHostUdpPortRangePolicy(*port_range_string);
   }
 
-  absl::optional<int> max_clipboard_size =
+  std::optional<int> max_clipboard_size =
       policies.FindInt(policy::key::kRemoteAccessHostClipboardSizeBytes);
   if (max_clipboard_size.has_value()) {
     if (max_clipboard_size.value() >= 0) {
diff --git a/remoting/host/it2me/it2me_host.h b/remoting/host/it2me/it2me_host.h
index 60115b5..7210f6a 100644
--- a/remoting/host/it2me/it2me_host.h
+++ b/remoting/host/it2me/it2me_host.h
@@ -9,6 +9,7 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/functional/callback_forward.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
@@ -25,7 +26,6 @@
 #include "remoting/protocol/port_range.h"
 #include "remoting/protocol/validating_authenticator.h"
 #include "remoting/signaling/signal_strategy.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -251,7 +251,7 @@
 
   // Set when the session was initiated for a managed Chrome OS device by an
   // admin using the admin console.
-  absl::optional<ChromeOsEnterpriseParams> chrome_os_enterprise_params_;
+  std::optional<ChromeOsEnterpriseParams> chrome_os_enterprise_params_;
 
   // Only the username stored in |authorized_helper_| will be allowed to connect
   // to this host instance, if set. Note: setting this value does not override
@@ -266,7 +266,7 @@
   PortRange udp_port_range_;
 
   // Stores the clipboard size policy value.
-  absl::optional<size_t> max_clipboard_size_;
+  std::optional<size_t> max_clipboard_size_;
 
   // Stores the remote support connections allowed policy value.
   bool remote_support_connections_allowed_ = true;
diff --git a/remoting/host/it2me/it2me_host_unittest.cc b/remoting/host/it2me/it2me_host_unittest.cc
index e0ea8c01f..05b904f 100644
--- a/remoting/host/it2me/it2me_host_unittest.cc
+++ b/remoting/host/it2me/it2me_host_unittest.cc
@@ -8,6 +8,7 @@
 #include <string>
 #include <utility>
 
+#include <optional>
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
 #include "base/location.h"
@@ -37,7 +38,6 @@
 #include "remoting/signaling/xmpp_log_to_server.h"
 #include "services/network/test/test_shared_url_loader_factory.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
 #include "base/linux_util.h"
@@ -228,7 +228,7 @@
   void RunValidationCallback(const std::string& remote_jid);
 
   void StartHost();
-  void StartHost(absl::optional<ChromeOsEnterpriseParams> enterprise_params);
+  void StartHost(std::optional<ChromeOsEnterpriseParams> enterprise_params);
   void ShutdownHost();
 
   static base::Value MakeList(std::initializer_list<base::StringPiece> values);
@@ -236,8 +236,8 @@
   ChromotingHost* GetHost() { return it2me_host_->host_.get(); }
 
   // Configuration values used by StartHost();
-  absl::optional<ChromeOsEnterpriseParams> enterprise_params_;
-  absl::optional<std::string> authorized_helper_;
+  std::optional<ChromeOsEnterpriseParams> enterprise_params_;
+  std::optional<std::string> authorized_helper_;
 
   // Stores the last nat traversal policy value received.
   bool last_nat_traversal_enabled_value_ = false;
@@ -256,7 +256,7 @@
   raw_ptr<FakeIt2MeDialogFactory, AcrossTasksDanglingUntriaged>
       dialog_factory_ = nullptr;
 
-  absl::optional<base::Value::Dict> policies_;
+  std::optional<base::Value::Dict> policies_;
 
   scoped_refptr<It2MeHost> it2me_host_;
 
@@ -417,7 +417,7 @@
 }
 
 void It2MeHostTest::StartHost(
-    absl::optional<ChromeOsEnterpriseParams> enterprise_params) {
+    std::optional<ChromeOsEnterpriseParams> enterprise_params) {
   enterprise_params_ = enterprise_params;
   StartHost();
 }
@@ -894,7 +894,7 @@
 }
 
 TEST_F(It2MeHostTest, TerminateUponInputDefaultsToFalse) {
-  StartHost(/*enterprise_params=*/absl::nullopt);
+  StartHost(/*enterprise_params=*/std::nullopt);
 
   EXPECT_FALSE(GetHost()->desktop_environment_options().terminate_upon_input());
 }
@@ -906,7 +906,7 @@
 }
 
 TEST_F(It2MeHostTest, EnableCurtainingDefaultsToFalse) {
-  StartHost(/*enterprise_params=*/absl::nullopt);
+  StartHost(/*enterprise_params=*/std::nullopt);
 
   EXPECT_FALSE(GetHost()->desktop_environment_options().enable_curtaining());
 }
@@ -934,7 +934,7 @@
   SetPolicies({{policy::key::kRemoteAccessHostAllowEnterpriseFileTransfer,
                 base::Value(true)}});
 
-  StartHost(/*enterprise_params=*/absl::nullopt);
+  StartHost(/*enterprise_params=*/std::nullopt);
 
   EXPECT_FALSE(GetHost()->desktop_environment_options().enable_file_transfer());
 }
@@ -959,7 +959,7 @@
 }
 
 TEST_F(It2MeHostTest, EnableFileTransferDefaultsToFalse) {
-  StartHost(/*enterprise_params=*/absl::nullopt);
+  StartHost(/*enterprise_params=*/std::nullopt);
 
   EXPECT_FALSE(GetHost()->desktop_environment_options().enable_file_transfer());
 }
@@ -1008,7 +1008,7 @@
       {{policy::key::kRemoteAccessHostAllowEnterpriseRemoteSupportConnections,
         base::Value(false)}});
 
-  StartHost(/*enterprise_params=*/absl::nullopt);
+  StartHost(/*enterprise_params=*/std::nullopt);
   ASSERT_EQ(It2MeHostState::kReceivedAccessCode, last_host_state_);
 }
 #endif
diff --git a/remoting/host/it2me/it2me_native_messaging_host.cc b/remoting/host/it2me/it2me_native_messaging_host.cc
index b55eef5..5a52541a 100644
--- a/remoting/host/it2me/it2me_native_messaging_host.cc
+++ b/remoting/host/it2me/it2me_native_messaging_host.cc
@@ -206,7 +206,7 @@
     return;
   }
 
-  absl::optional<base::Value::Dict> response =
+  std::optional<base::Value::Dict> response =
       CreateNativeMessageResponse(request);
   if (!response.has_value()) {
     SendErrorAndExit(base::Value::Dict(), ErrorCode::INCOMPATIBLE_PROTOCOL);
@@ -609,7 +609,7 @@
   }
 }
 
-absl::optional<bool>
+std::optional<bool>
 It2MeNativeMessagingHost::GetAllowElevatedHostPolicyValue() {
   DCHECK(policy_received_);
 #if BUILDFLAG(IS_WIN)
@@ -624,7 +624,7 @@
   }
 #endif  // BUILDFLAG(IS_WIN)
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void It2MeNativeMessagingHost::OnPolicyError() {
diff --git a/remoting/host/it2me/it2me_native_messaging_host.h b/remoting/host/it2me/it2me_native_messaging_host.h
index b35936f..0fbeec8 100644
--- a/remoting/host/it2me/it2me_native_messaging_host.h
+++ b/remoting/host/it2me/it2me_native_messaging_host.h
@@ -8,6 +8,7 @@
 #include <memory>
 #include <string>
 
+#include <optional>
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
@@ -18,7 +19,6 @@
 #include "remoting/host/it2me/it2me_host.h"
 #include "remoting/protocol/errors.h"
 #include "remoting/signaling/delegating_signal_strategy.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
 #include "remoting/host/native_messaging/log_message_handler.h"
@@ -101,7 +101,7 @@
   std::string ExtractAccessToken(const base::Value::Dict& message);
 
   // Returns the value of the 'allow_elevated_host' platform policy or empty.
-  absl::optional<bool> GetAllowElevatedHostPolicyValue();
+  std::optional<bool> GetAllowElevatedHostPolicyValue();
 
   // Indicates whether the current process is already elevated.
   bool is_process_elevated_ = false;
diff --git a/remoting/host/it2me/it2me_native_messaging_host_ash.cc b/remoting/host/it2me/it2me_native_messaging_host_ash.cc
index 8cd9948..cb95013 100644
--- a/remoting/host/it2me/it2me_native_messaging_host_ash.cc
+++ b/remoting/host/it2me/it2me_native_messaging_host_ash.cc
@@ -27,7 +27,7 @@
 
 bool ShouldSuppressNotifications(
     const mojom::SupportSessionParams& params,
-    const absl::optional<ChromeOsEnterpriseParams>& enterprise_params) {
+    const std::optional<ChromeOsEnterpriseParams>& enterprise_params) {
   if (enterprise_params.has_value()) {
     return enterprise_params->suppress_notifications;
   }
@@ -42,7 +42,7 @@
 
 bool ShouldSuppressUserDialog(
     const mojom::SupportSessionParams& params,
-    const absl::optional<ChromeOsEnterpriseParams>& enterprise_params) {
+    const std::optional<ChromeOsEnterpriseParams>& enterprise_params) {
   if (enterprise_params.has_value()) {
     return enterprise_params->suppress_user_dialogs;
   }
@@ -57,7 +57,7 @@
 
 bool ShouldTerminateUponInput(
     const mojom::SupportSessionParams& params,
-    const absl::optional<ChromeOsEnterpriseParams>& enterprise_params) {
+    const std::optional<ChromeOsEnterpriseParams>& enterprise_params) {
   if (enterprise_params.has_value()) {
     return enterprise_params->terminate_upon_input;
   }
@@ -72,7 +72,7 @@
 
 bool ShouldCurtainLocalUserSession(
     const mojom::SupportSessionParams& params,
-    const absl::optional<ChromeOsEnterpriseParams>& enterprise_params) {
+    const std::optional<ChromeOsEnterpriseParams>& enterprise_params) {
   if (!base::FeatureList::IsEnabled(features::kEnableCrdAdminRemoteAccess)) {
     return false;
   }
@@ -90,7 +90,7 @@
 }
 
 bool ShouldShowTroubleshootingTools(
-    const absl::optional<ChromeOsEnterpriseParams>& enterprise_params) {
+    const std::optional<ChromeOsEnterpriseParams>& enterprise_params) {
   if (enterprise_params.has_value()) {
     return enterprise_params->show_troubleshooting_tools;
   }
@@ -98,7 +98,7 @@
 }
 
 bool ShouldAllowTroubleshootingTools(
-    const absl::optional<ChromeOsEnterpriseParams>& enterprise_params) {
+    const std::optional<ChromeOsEnterpriseParams>& enterprise_params) {
   if (enterprise_params.has_value()) {
     return enterprise_params->allow_troubleshooting_tools;
   }
@@ -106,7 +106,7 @@
 }
 
 bool ShouldAllowReconnections(
-    const absl::optional<ChromeOsEnterpriseParams>& enterprise_params) {
+    const std::optional<ChromeOsEnterpriseParams>& enterprise_params) {
   if (enterprise_params.has_value()) {
     return enterprise_params->allow_reconnections;
   }
@@ -114,7 +114,7 @@
 }
 
 bool ShouldAllowFileTransfer(
-    const absl::optional<ChromeOsEnterpriseParams>& enterprise_params) {
+    const std::optional<ChromeOsEnterpriseParams>& enterprise_params) {
   if (enterprise_params.has_value()) {
     return enterprise_params->allow_file_transfer;
   }
@@ -153,8 +153,8 @@
 
 void It2MeNativeMessageHostAsh::Connect(
     const mojom::SupportSessionParams& params,
-    const absl::optional<ChromeOsEnterpriseParams>& enterprise_params,
-    const absl::optional<ReconnectParams>& reconnect_params,
+    const std::optional<ChromeOsEnterpriseParams>& enterprise_params,
+    const std::optional<ReconnectParams>& reconnect_params,
     base::OnceClosure connected_callback,
     HostStateConnectedCallback host_state_connected_callback,
     base::OnceClosure host_state_disconnected_callback,
@@ -314,7 +314,7 @@
           ErrorCodeToString(protocol::ErrorCode::INCOMPATIBLE_PROTOCOL));
       return;
     }
-    absl::optional<int> access_code_lifetime =
+    std::optional<int> access_code_lifetime =
         message.FindInt(kAccessCodeLifetime);
     if (!access_code_lifetime) {
       LOG(ERROR) << "Missing |" << kAccessCodeLifetime << "| value in message.";
@@ -336,7 +336,7 @@
     }
     remote_->OnHostStateConnected(*remote_username);
 
-    absl::optional<ReconnectParams> reconnect_params;
+    std::optional<ReconnectParams> reconnect_params;
     const auto* reconnect_params_ptr = message.FindDict(kReconnectParamsDict);
     if (reconnect_params_ptr) {
       reconnect_params.emplace(
@@ -375,7 +375,7 @@
 void It2MeNativeMessageHostAsh::HandleNatPolicyChangedMessage(
     base::Value::Dict message) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  absl::optional<bool> nat_enabled =
+  std::optional<bool> nat_enabled =
       message.FindBool(kNatPolicyChangedMessageNatEnabled);
   if (!nat_enabled.has_value()) {
     LOG(ERROR) << "Missing |" << kNatPolicyChangedMessageNatEnabled
@@ -384,7 +384,7 @@
     return;
   }
 
-  absl::optional<bool> relay_enabled =
+  std::optional<bool> relay_enabled =
       message.FindBool(kNatPolicyChangedMessageRelayEnabled);
   if (!nat_enabled.has_value()) {
     LOG(ERROR) << "Missing |" << kNatPolicyChangedMessageRelayEnabled
diff --git a/remoting/host/it2me/it2me_native_messaging_host_ash.h b/remoting/host/it2me/it2me_native_messaging_host_ash.h
index 51cbf43..deb699ad 100644
--- a/remoting/host/it2me/it2me_native_messaging_host_ash.h
+++ b/remoting/host/it2me/it2me_native_messaging_host_ash.h
@@ -7,6 +7,7 @@
 #include <memory>
 #include <string>
 
+#include <optional>
 #include "base/sequence_checker.h"
 #include "base/thread_annotations.h"
 #include "base/values.h"
@@ -15,7 +16,6 @@
 #include "mojo/public/cpp/bindings/remote.h"
 #include "remoting/host/chromeos/chromeos_enterprise_params.h"
 #include "remoting/host/mojom/remote_support.mojom.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace extensions {
 class NativeMessageHost;
@@ -45,7 +45,7 @@
   ~It2MeNativeMessageHostAsh() override;
 
   using HostStateConnectedCallback =
-      base::OnceCallback<void(absl::optional<ReconnectParams>)>;
+      base::OnceCallback<void(std::optional<ReconnectParams>)>;
 
   // Creates a new NMH instance, creates a new SupportHostObserver remote and
   // returns the pending_remote.  Start() must be called before the first call
@@ -62,14 +62,13 @@
   // |connected_callback| is run after the connection process has completed.
   // If `reconnect_params` is set then the new connection will allow a
   // previously connected client to reconnect.
-  void Connect(
-      const mojom::SupportSessionParams& params,
-      const absl::optional<ChromeOsEnterpriseParams>& enterprise_params,
-      const absl::optional<ReconnectParams>& reconnect_params,
-      base::OnceClosure connected_callback,
-      HostStateConnectedCallback host_state_connected_callback,
-      base::OnceClosure host_state_disconnected_callback,
-      base::OnceClosure disconnected_callback);
+  void Connect(const mojom::SupportSessionParams& params,
+               const std::optional<ChromeOsEnterpriseParams>& enterprise_params,
+               const std::optional<ReconnectParams>& reconnect_params,
+               base::OnceClosure connected_callback,
+               HostStateConnectedCallback host_state_connected_callback,
+               base::OnceClosure host_state_disconnected_callback,
+               base::OnceClosure disconnected_callback);
   // Disconnects an active session if one exists.
   void Disconnect();
 
diff --git a/remoting/host/it2me/it2me_native_messaging_host_lacros.cc b/remoting/host/it2me/it2me_native_messaging_host_lacros.cc
index e9a58ae2f..d503a06 100644
--- a/remoting/host/it2me/it2me_native_messaging_host_lacros.cc
+++ b/remoting/host/it2me/it2me_native_messaging_host_lacros.cc
@@ -41,7 +41,7 @@
 constexpr int kInvalidMessageId = -1;
 
 int GetMessageId(const base::Value::Dict& message) {
-  absl::optional<int> message_id = message.FindInt(kMessageId);
+  std::optional<int> message_id = message.FindInt(kMessageId);
   return message_id.value_or(kInvalidMessageId);
 }
 
@@ -89,7 +89,7 @@
   void OnHostStateConnecting() override;
   void OnHostStateConnected(const std::string& remote_username) override;
   void OnHostStateDisconnected(
-      const absl::optional<std::string>& disconnect_reason) override;
+      const std::optional<std::string>& disconnect_reason) override;
   void OnNatPolicyChanged(mojom::NatPolicyStatePtr policy_state) override;
   void OnHostStateError(int64_t error_code) override;
   void OnPolicyError() override;
@@ -219,7 +219,7 @@
 }
 
 void It2MeNativeMessagingHostLacros::OnHostStateDisconnected(
-    const absl::optional<std::string>& disconnect_reason) {
+    const std::optional<std::string>& disconnect_reason) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   base::Value::Dict message;
   if (disconnect_reason.has_value()) {
diff --git a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc
index 22bdcc54..882785cc 100644
--- a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc
+++ b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc
@@ -51,7 +51,7 @@
 const char kTestStunServer[] = "test_relay_server.com";
 
 void VerifyId(const base::Value::Dict& response, int expected_value) {
-  absl::optional<int> value = response.FindInt(kMessageId);
+  std::optional<int> value = response.FindInt(kMessageId);
   ASSERT_TRUE(value);
   EXPECT_EQ(expected_value, *value);
 }
@@ -72,7 +72,7 @@
   ASSERT_TRUE(string_value);
   EXPECT_EQ(type, *string_value);
 
-  absl::optional<int> int_value = response.FindInt(kMessageId);
+  std::optional<int> int_value = response.FindInt(kMessageId);
   ASSERT_TRUE(int_value);
   EXPECT_EQ(id, *int_value);
 }
@@ -231,7 +231,7 @@
 
  protected:
   void SetPolicies(base::Value::Dict dict);
-  absl::optional<base::Value::Dict> ReadMessageFromOutputPipe();
+  std::optional<base::Value::Dict> ReadMessageFromOutputPipe();
   void WriteMessageToInputPipe(const base::Value::Dict& message);
 
   void VerifyHelloResponse(int request_id);
@@ -248,7 +248,7 @@
                       bool expect_error_response);
   void TestConnect();
 
-  const absl::optional<ChromeOsEnterpriseParams>
+  const std::optional<ChromeOsEnterpriseParams>
   get_chrome_os_enterprise_params() {
     return factory_raw_ptr_->host->chrome_os_enterprise_params_;
   }
@@ -330,7 +330,7 @@
   test_run_loop_->Run();
 
   // Verify there are no more message in the output pipe.
-  absl::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
+  std::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
   EXPECT_FALSE(response);
 
   // The It2MeNativeMessagingHost dtor closes the handles that are passed to it.
@@ -358,7 +358,7 @@
   policy_run_loop_.reset(nullptr);
 }
 
-absl::optional<base::Value::Dict>
+std::optional<base::Value::Dict>
 It2MeNativeMessagingHostTest::ReadMessageFromOutputPipe() {
   while (true) {
     uint32_t length;
@@ -366,7 +366,7 @@
         reinterpret_cast<char*>(&length), sizeof(length));
     if (read_result != sizeof(length)) {
       // The output pipe has been closed, return an empty message.
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     std::string message_json(length, '\0');
@@ -375,13 +375,13 @@
     if (read_result != static_cast<int>(length)) {
       LOG(ERROR) << "Message size (" << read_result
                  << ") doesn't match the header (" << length << ").";
-      return absl::nullopt;
+      return std::nullopt;
     }
 
-    absl::optional<base::Value> message = base::JSONReader::Read(message_json);
+    std::optional<base::Value> message = base::JSONReader::Read(message_json);
     if (!message || !message->is_dict()) {
       LOG(ERROR) << "Malformed message:" << message_json;
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     base::Value::Dict result = std::move(*message).TakeDict();
@@ -405,13 +405,13 @@
 }
 
 void It2MeNativeMessagingHostTest::VerifyHelloResponse(int request_id) {
-  absl::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
+  std::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
   ASSERT_TRUE(response);
   VerifyCommonProperties(*response, kHelloResponse, request_id);
 }
 
 void It2MeNativeMessagingHostTest::VerifyErrorResponse() {
-  absl::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
+  std::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
   ASSERT_TRUE(response);
   VerifyStringProperty(*response, kMessageType, kErrorMessage);
 }
@@ -428,7 +428,7 @@
   // We expect a total of 7 messages: 1 connectResponse, 1 natPolicyChanged,
   // and 5 hostStateChanged.
   for (int i = 0; i < 7; ++i) {
-    absl::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
+    std::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
     ASSERT_TRUE(response);
 
     const std::string* type = response->FindString(kMessageType);
@@ -461,7 +461,7 @@
         ASSERT_TRUE(value);
         EXPECT_EQ(kTestAccessCode, *value);
 
-        absl::optional<int> access_code_lifetime =
+        std::optional<int> access_code_lifetime =
             response->FindInt(kAccessCodeLifetime);
         ASSERT_TRUE(access_code_lifetime);
         EXPECT_EQ(kTestAccessCodeLifetime.InSeconds(), *access_code_lifetime);
@@ -491,7 +491,7 @@
 
   // We expect a total of 2 messages: disconnectResponse and hostStateChanged.
   for (int i = 0; i < 2; i++) {
-    absl::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
+    std::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
     ASSERT_TRUE(response);
 
     const std::string* type = response->FindString(kMessageType);
@@ -520,7 +520,7 @@
 }
 
 void It2MeNativeMessagingHostTest::VerifyPolicyErrorResponse() {
-  absl::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
+  std::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
   ASSERT_TRUE(response);
   const std::string* type = response->FindString(kMessageType);
   ASSERT_TRUE(type);
@@ -544,7 +544,7 @@
     VerifyErrorResponse();
   }
 
-  absl::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
+  std::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
   EXPECT_FALSE(response);
 }
 
@@ -639,7 +639,7 @@
   message.Set(kMessageId, "42");
   WriteMessageToInputPipe(message);
 
-  absl::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
+  std::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
   ASSERT_TRUE(response);
   const std::string* value = response->FindString(kMessageId);
   EXPECT_FALSE(value);
diff --git a/remoting/host/keyboard_layout_monitor_linux.cc b/remoting/host/keyboard_layout_monitor_linux.cc
index 87e13fa..f9f7d51 100644
--- a/remoting/host/keyboard_layout_monitor_linux.cc
+++ b/remoting/host/keyboard_layout_monitor_linux.cc
@@ -6,6 +6,7 @@
 
 #include <gdk/gdk.h>
 
+#include <optional>
 #include "base/files/file_descriptor_watcher_posix.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
@@ -19,7 +20,6 @@
 #include "remoting/host/linux/keyboard_layout_monitor_wayland.h"
 #include "remoting/host/linux/wayland_utils.h"
 #include "remoting/proto/control.pb.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/glib/scoped_gsignal.h"
 #include "ui/events/keycodes/dom/dom_code.h"
 #include "ui/events/keycodes/dom/keycode_converter.h"
diff --git a/remoting/host/keyboard_layout_monitor_mac.cc b/remoting/host/keyboard_layout_monitor_mac.cc
index dea23f0..4cedac5 100644
--- a/remoting/host/keyboard_layout_monitor_mac.cc
+++ b/remoting/host/keyboard_layout_monitor_mac.cc
@@ -11,6 +11,7 @@
 #include <memory>
 #include <utility>
 
+#include <optional>
 #include "base/apple/scoped_cftyperef.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
@@ -20,7 +21,6 @@
 #include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "remoting/proto/control.pb.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/events/keycodes/dom/dom_code.h"
 #include "ui/events/keycodes/dom/keycode_converter.h"
 
@@ -59,9 +59,9 @@
   base::WeakPtrFactory<KeyboardLayoutMonitorMac> weak_ptr_factory_;
 };
 
-absl::optional<protocol::LayoutKeyFunction> GetFixedKeyFunction(int keycode);
-absl::optional<protocol::LayoutKeyFunction> GetCharFunction(UniChar char_code,
-                                                            int keycode);
+std::optional<protocol::LayoutKeyFunction> GetFixedKeyFunction(int keycode);
+std::optional<protocol::LayoutKeyFunction> GetCharFunction(UniChar char_code,
+                                                           int keycode);
 
 KeyboardLayoutMonitorMac::KeyboardLayoutMonitorMac(
     base::RepeatingCallback<void(const protocol::KeyboardLayout&)> callback)
@@ -169,7 +169,7 @@
         *(*layout_message.mutable_keys())[usb_code].mutable_actions();
 
     for (int shift_level = 0; shift_level < 4; ++shift_level) {
-      absl::optional<protocol::LayoutKeyFunction> fixed_function =
+      std::optional<protocol::LayoutKeyFunction> fixed_function =
           GetFixedKeyFunction(keycode);
       if (fixed_function) {
         key_actions[shift_level].set_function(*fixed_function);
@@ -198,7 +198,7 @@
       }
 
       if (result_length == 1) {
-        absl::optional<protocol::LayoutKeyFunction> char_function =
+        std::optional<protocol::LayoutKeyFunction> char_function =
             GetCharFunction(result_array[0], keycode);
         if (char_function) {
           key_actions[shift_level].set_function(*char_function);
@@ -222,7 +222,7 @@
                      callback_context->weak_ptr, std::move(layout_message)));
 }
 
-absl::optional<protocol::LayoutKeyFunction> GetFixedKeyFunction(int keycode) {
+std::optional<protocol::LayoutKeyFunction> GetFixedKeyFunction(int keycode) {
   // Some keys are not represented in the layout and always have the same
   // function.
   switch (keycode) {
@@ -283,12 +283,12 @@
     case kVK_JIS_Eisu:
       return protocol::LayoutKeyFunction::EISU;
     default:
-      return absl::nullopt;
+      return std::nullopt;
   }
 }
 
-absl::optional<protocol::LayoutKeyFunction> GetCharFunction(UniChar char_code,
-                                                            int keycode) {
+std::optional<protocol::LayoutKeyFunction> GetCharFunction(UniChar char_code,
+                                                           int keycode) {
   switch (char_code) {
     case kHomeCharCode:
       return protocol::LayoutKeyFunction::HOME;
@@ -333,7 +333,7 @@
     case kDeleteCharCode:
       return protocol::LayoutKeyFunction::DELETE_;
     default:
-      return absl::nullopt;
+      return std::nullopt;
   }
 }
 
diff --git a/remoting/host/linux/input_injector_wayland.cc b/remoting/host/linux/input_injector_wayland.cc
index 797d8b3..9be5cce7 100644
--- a/remoting/host/linux/input_injector_wayland.cc
+++ b/remoting/host/linux/input_injector_wayland.cc
@@ -11,6 +11,7 @@
 #include <set>
 #include <utility>
 
+#include <optional>
 #include "base/containers/contains.h"
 #include "base/containers/queue.h"
 #include "base/functional/bind.h"
@@ -32,7 +33,6 @@
 #include "remoting/host/linux/unicode_to_keysym.h"
 #include "remoting/host/linux/wayland_manager.h"
 #include "remoting/proto/internal.pb.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
 #include "third_party/webrtc/modules/desktop_capture/linux/wayland/scoped_glib.h"
 #include "third_party/webrtc/modules/desktop_capture/linux/wayland/xdg_desktop_portal_utils.h"
@@ -240,7 +240,7 @@
     return;
   }
   if (!clipboard_initialized_) {
-    pending_clipboard_event_ = absl::make_optional(event);
+    pending_clipboard_event_ = std::make_optional(event);
     return;
   }
   clipboard_->InjectClipboardEvent(event);
diff --git a/remoting/host/linux/input_injector_wayland.h b/remoting/host/linux/input_injector_wayland.h
index 72b5cb59..c6a5d2c4 100644
--- a/remoting/host/linux/input_injector_wayland.h
+++ b/remoting/host/linux/input_injector_wayland.h
@@ -13,6 +13,7 @@
 #include <set>
 #include <utility>
 
+#include <optional>
 #include "base/containers/queue.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
@@ -32,7 +33,6 @@
 #include "remoting/host/linux/remote_desktop_portal_injector.h"
 #include "remoting/host/linux/wayland_manager.h"
 #include "remoting/proto/internal.pb.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "remoting/host/chromeos/point_transformer.h"
@@ -121,7 +121,7 @@
 
     scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_;
     std::set<int> pressed_keys_;
-    absl::optional<webrtc::DesktopVector> latest_mouse_position_;
+    std::optional<webrtc::DesktopVector> latest_mouse_position_;
     float wheel_ticks_x_ = 0;
     float wheel_ticks_y_ = 0;
     base::TimeTicks latest_tick_y_event_;
@@ -141,7 +141,7 @@
     // but separated so that the remote desktop isn't blocked waiting for the
     // clipboard.
     bool clipboard_initialized_ = false;
-    absl::optional<protocol::ClipboardEvent> pending_clipboard_event_;
+    std::optional<protocol::ClipboardEvent> pending_clipboard_event_;
 
     // Keeps track of whether or not the associated seat has keyboard
     // capability.
diff --git a/remoting/host/linux/remoting_user_session.cc b/remoting/host/linux/remoting_user_session.cc
index 88693c0..a27dedd 100644
--- a/remoting/host/linux/remoting_user_session.cc
+++ b/remoting/host/linux/remoting_user_session.cc
@@ -37,6 +37,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/environment.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -46,7 +47,6 @@
 #include "base/strings/strcat.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -99,13 +99,13 @@
 // Shell-escapes a single argument in a way that is compatible with various
 // different shells. Returns nullopt when argument contains a newline, which
 // can't be represented in a cross-shell fashion.
-absl::optional<std::string> ShellEscapeArgument(
+std::optional<std::string> ShellEscapeArgument(
     const base::StringPiece argument) {
   std::string result;
   for (char character : argument) {
     // csh in particular doesn't provide a good way to handle this
     if (character == '\n') {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     // Some shells ascribe special meaning to some escape sequences such as \t,
@@ -231,12 +231,12 @@
 
   // Returns the current username according to PAM. It is possible for PAM
   // modules to change this from the initial value passed to the constructor.
-  absl::optional<std::string> GetUser() {
+  std::optional<std::string> GetUser() {
     const char* user;
     last_return_code_ = pam_get_item(pam_handle_, PAM_USER,
                                      reinterpret_cast<const void**>(&user));
     if (last_return_code_ != PAM_SUCCESS || user == nullptr) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return std::string(user);
   }
@@ -248,11 +248,11 @@
   }
 
   // Obtains the list of environment variables provided by PAM modules.
-  absl::optional<base::EnvironmentMap> GetEnvironment() {
+  std::optional<base::EnvironmentMap> GetEnvironment() {
     char** environment = pam_getenvlist(pam_handle_);
 
     if (environment == nullptr) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     base::EnvironmentMap environment_map;
@@ -323,14 +323,14 @@
   // argv[0] with a '-'.
   std::string shell_name = '-' + base::FilePath(login_shell).BaseName().value();
 
-  absl::optional<std::string> escaped_script_path =
+  std::optional<std::string> escaped_script_path =
       ShellEscapeArgument(FindScriptPath());
   CHECK(escaped_script_path) << "Could not escape script path";
 
   std::string shell_arg = *escaped_script_path + " --start --child-process";
 
   for (const std::string& arg : script_args) {
-    absl::optional<std::string> escaped_arg = ShellEscapeArgument(arg);
+    std::optional<std::string> escaped_arg = ShellEscapeArgument(arg);
     CHECK(escaped_arg) << "Could not escape script argument";
     shell_arg += " ";
     shell_arg += *escaped_arg;
@@ -369,7 +369,7 @@
 
 // Either |user| must be set when running as root, xor the real user ID must be
 // properly set when running as a user.
-void Relaunch(const absl::optional<std::string>& user,
+void Relaunch(const std::optional<std::string>& user,
               const std::vector<std::string>& script_args) {
   CHECK(user.has_value() == (getuid() == 0));
 
@@ -400,7 +400,7 @@
 // Returns: whether the session should be relaunched.
 bool ExecuteSession(std::string user,
                     bool chown_log,
-                    absl::optional<uid_t> match_uid,
+                    std::optional<uid_t> match_uid,
                     const std::vector<std::string>& script_args) {
   PamHandle pam_handle(kPamName, user.c_str(), &kPamConversation);
   CHECK(pam_handle.IsInitialized()) << "Failed to initialize PAM";
@@ -492,7 +492,7 @@
   if (child_pid == 0) {
     PCHECK(setuid(pwinfo->pw_uid) == 0) << "setuid failed";
     PCHECK(chdir(pwinfo->pw_dir) == 0) << "chdir to $HOME failed";
-    absl::optional<base::EnvironmentMap> pam_environment =
+    std::optional<base::EnvironmentMap> pam_environment =
         pam_handle.GetEnvironment();
     CHECK(pam_environment) << "Failed to get environment from PAM";
 
@@ -803,7 +803,7 @@
   argv += 2;
 
   bool foreground = false;
-  absl::optional<std::string> user;
+  std::optional<std::string> user;
   std::vector<std::string> script_args;
 
   while (argc > 0) {
@@ -855,8 +855,8 @@
   // Daemonizing redirects stdout to a log file, which we want to be owned by
   // the target user.
   bool chown_stdout = !foreground;
-  absl::optional<uid_t> match_uid =
-      real_uid != 0 ? absl::make_optional(real_uid) : absl::nullopt;
+  std::optional<uid_t> match_uid =
+      real_uid != 0 ? std::make_optional(real_uid) : std::nullopt;
 
   // Fork before opening PAM session so relaunches don't descend from the closed
   // PAM session.
@@ -885,7 +885,7 @@
       // If running as root, forward the username argument to the relaunched
       // process. Otherwise, it should be inferred from the user id and
       // environment.
-      Relaunch(real_uid == 0 ? user : absl::nullopt, script_args);
+      Relaunch(real_uid == 0 ? user : std::nullopt, script_args);
     }
   }
 
diff --git a/remoting/host/mojom/remoting_mojom_traits.cc b/remoting/host/mojom/remoting_mojom_traits.cc
index 7fbfe245..2ea9b8c 100644
--- a/remoting/host/mojom/remoting_mojom_traits.cc
+++ b/remoting/host/mojom/remoting_mojom_traits.cc
@@ -95,7 +95,7 @@
   out_options->set_enable_remote_open_url(data_view.enable_remote_open_url());
   out_options->set_enable_remote_webauthn(data_view.enable_remote_webauthn());
 
-  absl::optional<uint32_t> clipboard_size;
+  std::optional<uint32_t> clipboard_size;
   if (!data_view.ReadClipboardSize(&clipboard_size)) {
     return false;
   }
@@ -210,7 +210,7 @@
   }
   out_error->set_type(type);
 
-  absl::optional<int32_t> api_error_code;
+  std::optional<int32_t> api_error_code;
   if (!data_view.ReadApiErrorCode(&api_error_code)) {
     return false;
   }
@@ -283,7 +283,7 @@
   out_event->set_usb_keycode(data_view.usb_keycode());
   out_event->set_lock_states(data_view.lock_states());
 
-  absl::optional<bool> caps_lock_state;
+  std::optional<bool> caps_lock_state;
   if (!data_view.ReadCapsLockState(&caps_lock_state)) {
     return false;
   }
@@ -291,7 +291,7 @@
     out_event->set_caps_lock_state(*caps_lock_state);
   }
 
-  absl::optional<bool> num_lock_state;
+  std::optional<bool> num_lock_state;
   if (!data_view.ReadNumLockState(&num_lock_state)) {
     return false;
   }
@@ -349,7 +349,7 @@
                         ::remoting::protocol::MouseEvent>::
     Read(remoting::mojom::MouseEventDataView data_view,
          ::remoting::protocol::MouseEvent* out_event) {
-  absl::optional<int32_t> x;
+  std::optional<int32_t> x;
   if (!data_view.ReadX(&x)) {
     return false;
   }
@@ -357,7 +357,7 @@
     out_event->set_x(*x);
   }
 
-  absl::optional<int32_t> y;
+  std::optional<int32_t> y;
   if (!data_view.ReadY(&y)) {
     return false;
   }
@@ -373,7 +373,7 @@
     out_event->set_button(mouse_button);
   }
 
-  absl::optional<bool> button_down;
+  std::optional<bool> button_down;
   if (!data_view.ReadButtonDown(&button_down)) {
     return false;
   }
@@ -381,7 +381,7 @@
     out_event->set_button_down(*button_down);
   }
 
-  absl::optional<float> wheel_delta_x;
+  std::optional<float> wheel_delta_x;
   if (!data_view.ReadWheelDeltaX(&wheel_delta_x)) {
     return false;
   }
@@ -389,7 +389,7 @@
     out_event->set_wheel_delta_x(*wheel_delta_x);
   }
 
-  absl::optional<float> wheel_delta_y;
+  std::optional<float> wheel_delta_y;
   if (!data_view.ReadWheelDeltaY(&wheel_delta_y)) {
     return false;
   }
@@ -397,7 +397,7 @@
     out_event->set_wheel_delta_y(*wheel_delta_y);
   }
 
-  absl::optional<float> wheel_ticks_x;
+  std::optional<float> wheel_ticks_x;
   if (!data_view.ReadWheelTicksX(&wheel_ticks_x)) {
     return false;
   }
@@ -405,7 +405,7 @@
     out_event->set_wheel_ticks_x(*wheel_ticks_x);
   }
 
-  absl::optional<float> wheel_ticks_y;
+  std::optional<float> wheel_ticks_y;
   if (!data_view.ReadWheelTicksY(&wheel_ticks_y)) {
     return false;
   }
@@ -413,7 +413,7 @@
     out_event->set_wheel_ticks_y(*wheel_ticks_y);
   }
 
-  absl::optional<int32_t> delta_x;
+  std::optional<int32_t> delta_x;
   if (!data_view.ReadDeltaX(&delta_x)) {
     return false;
   }
@@ -421,7 +421,7 @@
     out_event->set_delta_x(*delta_x);
   }
 
-  absl::optional<int32_t> delta_y;
+  std::optional<int32_t> delta_y;
   if (!data_view.ReadDeltaY(&delta_y)) {
     return false;
   }
diff --git a/remoting/host/mojom/remoting_mojom_traits.h b/remoting/host/mojom/remoting_mojom_traits.h
index 4bc1e72..b89795d 100644
--- a/remoting/host/mojom/remoting_mojom_traits.h
+++ b/remoting/host/mojom/remoting_mojom_traits.h
@@ -9,6 +9,7 @@
 #include <memory>
 #include <string>
 
+#include <optional>
 #include "base/containers/span.h"
 #include "base/files/file_path.h"
 #include "base/numerics/safe_conversions.h"
@@ -35,7 +36,6 @@
 #include "remoting/protocol/file_transfer_helpers.h"
 #include "remoting/protocol/transport.h"
 #include "services/network/public/cpp/ip_endpoint_mojom_traits.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
 #include "third_party/webrtc/modules/desktop_capture/mouse_cursor.h"
 #include "ui/gfx/geometry/mojom/geometry_mojom_traits.h"
@@ -152,10 +152,10 @@
     return options.enable_remote_webauthn();
   }
 
-  static absl::optional<uint32_t> clipboard_size(
+  static std::optional<uint32_t> clipboard_size(
       const ::remoting::DesktopEnvironmentOptions& options) {
     if (!options.clipboard_size().has_value()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     size_t clipboard_size = options.clipboard_size().value();
@@ -618,12 +618,12 @@
     return error.type();
   }
 
-  static absl::optional<int32_t> api_error_code(
+  static std::optional<int32_t> api_error_code(
       const ::remoting::protocol::FileTransfer_Error& error) {
     if (error.has_api_error_code()) {
       return error.api_error_code();
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   static const std::string& function(
@@ -1169,20 +1169,20 @@
     return event.lock_states();
   }
 
-  static absl::optional<bool> caps_lock_state(
+  static std::optional<bool> caps_lock_state(
       const ::remoting::protocol::KeyEvent& event) {
     if (event.has_caps_lock_state()) {
       return event.caps_lock_state();
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  static absl::optional<bool> num_lock_state(
+  static std::optional<bool> num_lock_state(
       const ::remoting::protocol::KeyEvent& event) {
     if (event.has_num_lock_state()) {
       return event.num_lock_state();
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   static bool Read(remoting::mojom::KeyEventDataView data_view,
@@ -1193,20 +1193,20 @@
 class StructTraits<remoting::mojom::MouseEventDataView,
                    ::remoting::protocol::MouseEvent> {
  public:
-  static absl::optional<int32_t> x(
+  static std::optional<int32_t> x(
       const ::remoting::protocol::MouseEvent& event) {
     if (event.has_x()) {
       return event.x();
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  static absl::optional<int32_t> y(
+  static std::optional<int32_t> y(
       const ::remoting::protocol::MouseEvent& event) {
     if (event.has_y()) {
       return event.y();
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   static ::remoting::protocol::MouseEvent::MouseButton button(
@@ -1217,61 +1217,61 @@
     return ::remoting::protocol::MouseEvent::BUTTON_UNDEFINED;
   }
 
-  static absl::optional<bool> button_down(
+  static std::optional<bool> button_down(
       const ::remoting::protocol::MouseEvent& event) {
     if (event.has_button_down()) {
       DCHECK(event.has_button());
       return event.button_down();
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  static absl::optional<float> wheel_delta_x(
+  static std::optional<float> wheel_delta_x(
       const ::remoting::protocol::MouseEvent& event) {
     if (event.has_wheel_delta_x()) {
       return event.wheel_delta_x();
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  static absl::optional<float> wheel_delta_y(
+  static std::optional<float> wheel_delta_y(
       const ::remoting::protocol::MouseEvent& event) {
     if (event.has_wheel_delta_y()) {
       return event.wheel_delta_y();
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  static absl::optional<float> wheel_ticks_x(
+  static std::optional<float> wheel_ticks_x(
       const ::remoting::protocol::MouseEvent& event) {
     if (event.wheel_ticks_x()) {
       return event.wheel_ticks_x();
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  static absl::optional<float> wheel_ticks_y(
+  static std::optional<float> wheel_ticks_y(
       const ::remoting::protocol::MouseEvent& event) {
     if (event.wheel_ticks_y()) {
       return event.wheel_ticks_y();
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  static absl::optional<int32_t> delta_x(
+  static std::optional<int32_t> delta_x(
       const ::remoting::protocol::MouseEvent& event) {
     if (event.has_delta_x()) {
       return event.delta_x();
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  static absl::optional<int32_t> delta_y(
+  static std::optional<int32_t> delta_y(
       const ::remoting::protocol::MouseEvent& event) {
     if (event.has_delta_y()) {
       return event.delta_y();
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   static bool Read(remoting::mojom::MouseEventDataView data_view,
diff --git a/remoting/host/native_messaging/native_messaging_helpers.cc b/remoting/host/native_messaging/native_messaging_helpers.cc
index b434fa8..d1feaeb 100644
--- a/remoting/host/native_messaging/native_messaging_helpers.cc
+++ b/remoting/host/native_messaging/native_messaging_helpers.cc
@@ -37,12 +37,12 @@
   return true;
 }
 
-absl::optional<base::Value::Dict> CreateNativeMessageResponse(
+std::optional<base::Value::Dict> CreateNativeMessageResponse(
     const base::Value::Dict& request) {
   const std::string* type = request.FindString(kMessageType);
   if (!type) {
     LOG(ERROR) << "'" << kMessageType << "' not found in request.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   base::Value::Dict response;
diff --git a/remoting/host/native_messaging/native_messaging_helpers.h b/remoting/host/native_messaging/native_messaging_helpers.h
index 7653245..c9853d4 100644
--- a/remoting/host/native_messaging/native_messaging_helpers.h
+++ b/remoting/host/native_messaging/native_messaging_helpers.h
@@ -7,8 +7,8 @@
 
 #include <string>
 
+#include <optional>
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -23,7 +23,7 @@
 // is malformed.
 // For a request like this: {id: "abc", type: "hello"}, the response will be:
 // {id: "abc", type: "helloResponse"}.
-absl::optional<base::Value::Dict> CreateNativeMessageResponse(
+std::optional<base::Value::Dict> CreateNativeMessageResponse(
     const base::Value::Dict& request);
 
 // Adds hello response fields to |response|, which should be created by calling
diff --git a/remoting/host/native_messaging/native_messaging_pipe.cc b/remoting/host/native_messaging/native_messaging_pipe.cc
index 78332b4..bd6c5bf 100644
--- a/remoting/host/native_messaging/native_messaging_pipe.cc
+++ b/remoting/host/native_messaging/native_messaging_pipe.cc
@@ -37,7 +37,7 @@
 
 void NativeMessagingPipe::PostMessageFromNativeHost(
     const std::string& message) {
-  absl::optional<base::Value> json = base::JSONReader::Read(message);
+  std::optional<base::Value> json = base::JSONReader::Read(message);
   channel_->SendMessage(json);
 }
 
diff --git a/remoting/host/native_messaging/native_messaging_reader.cc b/remoting/host/native_messaging/native_messaging_reader.cc
index 6574cb3..e2f066af 100644
--- a/remoting/host/native_messaging/native_messaging_reader.cc
+++ b/remoting/host/native_messaging/native_messaging_reader.cc
@@ -121,7 +121,7 @@
       return;
     }
 
-    absl::optional<base::Value> message = base::JSONReader::Read(message_json);
+    std::optional<base::Value> message = base::JSONReader::Read(message_json);
     if (!message) {
       LOG(ERROR) << "Failed to parse JSON message: " << message_json;
       NotifyEof();
diff --git a/remoting/host/native_messaging/native_messaging_reader_unittest.cc b/remoting/host/native_messaging/native_messaging_reader_unittest.cc
index 8cda736a..6c0da95d 100644
--- a/remoting/host/native_messaging/native_messaging_reader_unittest.cc
+++ b/remoting/host/native_messaging/native_messaging_reader_unittest.cc
@@ -8,6 +8,7 @@
 #include <memory>
 #include <utility>
 
+#include <optional>
 #include "base/functional/bind.h"
 #include "base/run_loop.h"
 #include "base/test/task_environment.h"
@@ -15,7 +16,6 @@
 #include "build/build_config.h"
 #include "remoting/host/setup/test_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -47,7 +47,7 @@
   base::File read_file_;
   base::File write_file_;
   bool on_error_signaled_ = false;
-  absl::optional<base::Value> message_;
+  std::optional<base::Value> message_;
 
  private:
   // MessageLoop declared here, since the NativeMessageReader ctor requires a
@@ -133,7 +133,7 @@
   ASSERT_TRUE(message_);
 
   ASSERT_TRUE(message_->is_dict());
-  absl::optional<int> result = message_->GetDict().FindInt("foo");
+  std::optional<int> result = message_->GetDict().FindInt("foo");
   ASSERT_TRUE(result.has_value());
   ASSERT_EQ(42, result);
 }
@@ -154,7 +154,7 @@
     ASSERT_FALSE(on_error_signaled_);
     ASSERT_TRUE(message_);
     ASSERT_TRUE(message_->is_dict());
-    absl::optional<int> result = message_->GetDict().FindInt("foo");
+    std::optional<int> result = message_->GetDict().FindInt("foo");
     ASSERT_TRUE(result.has_value());
     ASSERT_EQ(42, result);
   }
@@ -165,7 +165,7 @@
     ASSERT_FALSE(on_error_signaled_);
     ASSERT_TRUE(message_);
     ASSERT_TRUE(message_->is_dict());
-    absl::optional<int> result = message_->GetDict().FindInt("bar");
+    std::optional<int> result = message_->GetDict().FindInt("bar");
     ASSERT_TRUE(result.has_value());
     ASSERT_EQ(43, result);
   }
@@ -176,7 +176,7 @@
     ASSERT_FALSE(on_error_signaled_);
     ASSERT_TRUE(message_);
     ASSERT_TRUE(message_->is_dict());
-    absl::optional<int> result = message_->GetDict().FindInt("baz");
+    std::optional<int> result = message_->GetDict().FindInt("baz");
     ASSERT_TRUE(result.has_value());
     ASSERT_EQ(44, result);
   }
diff --git a/remoting/host/native_messaging/pipe_messaging_channel.cc b/remoting/host/native_messaging/pipe_messaging_channel.cc
index d0857acb..f7b73fb 100644
--- a/remoting/host/native_messaging/pipe_messaging_channel.cc
+++ b/remoting/host/native_messaging/pipe_messaging_channel.cc
@@ -63,8 +63,7 @@
   }
 }
 
-void PipeMessagingChannel::SendMessage(
-    absl::optional<base::ValueView> message) {
+void PipeMessagingChannel::SendMessage(std::optional<base::ValueView> message) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   bool success = message && native_messaging_writer_;
diff --git a/remoting/host/native_messaging/pipe_messaging_channel.h b/remoting/host/native_messaging/pipe_messaging_channel.h
index 5082601..ed75c206 100644
--- a/remoting/host/native_messaging/pipe_messaging_channel.h
+++ b/remoting/host/native_messaging/pipe_messaging_channel.h
@@ -49,7 +49,7 @@
 
   // extensions::NativeMessagingChannel implementation.
   void Start(EventHandler* event_handler) override;
-  void SendMessage(absl::optional<base::ValueView> message) override;
+  void SendMessage(std::optional<base::ValueView> message) override;
 
  private:
   // Processes a message received from the client app.
diff --git a/remoting/host/pairing_registry_delegate_win.cc b/remoting/host/pairing_registry_delegate_win.cc
index 7875e70..c4686c2 100644
--- a/remoting/host/pairing_registry_delegate_win.cc
+++ b/remoting/host/pairing_registry_delegate_win.cc
@@ -6,12 +6,12 @@
 
 #include <utility>
 
+#include <optional>
 #include "base/json/json_string_value_serializer.h"
 #include "base/logging.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "base/win/registry.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #include <windows.h>
 
@@ -41,15 +41,15 @@
 
 // Reads value |value_name| from |key| as a JSON string and returns it as
 // |base::Value|.
-absl::optional<base::Value::Dict> ReadValue(const base::win::RegKey& key,
-                                            const wchar_t* value_name) {
+std::optional<base::Value::Dict> ReadValue(const base::win::RegKey& key,
+                                           const wchar_t* value_name) {
   // presubmit: allow wstring
   std::wstring value_json;
   LONG result = key.ReadValue(value_name, &value_json);
   if (result != ERROR_SUCCESS) {
     SetLastError(result);
     PLOG(ERROR) << "Cannot read value '" << value_name << "'";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Parse the value.
@@ -62,12 +62,12 @@
   if (!value) {
     LOG(ERROR) << "Failed to parse '" << value_name << "': " << error_message
                << " (" << error_code << ").";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (!value->is_dict()) {
     LOG(ERROR) << "Failed to parse '" << value_name << "': not a dictionary.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return std::move(*value).TakeDict();
@@ -192,7 +192,7 @@
   std::wstring value_name = base::UTF8ToWide(client_id);
 
   // Read unprivileged fields first.
-  absl::optional<base::Value::Dict> pairing =
+  std::optional<base::Value::Dict> pairing =
       ReadValue(unprivileged_, value_name.c_str());
   if (!pairing) {
     return PairingRegistry::Pairing();
@@ -200,7 +200,7 @@
 
   // Read the shared secret.
   if (privileged_.Valid()) {
-    absl::optional<base::Value::Dict> secret =
+    std::optional<base::Value::Dict> secret =
         ReadValue(privileged_, value_name.c_str());
     if (!secret) {
       return PairingRegistry::Pairing();
@@ -224,7 +224,7 @@
   base::Value::Dict pairing_json = pairing.ToValue();
 
   // Extract the shared secret to a separate dictionary.
-  absl::optional<base::Value> secret_key =
+  std::optional<base::Value> secret_key =
       pairing_json.Extract(PairingRegistry::kSharedSecretKey);
   CHECK(secret_key.has_value());
   base::Value::Dict secret_json;
diff --git a/remoting/host/register_support_host_request.h b/remoting/host/register_support_host_request.h
index 16a7cee..711a4020 100644
--- a/remoting/host/register_support_host_request.h
+++ b/remoting/host/register_support_host_request.h
@@ -8,13 +8,13 @@
 #include <memory>
 #include <string>
 
+#include <optional>
 #include "base/functional/callback_forward.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/time/time.h"
 #include "remoting/base/rsa_key_pair.h"
 #include "remoting/host/chromeos/chromeos_enterprise_params.h"
 #include "remoting/protocol/errors.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -44,7 +44,7 @@
   virtual void StartRequest(SignalStrategy* signal_strategy,
                             scoped_refptr<RsaKeyPair> key_pair,
                             const std::string& authorized_helper,
-                            absl::optional<ChromeOsEnterpriseParams> params,
+                            std::optional<ChromeOsEnterpriseParams> params,
                             RegisterCallback callback) = 0;
 };
 
diff --git a/remoting/host/remote_open_url/remote_open_url_client_delegate_win.cc b/remoting/host/remote_open_url/remote_open_url_client_delegate_win.cc
index e455864..bde8b2f 100644
--- a/remoting/host/remote_open_url/remote_open_url_client_delegate_win.cc
+++ b/remoting/host/remote_open_url/remote_open_url_client_delegate_win.cc
@@ -54,7 +54,7 @@
   task_dialog.AppendButtonWithStringId(IDOK,
                                        IDS_OPEN_DEFAULT_APPS_SETTINGS_BUTTON);
   task_dialog.set_default_button(IDOK);
-  absl::optional<int> result = task_dialog.Show();
+  std::optional<int> result = task_dialog.Show();
   DCHECK_EQ(IDOK, *result);
   base::win::LaunchDefaultAppsSettingsModernDialog(/*protocol=*/std::wstring());
 }
diff --git a/remoting/host/remote_open_url/url_forwarder_configurator_main_win.cc b/remoting/host/remote_open_url/url_forwarder_configurator_main_win.cc
index fcc0376..10959ee 100644
--- a/remoting/host/remote_open_url/url_forwarder_configurator_main_win.cc
+++ b/remoting/host/remote_open_url/url_forwarder_configurator_main_win.cc
@@ -106,7 +106,7 @@
   }
   task_dialog.set_default_button(IDOK);
 
-  absl::optional<int> button_result = task_dialog.Show();
+  std::optional<int> button_result = task_dialog.Show();
   if (!button_result.has_value()) {
     LOG(ERROR) << "Failed to show the setup dialog.";
     return false;
diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc
index cba37d0..f154a8bf 100644
--- a/remoting/host/remoting_me2me_host.cc
+++ b/remoting/host/remoting_me2me_host.cc
@@ -12,6 +12,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -109,7 +110,6 @@
 #include "remoting/signaling/ftl_signal_strategy.h"
 #include "remoting/signaling/remoting_log_to_server.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/webrtc/rtc_base/event_tracer.h"
 
 #if BUILDFLAG(IS_POSIX)
@@ -417,7 +417,7 @@
   base::Value::Dict config_;
   std::string host_owner_;
   bool is_googler_ = false;
-  absl::optional<size_t> max_clipboard_size_;
+  std::optional<size_t> max_clipboard_size_;
 
   std::unique_ptr<PolicyWatcher> policy_watcher_;
   PolicyState policy_state_ = POLICY_INITIALIZING;
@@ -435,7 +435,7 @@
   ThirdPartyAuthConfig third_party_auth_config_;
   bool security_key_auth_policy_enabled_ = false;
   bool security_key_extension_supported_ = true;
-  absl::optional<int> max_session_duration_minutes_;
+  std::optional<int> max_session_duration_minutes_;
 
   // Allows us to override field trials which are causing issues for chromoting.
   std::unique_ptr<base::FieldTrialList> field_trial_list_;
@@ -642,7 +642,7 @@
 void HostProcess::OnConfigUpdated(const std::string& serialized_config) {
   HOST_LOG << "Parsing new host configuration.";
 
-  absl::optional<base::Value::Dict> config(
+  std::optional<base::Value::Dict> config(
       HostConfigFromJson(serialized_config));
   if (!config.has_value()) {
     LOG(ERROR) << "Invalid configuration.";
@@ -1392,7 +1392,7 @@
   DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
 
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
-  absl::optional<bool> host_username_match_required =
+  std::optional<bool> host_username_match_required =
       policies.FindBool(policy::key::kRemoteAccessHostMatchUsername);
   if (!host_username_match_required.has_value()) {
     return false;
@@ -1408,7 +1408,7 @@
   // Returns true if the host has to be restarted after this policy update.
   DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
 
-  absl::optional<bool> allow_nat_traversal =
+  std::optional<bool> allow_nat_traversal =
       policies.FindBool(policy::key::kRemoteAccessHostFirewallTraversal);
   if (!allow_nat_traversal.has_value()) {
     return false;
@@ -1427,7 +1427,7 @@
   // Returns true if the host has to be restarted after this policy update.
   DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
 
-  absl::optional<bool> allow_relay =
+  std::optional<bool> allow_relay =
       policies.FindBool(policy::key::kRemoteAccessHostAllowRelayedConnection);
   if (!allow_relay.has_value()) {
     return false;
@@ -1464,7 +1464,7 @@
   // Returns true if the host has to be restarted after this policy update.
   DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
 
-  absl::optional<bool> curtain_required =
+  std::optional<bool> curtain_required =
       policies.FindBool(policy::key::kRemoteAccessHostRequireCurtain);
   if (!curtain_required.has_value()) {
     return false;
@@ -1523,7 +1523,7 @@
 bool HostProcess::OnPairingPolicyUpdate(const base::Value::Dict& policies) {
   DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
 
-  absl::optional<bool> allow_pairing =
+  std::optional<bool> allow_pairing =
       policies.FindBool(policy::key::kRemoteAccessHostAllowClientPairing);
   if (!allow_pairing.has_value()) {
     return false;
@@ -1541,7 +1541,7 @@
 bool HostProcess::OnGnubbyAuthPolicyUpdate(const base::Value::Dict& policies) {
   DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
 
-  absl::optional<bool> security_key_auth_policy_enabled =
+  std::optional<bool> security_key_auth_policy_enabled =
       policies.FindBool(policy::key::kRemoteAccessHostAllowGnubbyAuth);
   if (!security_key_auth_policy_enabled.has_value()) {
     return false;
@@ -1561,7 +1561,7 @@
     const base::Value::Dict& policies) {
   DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
 
-  absl::optional<bool> file_transfer_enabled =
+  std::optional<bool> file_transfer_enabled =
       policies.FindBool(policy::key::kRemoteAccessHostAllowFileTransfer);
   if (!file_transfer_enabled.has_value()) {
     return false;
@@ -1584,7 +1584,7 @@
     const base::Value::Dict& policies) {
   DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
 
-  absl::optional<bool> enable_user_interface =
+  std::optional<bool> enable_user_interface =
       policies.FindBool(policy::key::kRemoteAccessHostEnableUserInterface);
   if (!enable_user_interface) {
     return false;
@@ -1607,7 +1607,7 @@
     const base::Value::Dict& policies) {
   DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
 
-  absl::optional<int> value = policies.FindInt(
+  std::optional<int> value = policies.FindInt(
       policy::key::kRemoteAccessHostMaximumSessionDurationMinutes);
   if (!value) {
     return false;
@@ -1630,7 +1630,7 @@
     const base::Value::Dict& policies) {
   DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
 
-  absl::optional<int> max_clipboard_size =
+  std::optional<int> max_clipboard_size =
       policies.FindInt(policy::key::kRemoteAccessHostClipboardSizeBytes);
   if (!max_clipboard_size) {
     return false;
@@ -1654,7 +1654,7 @@
   // Returns false: never restart the host after this policy update.
   DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
 
-  absl::optional<bool> allow_remote_access_connections = policies.FindBool(
+  std::optional<bool> allow_remote_access_connections = policies.FindBool(
       policy::key::kRemoteAccessHostAllowRemoteAccessConnections);
   if (!allow_remote_access_connections.has_value()) {
     return false;
@@ -1810,7 +1810,7 @@
   } else if (desktop_environment_options_.clipboard_size().has_value()) {
     // If we've transitioned from having a policy value to no value then make
     // sure the value stored in desktop_environment_options has been cleared.
-    desktop_environment_options_.set_clipboard_size(absl::optional<size_t>());
+    desktop_environment_options_.set_clipboard_size(std::optional<size_t>());
   }
 
   host_ = std::make_unique<ChromotingHost>(
diff --git a/remoting/host/remoting_register_support_host_request.cc b/remoting/host/remoting_register_support_host_request.cc
index e23fa73..6283061 100644
--- a/remoting/host/remoting_register_support_host_request.cc
+++ b/remoting/host/remoting_register_support_host_request.cc
@@ -158,7 +158,7 @@
     SignalStrategy* signal_strategy,
     scoped_refptr<RsaKeyPair> key_pair,
     const std::string& authorized_helper,
-    absl::optional<ChromeOsEnterpriseParams> params,
+    std::optional<ChromeOsEnterpriseParams> params,
     RegisterCallback callback) {
   DCHECK_EQ(State::NOT_STARTED, state_);
   DCHECK(signal_strategy);
diff --git a/remoting/host/remoting_register_support_host_request.h b/remoting/host/remoting_register_support_host_request.h
index 835f6b0..e22af08 100644
--- a/remoting/host/remoting_register_support_host_request.h
+++ b/remoting/host/remoting_register_support_host_request.h
@@ -5,13 +5,13 @@
 #ifndef REMOTING_HOST_REMOTING_REGISTER_SUPPORT_HOST_REQUEST_H_
 #define REMOTING_HOST_REMOTING_REGISTER_SUPPORT_HOST_REQUEST_H_
 
+#include <optional>
 #include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
 #include "remoting/host/chromeos/chromeos_enterprise_params.h"
 #include "remoting/host/register_support_host_request.h"
 #include "remoting/signaling/signal_strategy.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace network {
 class SharedURLLoaderFactory;
@@ -52,7 +52,7 @@
   void StartRequest(SignalStrategy* signal_strategy,
                     scoped_refptr<RsaKeyPair> key_pair,
                     const std::string& authorized_helper,
-                    absl::optional<ChromeOsEnterpriseParams> params,
+                    std::optional<ChromeOsEnterpriseParams> params,
                     RegisterCallback callback) override;
 
  private:
@@ -98,7 +98,7 @@
   RegisterCallback callback_;
   std::unique_ptr<OAuthTokenGetter> token_getter_;
   std::unique_ptr<RegisterSupportHostClient> register_host_client_;
-  absl::optional<ChromeOsEnterpriseParams> enterprise_params_;
+  std::optional<ChromeOsEnterpriseParams> enterprise_params_;
   std::string authorized_helper_;
 
   State state_ = State::NOT_STARTED;
diff --git a/remoting/host/remoting_register_support_host_request_unittest.cc b/remoting/host/remoting_register_support_host_request_unittest.cc
index b6d9bcf..655f23f 100644
--- a/remoting/host/remoting_register_support_host_request_unittest.cc
+++ b/remoting/host/remoting_register_support_host_request_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "remoting/host/remoting_register_support_host_request.h"
 
+#include <optional>
 #include "base/memory/raw_ptr.h"
 #include "base/test/mock_callback.h"
 #include "base/test/task_environment.h"
@@ -17,7 +18,6 @@
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -153,7 +153,7 @@
       .Times(1);
 
   register_host_request_->StartRequest(signal_strategy_.get(), key_pair_,
-                                       authorized_helper_, absl::nullopt,
+                                       authorized_helper_, std::nullopt,
                                        register_callback.Get());
   signal_strategy_->Connect();
 }
@@ -211,7 +211,7 @@
   authorized_helper_ = kTestAuthorizedHelper;
 
   register_host_request_->StartRequest(signal_strategy_.get(), key_pair_,
-                                       authorized_helper_, absl::nullopt,
+                                       authorized_helper_, std::nullopt,
                                        register_callback.Get());
   signal_strategy_->Connect();
 }
@@ -236,7 +236,7 @@
       .Times(1);
 
   register_host_request_->StartRequest(signal_strategy_.get(), key_pair_,
-                                       authorized_helper_, absl::nullopt,
+                                       authorized_helper_, std::nullopt,
                                        register_callback.Get());
   signal_strategy_->Connect();
 }
@@ -260,7 +260,7 @@
       .Times(1);
 
   register_host_request_->StartRequest(signal_strategy_.get(), key_pair_,
-                                       authorized_helper_, absl::nullopt,
+                                       authorized_helper_, std::nullopt,
                                        register_callback.Get());
   signal_strategy_->Connect();
   signal_strategy_->Disconnect();
diff --git a/remoting/host/resizing_host_observer.cc b/remoting/host/resizing_host_observer.cc
index a11cdf5..309b8f0 100644
--- a/remoting/host/resizing_host_observer.cc
+++ b/remoting/host/resizing_host_observer.cc
@@ -144,7 +144,7 @@
 
 void ResizingHostObserver::SetScreenResolution(
     const ScreenResolution& resolution,
-    absl::optional<webrtc::ScreenId> opt_screen_id) {
+    std::optional<webrtc::ScreenId> opt_screen_id) {
   // Get the current time. This function is called exactly once for each call
   // to SetScreenResolution to simplify the implementation of unit-tests.
   base::TimeTicks now = clock_->NowTicks();
@@ -302,7 +302,7 @@
   // If there was a pending resolution request for an unspecifed monitor, apply
   // it now.
   if (!pending_resolution_request_.IsEmpty()) {
-    SetScreenResolution(pending_resolution_request_, absl::nullopt);
+    SetScreenResolution(pending_resolution_request_, std::nullopt);
     pending_resolution_request_ = {};
   }
 }
diff --git a/remoting/host/resizing_host_observer.h b/remoting/host/resizing_host_observer.h
index 33066bc..db02bbb 100644
--- a/remoting/host/resizing_host_observer.h
+++ b/remoting/host/resizing_host_observer.h
@@ -48,7 +48,7 @@
 
   // ScreenControls interface.
   void SetScreenResolution(const ScreenResolution& resolution,
-                           absl::optional<webrtc::ScreenId> screen_id) override;
+                           std::optional<webrtc::ScreenId> screen_id) override;
   void SetVideoLayout(const protocol::VideoLayout& video_layout) override;
 
   // Allows tests to provide display-info updates.
diff --git a/remoting/host/resizing_host_observer_unittest.cc b/remoting/host/resizing_host_observer_unittest.cc
index 922cd506..159a062 100644
--- a/remoting/host/resizing_host_observer_unittest.cc
+++ b/remoting/host/resizing_host_observer_unittest.cc
@@ -157,7 +157,7 @@
   }
 
   void SetScreenResolution(const ScreenResolution& client_size) {
-    resizing_host_observer_->SetScreenResolution(client_size, absl::nullopt);
+    resizing_host_observer_->SetScreenResolution(client_size, std::nullopt);
     if (auto_advance_clock_) {
       clock_.Advance(base::Seconds(1));
     }
diff --git a/remoting/host/security_key/security_key_extension_session.cc b/remoting/host/security_key/security_key_extension_session.cc
index 24bba7c..6fd2c30 100644
--- a/remoting/host/security_key/security_key_extension_session.cc
+++ b/remoting/host/security_key/security_key_extension_session.cc
@@ -95,7 +95,7 @@
     return false;
   }
 
-  absl::optional<base::Value> value = base::JSONReader::Read(message.data());
+  std::optional<base::Value> value = base::JSONReader::Read(message.data());
   if (!value || !value->is_dict()) {
     LOG(WARNING) << "Failed to retrieve data from gnubby-auth message.";
     return true;
@@ -145,7 +145,7 @@
 
 void SecurityKeyExtensionSession::ProcessDataMessage(
     const base::Value::Dict& message_data) const {
-  absl::optional<int> connection_id_opt = message_data.FindInt(kConnectionId);
+  std::optional<int> connection_id_opt = message_data.FindInt(kConnectionId);
   if (!connection_id_opt.has_value()) {
     LOG(WARNING) << "Could not extract connection id from message.";
     return;
@@ -173,7 +173,7 @@
 
 void SecurityKeyExtensionSession::ProcessErrorMessage(
     const base::Value::Dict& message_data) const {
-  absl::optional<int> connection_id_opt = message_data.FindInt(kConnectionId);
+  std::optional<int> connection_id_opt = message_data.FindInt(kConnectionId);
   if (!connection_id_opt.has_value()) {
     LOG(WARNING) << "Could not extract connection id from message.";
     return;
diff --git a/remoting/host/setup/corp_host_starter.cc b/remoting/host/setup/corp_host_starter.cc
index f70b3ed..1adea603 100644
--- a/remoting/host/setup/corp_host_starter.cc
+++ b/remoting/host/setup/corp_host_starter.cc
@@ -73,7 +73,7 @@
  private:
   void StartHostProcess();
 
-  void OnExistingConfigLoaded(absl::optional<base::Value::Dict> config);
+  void OnExistingConfigLoaded(std::optional<base::Value::Dict> config);
 
   void OnProvisionCorpMachineResponse(
       const ProtobufHttpStatus& status,
@@ -136,8 +136,8 @@
 }
 
 void CorpHostStarter::OnExistingConfigLoaded(
-    absl::optional<base::Value::Dict> config) {
-  absl::optional<std::string> existing_host_id;
+    std::optional<base::Value::Dict> config) {
+  std::optional<std::string> existing_host_id;
   if (config.has_value()) {
     std::string* host_id = config->FindString("host_id");
     if (host_id) {
diff --git a/remoting/host/setup/daemon_controller.cc b/remoting/host/setup/daemon_controller.cc
index 69c69cb5..898395c2 100644
--- a/remoting/host/setup/daemon_controller.cc
+++ b/remoting/host/setup/daemon_controller.cc
@@ -118,7 +118,7 @@
 void DaemonController::DoGetConfig(GetConfigCallback done) {
   DCHECK(delegate_task_runner_->BelongsToCurrentThread());
 
-  absl::optional<base::Value::Dict> config = delegate_->GetConfig();
+  std::optional<base::Value::Dict> config = delegate_->GetConfig();
   caller_task_runner_->PostTask(
       FROM_HERE, base::BindOnce(std::move(done), std::move(config)));
 }
@@ -171,7 +171,7 @@
 
 void DaemonController::InvokeConfigCallbackAndScheduleNext(
     GetConfigCallback done,
-    absl::optional<base::Value::Dict> config) {
+    std::optional<base::Value::Dict> config) {
   DCHECK(caller_task_runner_->BelongsToCurrentThread());
 
   std::move(done).Run(std::move(config));
diff --git a/remoting/host/setup/daemon_controller.h b/remoting/host/setup/daemon_controller.h
index 086fb40..b3048b4 100644
--- a/remoting/host/setup/daemon_controller.h
+++ b/remoting/host/setup/daemon_controller.h
@@ -8,11 +8,11 @@
 #include <memory>
 #include <string>
 
+#include <optional>
 #include "base/containers/queue.h"
 #include "base/functional/callback.h"
 #include "base/memory/ref_counted.h"
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class SingleThreadTaskRunner;
@@ -66,7 +66,7 @@
   // is returned containing host_id and service_account, with security-sensitive
   // fields filtered out. An empty dictionary is returned if the host is not
   // configured, and nullptr if the configuration is corrupt or cannot be read.
-  typedef base::OnceCallback<void(absl::optional<base::Value::Dict> config)>
+  typedef base::OnceCallback<void(std::optional<base::Value::Dict> config)>
       GetConfigCallback;
 
   // Callback used for asynchronous operations, e.g. when
@@ -110,7 +110,7 @@
 
     // Queries current host configuration. Any values that might be security
     // sensitive have been filtered out.
-    virtual absl::optional<base::Value::Dict> GetConfig() = 0;
+    virtual std::optional<base::Value::Dict> GetConfig() = 0;
 
     // Checks to verify that the required OS permissions have been granted to
     // the host process, querying the user if necessary. Notifies the callback
@@ -218,7 +218,7 @@
                                                AsyncResult result);
   void InvokeConfigCallbackAndScheduleNext(
       GetConfigCallback done,
-      absl::optional<base::Value::Dict> config);
+      std::optional<base::Value::Dict> config);
   void InvokeConsentCallbackAndScheduleNext(GetUsageStatsConsentCallback done,
                                             const UsageStatsConsent& consent);
 
diff --git a/remoting/host/setup/daemon_controller_delegate_linux.cc b/remoting/host/setup/daemon_controller_delegate_linux.cc
index 5ff1dc19..28fae20 100644
--- a/remoting/host/setup/daemon_controller_delegate_linux.cc
+++ b/remoting/host/setup/daemon_controller_delegate_linux.cc
@@ -7,6 +7,7 @@
 #include <unistd.h>
 #include <utility>
 
+#include <optional>
 #include "base/command_line.h"
 #include "base/compiler_specific.h"
 #include "base/environment.h"
@@ -27,7 +28,6 @@
 #include "remoting/base/file_path_util_linux.h"
 #include "remoting/host/host_config.h"
 #include "remoting/host/usage_stats_consent.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -144,11 +144,11 @@
   }
 }
 
-absl::optional<base::Value::Dict> DaemonControllerDelegateLinux::GetConfig() {
-  absl::optional<base::Value::Dict> host_config(
+std::optional<base::Value::Dict> DaemonControllerDelegateLinux::GetConfig() {
+  std::optional<base::Value::Dict> host_config(
       HostConfigFromJsonFile(GetConfigPath()));
   if (!host_config.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   base::Value::Dict result;
@@ -218,7 +218,7 @@
 void DaemonControllerDelegateLinux::UpdateConfig(
     base::Value::Dict config,
     DaemonController::CompletionCallback done) {
-  absl::optional<base::Value::Dict> new_config(
+  std::optional<base::Value::Dict> new_config(
       HostConfigFromJsonFile(GetConfigPath()));
   if (!new_config.has_value()) {
     LOG(ERROR) << "Failed to read existing config file.";
diff --git a/remoting/host/setup/daemon_controller_delegate_linux.h b/remoting/host/setup/daemon_controller_delegate_linux.h
index c099505..3e472e3 100644
--- a/remoting/host/setup/daemon_controller_delegate_linux.h
+++ b/remoting/host/setup/daemon_controller_delegate_linux.h
@@ -23,7 +23,7 @@
 
   // DaemonController::Delegate interface.
   DaemonController::State GetState() override;
-  absl::optional<base::Value::Dict> GetConfig() override;
+  std::optional<base::Value::Dict> GetConfig() override;
   void CheckPermission(bool it2me, DaemonController::BoolCallback) override;
   void SetConfigAndStart(base::Value::Dict config,
                          bool consent,
diff --git a/remoting/host/setup/daemon_controller_delegate_mac.h b/remoting/host/setup/daemon_controller_delegate_mac.h
index bcfde6f..c2b1480 100644
--- a/remoting/host/setup/daemon_controller_delegate_mac.h
+++ b/remoting/host/setup/daemon_controller_delegate_mac.h
@@ -30,7 +30,7 @@
 
   // DaemonController::Delegate interface.
   DaemonController::State GetState() override;
-  absl::optional<base::Value::Dict> GetConfig() override;
+  std::optional<base::Value::Dict> GetConfig() override;
   void CheckPermission(bool it2me, DaemonController::BoolCallback) override;
   void SetConfigAndStart(base::Value::Dict config,
                          bool consent,
diff --git a/remoting/host/setup/daemon_controller_delegate_mac.mm b/remoting/host/setup/daemon_controller_delegate_mac.mm
index 0b8e02a6..3fdc9d90 100644
--- a/remoting/host/setup/daemon_controller_delegate_mac.mm
+++ b/remoting/host/setup/daemon_controller_delegate_mac.mm
@@ -8,6 +8,7 @@
 #include <sys/types.h>
 #include <utility>
 
+#include <optional>
 #include "base/apple/bridging.h"
 #include "base/apple/foundation_util.h"
 #include "base/apple/osstatus_logging.h"
@@ -32,7 +33,6 @@
 #include "remoting/host/mac/permission_checker.h"
 #include "remoting/host/mac/permission_wizard.h"
 #include "remoting/host/resources.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 
@@ -236,11 +236,11 @@
   }
 }
 
-absl::optional<base::Value::Dict> DaemonControllerDelegateMac::GetConfig() {
+std::optional<base::Value::Dict> DaemonControllerDelegateMac::GetConfig() {
   base::FilePath config_path(kHostConfigFilePath);
   auto host_config = HostConfigFromJsonFile(config_path);
   if (!host_config.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   base::Value::Dict config;
@@ -282,7 +282,7 @@
     base::Value::Dict config,
     DaemonController::CompletionCallback done) {
   base::FilePath config_file_path(kHostConfigFilePath);
-  absl::optional<base::Value::Dict> host_config(
+  std::optional<base::Value::Dict> host_config(
       HostConfigFromJsonFile(config_file_path));
   if (!host_config.has_value()) {
     std::move(done).Run(DaemonController::RESULT_FAILED);
@@ -307,10 +307,10 @@
   consent.set_by_policy = false;
 
   base::FilePath config_file_path(kHostConfigFilePath);
-  absl::optional<base::Value::Dict> host_config(
+  std::optional<base::Value::Dict> host_config(
       HostConfigFromJsonFile(config_file_path));
   if (host_config.has_value()) {
-    absl::optional<bool> host_config_value =
+    std::optional<bool> host_config_value =
         host_config->FindBool(kUsageStatsConsentConfigPath);
     if (host_config_value.has_value()) {
       consent.allowed = host_config_value.value();
diff --git a/remoting/host/setup/daemon_controller_delegate_win.cc b/remoting/host/setup/daemon_controller_delegate_win.cc
index b7dcbfb..2dcc98f 100644
--- a/remoting/host/setup/daemon_controller_delegate_win.cc
+++ b/remoting/host/setup/daemon_controller_delegate_win.cc
@@ -83,7 +83,7 @@
     return false;
   }
 
-  absl::optional<base::Value::Dict> config = HostConfigFromJson(file_content);
+  std::optional<base::Value::Dict> config = HostConfigFromJson(file_content);
   if (!config.has_value()) {
     LOG(ERROR) << "Config file: '" << filename.value() << "' is empty.";
     return false;
@@ -351,13 +351,13 @@
   return ConvertToDaemonState(status.dwCurrentState);
 }
 
-absl::optional<base::Value::Dict> DaemonControllerDelegateWin::GetConfig() {
+std::optional<base::Value::Dict> DaemonControllerDelegateWin::GetConfig() {
   base::FilePath config_dir = remoting::GetConfigDir();
 
   // Read the unprivileged part of host configuration.
   base::Value::Dict config;
   if (!ReadConfig(config_dir.Append(kUnprivilegedConfigFileName), config)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return config;
diff --git a/remoting/host/setup/daemon_controller_delegate_win.h b/remoting/host/setup/daemon_controller_delegate_win.h
index aef2291..825d958 100644
--- a/remoting/host/setup/daemon_controller_delegate_win.h
+++ b/remoting/host/setup/daemon_controller_delegate_win.h
@@ -21,7 +21,7 @@
 
   // DaemonController::Delegate interface.
   DaemonController::State GetState() override;
-  absl::optional<base::Value::Dict> GetConfig() override;
+  std::optional<base::Value::Dict> GetConfig() override;
   void CheckPermission(bool it2me, DaemonController::BoolCallback) override;
   void SetConfigAndStart(base::Value::Dict config,
                          bool consent,
diff --git a/remoting/host/setup/host_stopper.cc b/remoting/host/setup/host_stopper.cc
index e2d1b297..a233bff 100644
--- a/remoting/host/setup/host_stopper.cc
+++ b/remoting/host/setup/host_stopper.cc
@@ -27,7 +27,7 @@
       base::BindOnce(&HostStopper::OnConfigLoaded, weak_ptr_));
 }
 
-void HostStopper::OnConfigLoaded(absl::optional<base::Value::Dict> config) {
+void HostStopper::OnConfigLoaded(std::optional<base::Value::Dict> config) {
   const std::string* hostId = nullptr;
   if (!config || !(hostId = config->FindString("host_id"))) {
     std::move(on_done_).Run();
diff --git a/remoting/host/setup/host_stopper.h b/remoting/host/setup/host_stopper.h
index dc54107..4bae6bd 100644
--- a/remoting/host/setup/host_stopper.h
+++ b/remoting/host/setup/host_stopper.h
@@ -5,12 +5,12 @@
 #ifndef REMOTING_HOST_SETUP_HOST_STOPPER_H_
 #define REMOTING_HOST_SETUP_HOST_STOPPER_H_
 
+#include <optional>
 #include "base/functional/callback.h"
 #include "base/memory/weak_ptr.h"
 #include "base/values.h"
 #include "remoting/host/setup/daemon_controller.h"
 #include "remoting/host/setup/service_client.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -27,7 +27,7 @@
   void StopLocalHost(std::string access_token, base::OnceClosure on_done);
 
  private:
-  void OnConfigLoaded(absl::optional<base::Value::Dict> config);
+  void OnConfigLoaded(std::optional<base::Value::Dict> config);
   void StopHost();
   void OnStopped(DaemonController::AsyncResult);
 
diff --git a/remoting/host/setup/me2me_native_messaging_host.cc b/remoting/host/setup/me2me_native_messaging_host.cc
index 8f8013a..8b1a6e4 100644
--- a/remoting/host/setup/me2me_native_messaging_host.cc
+++ b/remoting/host/setup/me2me_native_messaging_host.cc
@@ -9,6 +9,7 @@
 #include <string>
 #include <utility>
 
+#include <optional>
 #include "base/command_line.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
@@ -30,7 +31,6 @@
 #include "remoting/host/native_messaging/log_message_handler.h"
 #include "remoting/host/pin_hash.h"
 #include "remoting/protocol/pairing_registry.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_WIN)
 #include "remoting/host/win/elevated_native_messaging_host.h"
@@ -54,12 +54,12 @@
 
 // Helper to extract the "config" part of a message as a base::Value::Dict.
 // Returns nullptr on failure, and logs an error message.
-absl::optional<base::Value::Dict> ConfigDictionaryFromMessage(
+std::optional<base::Value::Dict> ConfigDictionaryFromMessage(
     base::Value::Dict message) {
   if (base::Value::Dict* config_dict = message.FindDict("config")) {
     return std::move(*config_dict);
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace
@@ -92,7 +92,7 @@
   DCHECK(task_runner()->BelongsToCurrentThread());
 
   base::Value::Dict response;
-  absl::optional<base::Value> message_value = base::JSONReader::Read(message);
+  std::optional<base::Value> message_value = base::JSONReader::Read(message);
   if (!message_value || !message_value->is_dict()) {
     OnError("Received a message that's not a dictionary.");
     return;
@@ -293,7 +293,7 @@
     }
   }
 
-  absl::optional<base::Value::Dict> config_dict =
+  std::optional<base::Value::Dict> config_dict =
       ConfigDictionaryFromMessage(std::move(message));
   if (!config_dict) {
     OnError("'config' dictionary not found");
@@ -360,13 +360,13 @@
     }
   }
 
-  absl::optional<bool> consent = message.FindBool("consent");
+  std::optional<bool> consent = message.FindBool("consent");
   if (!consent) {
     OnError("'consent' not found.");
     return;
   }
 
-  absl::optional<base::Value::Dict> config_dict =
+  std::optional<base::Value::Dict> config_dict =
       ConfigDictionaryFromMessage(std::move(message));
   if (!config_dict) {
     OnError("'config' dictionary not found");
@@ -481,7 +481,7 @@
 
 void Me2MeNativeMessagingHost::SendConfigResponse(
     base::Value::Dict response,
-    absl::optional<base::Value::Dict> config) {
+    std::optional<base::Value::Dict> config) {
   DCHECK(task_runner()->BelongsToCurrentThread());
 
   if (config) {
diff --git a/remoting/host/setup/me2me_native_messaging_host.h b/remoting/host/setup/me2me_native_messaging_host.h
index 5f2d5d7..eb44d6df 100644
--- a/remoting/host/setup/me2me_native_messaging_host.h
+++ b/remoting/host/setup/me2me_native_messaging_host.h
@@ -100,7 +100,7 @@
   // These methods fill in the |response| dictionary from the other parameters,
   // and pass it to SendResponse().
   void SendConfigResponse(base::Value::Dict response,
-                          absl::optional<base::Value::Dict> config);
+                          std::optional<base::Value::Dict> config);
   void SendPairedClientsResponse(base::Value::Dict response,
                                  base::Value::List pairings);
   void SendUsageStatsConsentResponse(
diff --git a/remoting/host/setup/me2me_native_messaging_host_unittest.cc b/remoting/host/setup/me2me_native_messaging_host_unittest.cc
index 61d9fc1..417c3ef 100644
--- a/remoting/host/setup/me2me_native_messaging_host_unittest.cc
+++ b/remoting/host/setup/me2me_native_messaging_host_unittest.cc
@@ -11,6 +11,7 @@
 #include <string>
 #include <utility>
 
+#include <optional>
 #include "base/compiler_specific.h"
 #include "base/functional/bind.h"
 #include "base/json/json_reader.h"
@@ -36,7 +37,6 @@
 #include "remoting/protocol/protocol_mock_objects.h"
 #include "services/network/test/test_shared_url_loader_factory.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -171,7 +171,7 @@
 
   // DaemonController::Delegate interface.
   DaemonController::State GetState() override;
-  absl::optional<base::Value::Dict> GetConfig() override;
+  std::optional<base::Value::Dict> GetConfig() override;
   void CheckPermission(bool it2me,
                        DaemonController::BoolCallback callback) override;
   void SetConfigAndStart(base::Value::Dict config,
@@ -191,7 +191,7 @@
   return DaemonController::STATE_STARTED;
 }
 
-absl::optional<base::Value::Dict> MockDaemonControllerDelegate::GetConfig() {
+std::optional<base::Value::Dict> MockDaemonControllerDelegate::GetConfig() {
   return base::Value::Dict();
 }
 
@@ -250,7 +250,7 @@
   void SetUp() override;
   void TearDown() override;
 
-  absl::optional<base::Value::Dict> ReadMessageFromOutputPipe();
+  std::optional<base::Value::Dict> ReadMessageFromOutputPipe();
 
   void WriteMessageToInputPipe(const base::ValueView& message);
 
@@ -409,7 +409,7 @@
   test_run_loop_->Run();
 
   // Verify there are no more message in the output pipe.
-  absl::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
+  std::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
   EXPECT_FALSE(response);
 
   // The It2MeMe2MeNativeMessagingHost dtor closes the handles that are passed
@@ -417,26 +417,26 @@
   output_read_file_.Close();
 }
 
-absl::optional<base::Value::Dict>
+std::optional<base::Value::Dict>
 Me2MeNativeMessagingHostTest::ReadMessageFromOutputPipe() {
   while (true) {
     uint32_t length;
     int read_result = output_read_file_.ReadAtCurrentPos(
         reinterpret_cast<char*>(&length), sizeof(length));
     if (read_result != sizeof(length)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     std::string message_json(length, '\0');
     read_result =
         output_read_file_.ReadAtCurrentPos(std::data(message_json), length);
     if (read_result != static_cast<int>(length)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
-    absl::optional<base::Value> message = base::JSONReader::Read(message_json);
+    std::optional<base::Value> message = base::JSONReader::Read(message_json);
     if (!message || !message->is_dict()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     base::Value::Dict& result = message->GetDict();
@@ -470,7 +470,7 @@
   WriteMessageToInputPipe(good_message);
 
   // Read from output pipe, and verify responses.
-  absl::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
+  std::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
   ASSERT_TRUE(response);
   VerifyHelloResponse(std::move(*response));
 
@@ -556,11 +556,11 @@
 
   // Read all responses from output pipe, and verify them.
   for (int i = 0; i < next_id; ++i) {
-    absl::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
+    std::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
     ASSERT_TRUE(response);
 
     // Make sure that id is available and is in the range.
-    absl::optional<int> id = response->FindInt("id");
+    std::optional<int> id = response->FindInt("id");
     ASSERT_TRUE(id);
     ASSERT_TRUE(0 <= *id && *id < next_id);
 
@@ -581,7 +581,7 @@
   message.Set("id", "42");
   WriteMessageToInputPipe(message);
 
-  absl::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
+  std::optional<base::Value::Dict> response = ReadMessageFromOutputPipe();
   EXPECT_TRUE(response);
   std::string* value = response->FindString("id");
   EXPECT_FALSE(value);
diff --git a/remoting/host/token_validator_base.cc b/remoting/host/token_validator_base.cc
index a94aa50..eb70427 100644
--- a/remoting/host/token_validator_base.cc
+++ b/remoting/host/token_validator_base.cc
@@ -246,7 +246,7 @@
           ? data_.substr(sizeof(kJsonSafetyPrefix) - 1)
           : data_;
 
-  absl::optional<base::Value> value = base::JSONReader::Read(responseData);
+  std::optional<base::Value> value = base::JSONReader::Read(responseData);
   if (!value || !value->is_dict()) {
     LOG(ERROR) << "Invalid token validation response: '" << data_ << "'";
     return RejectionReason::INVALID_CREDENTIALS;
diff --git a/remoting/host/usage_stats_consent_linux.cc b/remoting/host/usage_stats_consent_linux.cc
index 7fe00c1c..1e9b9033 100644
--- a/remoting/host/usage_stats_consent_linux.cc
+++ b/remoting/host/usage_stats_consent_linux.cc
@@ -7,6 +7,7 @@
 #include <memory>
 #include <string>
 
+#include <optional>
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
@@ -16,7 +17,6 @@
 #include "remoting/base/is_google_email.h"
 #include "remoting/host/config_file_watcher.h"
 #include "remoting/host/host_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -26,7 +26,7 @@
 
   std::string filename = GetHostHash() + ".json";
   base::FilePath config_path = GetConfigDirectoryPath().Append(filename);
-  absl::optional<base::Value::Dict> config(HostConfigFromJsonFile(config_path));
+  std::optional<base::Value::Dict> config(HostConfigFromJsonFile(config_path));
   if (!config.has_value()) {
     LOG(ERROR) << "No host config file found.";
     return false;
diff --git a/remoting/host/usage_stats_consent_mac.cc b/remoting/host/usage_stats_consent_mac.cc
index ce08666..21aea57 100644
--- a/remoting/host/usage_stats_consent_mac.cc
+++ b/remoting/host/usage_stats_consent_mac.cc
@@ -7,13 +7,13 @@
 #include <memory>
 #include <string>
 
+#include <optional>
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/notreached.h"
 #include "base/values.h"
 #include "remoting/host/config_file_watcher.h"
 #include "remoting/host/host_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -28,10 +28,10 @@
   if (command_line->HasSwitch(kHostConfigSwitchName)) {
     base::FilePath config_file_path =
         command_line->GetSwitchValuePath(kHostConfigSwitchName);
-    absl::optional<base::Value::Dict> host_config(
+    std::optional<base::Value::Dict> host_config(
         HostConfigFromJsonFile(config_file_path));
     if (host_config.has_value()) {
-      absl::optional<bool> host_config_value =
+      std::optional<bool> host_config_value =
           host_config->FindBool(kUsageStatsConsentConfigPath);
       if (host_config_value.has_value()) {
         allowed = host_config_value.value();
diff --git a/remoting/host/webauthn/remote_webauthn_native_messaging_host.cc b/remoting/host/webauthn/remote_webauthn_native_messaging_host.cc
index 1c1e7e41..4f84a4d 100644
--- a/remoting/host/webauthn/remote_webauthn_native_messaging_host.cc
+++ b/remoting/host/webauthn/remote_webauthn_native_messaging_host.cc
@@ -83,7 +83,7 @@
     return;
   }
 
-  absl::optional<base::Value::Dict> response =
+  std::optional<base::Value::Dict> response =
       CreateNativeMessageResponse(request);
   if (!response.has_value()) {
     return;
diff --git a/remoting/host/win/simple_task_dialog.cc b/remoting/host/win/simple_task_dialog.cc
index f4bb0425..24262fa 100644
--- a/remoting/host/win/simple_task_dialog.cc
+++ b/remoting/host/win/simple_task_dialog.cc
@@ -70,7 +70,7 @@
   return true;
 }
 
-absl::optional<int> SimpleTaskDialog::Show() {
+std::optional<int> SimpleTaskDialog::Show() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   std::vector<TASKDIALOG_BUTTON> taskdialog_buttons;
@@ -104,7 +104,7 @@
       LOG(ERROR) << "TaskDialogIndirect() Failed: 0x" << std::hex << hr;
     }
 
-    return absl::nullopt;
+    return std::nullopt;
   }
   return button_result;
 }
diff --git a/remoting/host/win/simple_task_dialog.h b/remoting/host/win/simple_task_dialog.h
index 01387e8..32aedf3 100644
--- a/remoting/host/win/simple_task_dialog.h
+++ b/remoting/host/win/simple_task_dialog.h
@@ -13,10 +13,10 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/sequence_checker.h"
 #include "base/thread_annotations.h"
 #include "base/time/time.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -62,7 +62,7 @@
 
   // Shows the dialog and returns the ID of the button that the user clicked.
   // Returns nullopt if the dialog fails to show or times out.
-  absl::optional<int> Show();
+  std::optional<int> Show();
 
   SimpleTaskDialog(const SimpleTaskDialog&) = delete;
   SimpleTaskDialog& operator=(const SimpleTaskDialog&) = delete;
diff --git a/remoting/host/win/unprivileged_process_delegate.cc b/remoting/host/win/unprivileged_process_delegate.cc
index 7be275b..8db2d793 100644
--- a/remoting/host/win/unprivileged_process_delegate.cc
+++ b/remoting/host/win/unprivileged_process_delegate.cc
@@ -14,6 +14,7 @@
 #include <string>
 #include <utility>
 
+#include <optional>
 #include "base/command_line.h"
 #include "base/files/file.h"
 #include "base/logging.h"
@@ -36,7 +37,6 @@
 #include "remoting/host/win/launch_process_with_token.h"
 #include "remoting/host/win/security_descriptor.h"
 #include "remoting/host/win/window_station_and_desktop.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using base::win::ScopedHandle;
 using base::win::Sid;
@@ -107,7 +107,7 @@
   }
 
   ScopedHandle restricted_token(temp_handle);
-  absl::optional<Sid> sid = Sid::FromIntegrityLevel(SECURITY_MANDATORY_LOW_RID);
+  std::optional<Sid> sid = Sid::FromIntegrityLevel(SECURITY_MANDATORY_LOW_RID);
   if (!sid) {
     LOG(ERROR) << "Failed to get integrity level SID";
     return false;
diff --git a/remoting/host/xmpp_register_support_host_request.cc b/remoting/host/xmpp_register_support_host_request.cc
index 9ca135f..76aff317 100644
--- a/remoting/host/xmpp_register_support_host_request.cc
+++ b/remoting/host/xmpp_register_support_host_request.cc
@@ -66,7 +66,7 @@
     SignalStrategy* signal_strategy,
     scoped_refptr<RsaKeyPair> key_pair,
     const std::string& authorized_helper,
-    absl::optional<ChromeOsEnterpriseParams> params,
+    std::optional<ChromeOsEnterpriseParams> params,
     RegisterCallback callback) {
   DCHECK(signal_strategy);
   DCHECK(key_pair.get());
diff --git a/remoting/host/xmpp_register_support_host_request.h b/remoting/host/xmpp_register_support_host_request.h
index cdc7b1b..f604098 100644
--- a/remoting/host/xmpp_register_support_host_request.h
+++ b/remoting/host/xmpp_register_support_host_request.h
@@ -53,7 +53,7 @@
   void StartRequest(SignalStrategy* signal_strategy,
                     scoped_refptr<RsaKeyPair> key_pair,
                     const std::string& authorized_helper,
-                    absl::optional<ChromeOsEnterpriseParams> params,
+                    std::optional<ChromeOsEnterpriseParams> params,
                     RegisterCallback callback) override;
 
   // HostStatusObserver implementation.
diff --git a/remoting/host/xmpp_register_support_host_request_unittest.cc b/remoting/host/xmpp_register_support_host_request_unittest.cc
index db82fc391..6c8e22a5c 100644
--- a/remoting/host/xmpp_register_support_host_request_unittest.cc
+++ b/remoting/host/xmpp_register_support_host_request_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include "base/functional/bind.h"
 #include "base/memory/ref_counted.h"
 #include "base/observer_list.h"
@@ -24,7 +25,6 @@
 #include "remoting/signaling/xmpp_constants.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
 
 using jingle_xmpp::QName;
@@ -88,7 +88,7 @@
 TEST_F(XmppRegisterSupportHostRequestTest, Timeout) {
   auto request = std::make_unique<XmppRegisterSupportHostRequest>(kTestBotJid);
   request->StartRequest(&signal_strategy_, key_pair_, authorized_helper_,
-                        absl::nullopt, callback_.Get());
+                        std::nullopt, callback_.Get());
   EXPECT_CALL(signal_strategy_, GetNextId()).WillOnce(Return(kStanzaId));
   EXPECT_CALL(signal_strategy_, SendStanzaPtr(NotNull()))
       .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
@@ -109,7 +109,7 @@
 
   auto request = std::make_unique<XmppRegisterSupportHostRequest>(kTestBotJid);
   request->StartRequest(&signal_strategy_, key_pair_, authorized_helper_,
-                        absl::nullopt, callback_.Get());
+                        std::nullopt, callback_.Get());
 
   XmlElement* sent_iq = nullptr;
   EXPECT_CALL(signal_strategy_, GetNextId()).WillOnce(Return(kStanzaId));
@@ -205,7 +205,7 @@
 
   auto request = std::make_unique<XmppRegisterSupportHostRequest>(kTestBotJid);
   request->StartRequest(&signal_strategy_, key_pair_, authorized_helper_,
-                        absl::nullopt, callback_.Get());
+                        std::nullopt, callback_.Get());
 
   XmlElement* sent_iq = nullptr;
   EXPECT_CALL(signal_strategy_, GetNextId()).WillOnce(Return(kStanzaId));
diff --git a/remoting/host/xsession_chooser_linux.cc b/remoting/host/xsession_chooser_linux.cc
index 7a23bb7..a80302b0 100644
--- a/remoting/host/xsession_chooser_linux.cc
+++ b/remoting/host/xsession_chooser_linux.cc
@@ -20,6 +20,7 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/environment.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_path.h"
@@ -36,7 +37,6 @@
 #include "base/task/single_thread_task_executor.h"
 #include "remoting/base/logging.h"
 #include "remoting/base/string_resources.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/icu/source/common/unicode/unistr.h"
 #include "third_party/icu/source/i18n/unicode/coll.h"
 #include "ui/base/glib/scoped_gobject.h"
@@ -170,7 +170,7 @@
   return true;
 }
 
-absl::optional<XSession> TryLoadSession(base::FilePath path) {
+std::optional<XSession> TryLoadSession(base::FilePath path) {
   std::unique_ptr<GKeyFile, void (*)(GKeyFile*)> key_file(g_key_file_new(),
                                                           &g_key_file_free);
   GError* error;
@@ -179,14 +179,14 @@
                                  G_KEY_FILE_NONE, &error)) {
     LOG(WARNING) << "Failed to load " << path << ": " << error->message;
     g_error_free(error);
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Files without a "Desktop Entry" group can be ignored. (An empty file can be
   // put in a higher-priority directory to hide entries from a lower-priority
   // directory.)
   if (!g_key_file_has_group(key_file.get(), G_KEY_FILE_DESKTOP_GROUP)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Files with "NoDisplay" or "Hidden" set should be ignored.
@@ -194,7 +194,7 @@
        {G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, G_KEY_FILE_DESKTOP_KEY_HIDDEN}) {
     if (g_key_file_get_boolean(key_file.get(), G_KEY_FILE_DESKTOP_GROUP, key,
                                nullptr)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
 
@@ -213,7 +213,7 @@
             : !base::ExecutableExistsInPath(base::Environment::Create().get(),
                                             try_exec_path.value())) {
       LOG(INFO) << "Rejecting " << path << " due to TryExec=" << try_exec_path;
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
 
@@ -227,7 +227,7 @@
   } else {
     LOG(WARNING) << "Failed to load value of " << G_KEY_FILE_DESKTOP_KEY_NAME
                  << " from " << path;
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (gchar* exec =
@@ -238,7 +238,7 @@
   } else {
     LOG(WARNING) << "Failed to load value of " << G_KEY_FILE_DESKTOP_KEY_EXEC
                  << " from " << path;
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Optional fields.
@@ -300,7 +300,7 @@
        "default"});
 
   for (const auto& session : session_files) {
-    absl::optional<XSession> loaded_session = TryLoadSession(session.second);
+    std::optional<XSession> loaded_session = TryLoadSession(session.second);
     if (loaded_session) {
       sessions.push_back(std::move(*loaded_session));
     }
diff --git a/remoting/ios/app/notification_presenter.h b/remoting/ios/app/notification_presenter.h
index a7f4911..8928ba2 100644
--- a/remoting/ios/app/notification_presenter.h
+++ b/remoting/ios/app/notification_presenter.h
@@ -7,13 +7,13 @@
 
 #import <Foundation/Foundation.h>
 
+#include <optional>
 #include "base/no_destructor.h"
 #include "base/sequence_checker.h"
 #include "base/threading/sequence_bound.h"
 #include "base/timer/timer.h"
 #include "remoting/client/notification/notification_client.h"
 #include "remoting/client/notification/notification_message.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting {
 
@@ -42,7 +42,7 @@
   ~NotificationPresenter() = delete;
 
   void FetchNotification();
-  void OnNotificationFetched(absl::optional<NotificationMessage> notification);
+  void OnNotificationFetched(std::optional<NotificationMessage> notification);
 
   NotificationClient notification_client_;
 
diff --git a/remoting/ios/app/notification_presenter.mm b/remoting/ios/app/notification_presenter.mm
index ff7da35..0be8e67 100644
--- a/remoting/ios/app/notification_presenter.mm
+++ b/remoting/ios/app/notification_presenter.mm
@@ -105,7 +105,7 @@
 }
 
 void NotificationPresenter::OnNotificationFetched(
-    absl::optional<NotificationMessage> notification) {
+    std::optional<NotificationMessage> notification) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK_EQ(State::FETCHING, state_);
 
diff --git a/remoting/proto/internal_stubs.cc b/remoting/proto/internal_stubs.cc
index 1b90a425..d12a9f6 100644
--- a/remoting/proto/internal_stubs.cc
+++ b/remoting/proto/internal_stubs.cc
@@ -37,7 +37,7 @@
     const std::string& owner_email,
     const std::string& fqdn,
     const std::string& public_key,
-    absl::optional<std::string> existing_host_id) {
+    std::optional<std::string> existing_host_id) {
   return std::make_unique<RemoteAccessHostV1Proto>();
 }
 
diff --git a/remoting/proto/internal_stubs.h b/remoting/proto/internal_stubs.h
index eaffd5e..36dba4af 100644
--- a/remoting/proto/internal_stubs.h
+++ b/remoting/proto/internal_stubs.h
@@ -8,7 +8,7 @@
 #include <memory>
 #include <string>
 
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include <optional>
 #include "third_party/protobuf/src/google/protobuf/message_lite.h"
 
 // This file defines proto and function stubs for internal-only implementations.
@@ -48,7 +48,7 @@
     const std::string& owner_email,
     const std::string& fqdn,
     const std::string& public_key,
-    absl::optional<std::string> existing_host_id);
+    std::optional<std::string> existing_host_id);
 
 extern std::string GetReportProvisioningErrorRequestPath();
 extern std::unique_ptr<ReportProvisioningErrorRequest>
diff --git a/remoting/protocol/clipboard_filter.h b/remoting/protocol/clipboard_filter.h
index a2ebe82..829a462 100644
--- a/remoting/protocol/clipboard_filter.h
+++ b/remoting/protocol/clipboard_filter.h
@@ -5,10 +5,10 @@
 #ifndef REMOTING_PROTOCOL_CLIPBOARD_FILTER_H_
 #define REMOTING_PROTOCOL_CLIPBOARD_FILTER_H_
 
+#include <optional>
 #include "base/compiler_specific.h"
 #include "base/memory/raw_ptr.h"
 #include "remoting/protocol/clipboard_stub.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting::protocol {
 
@@ -42,7 +42,7 @@
  private:
   raw_ptr<ClipboardStub, DanglingUntriaged> clipboard_stub_ = nullptr;
   bool enabled_ = true;
-  absl::optional<size_t> max_size_;
+  std::optional<size_t> max_size_;
 };
 
 }  // namespace remoting::protocol
diff --git a/remoting/protocol/fake_stream_socket.h b/remoting/protocol/fake_stream_socket.h
index 1e90660..b8004f06 100644
--- a/remoting/protocol/fake_stream_socket.h
+++ b/remoting/protocol/fake_stream_socket.h
@@ -9,11 +9,11 @@
 #include <memory>
 #include <string>
 
+#include <optional>
 #include "base/memory/weak_ptr.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "remoting/protocol/p2p_stream_socket.h"
 #include "remoting/protocol/stream_channel_factory.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class SingleThreadTaskRunner;
@@ -93,7 +93,7 @@
   int write_limit_ = 0;
   int next_write_error_ = 0;
 
-  absl::optional<int> next_read_error_;
+  std::optional<int> next_read_error_;
   scoped_refptr<net::IOBuffer> read_buffer_;
   int read_buffer_size_ = 0;
   net::CompletionOnceCallback read_callback_;
diff --git a/remoting/protocol/file_transfer_helpers.cc b/remoting/protocol/file_transfer_helpers.cc
index 026e058e..1d5cec7b 100644
--- a/remoting/protocol/file_transfer_helpers.cc
+++ b/remoting/protocol/file_transfer_helpers.cc
@@ -9,7 +9,7 @@
 FileTransfer_Error MakeFileTransferError(
     base::Location location,
     FileTransfer_Error_Type type,
-    absl::optional<int32_t> api_error_code) {
+    std::optional<int32_t> api_error_code) {
   FileTransfer_Error error;
   error.set_type(type);
   if (api_error_code) {
diff --git a/remoting/protocol/file_transfer_helpers.h b/remoting/protocol/file_transfer_helpers.h
index fb7c19e5..1063a2e 100644
--- a/remoting/protocol/file_transfer_helpers.h
+++ b/remoting/protocol/file_transfer_helpers.h
@@ -8,10 +8,10 @@
 #include <cstdint>
 #include <ostream>
 
+#include <optional>
 #include "base/location.h"
 #include "remoting/base/result.h"
 #include "remoting/proto/file_transfer.pb.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace remoting::protocol {
 
@@ -21,7 +21,7 @@
 FileTransfer_Error MakeFileTransferError(
     base::Location location,
     FileTransfer_Error_Type type,
-    absl::optional<std::int32_t> api_error_code = absl::nullopt);
+    std::optional<std::int32_t> api_error_code = std::nullopt);
 
 std::ostream& operator<<(std::ostream& stream, const FileTransfer_Error& error);
 
diff --git a/remoting/protocol/ice_config.cc b/remoting/protocol/ice_config.cc
index 766e5e7..6c56405 100644
--- a/remoting/protocol/ice_config.cc
+++ b/remoting/protocol/ice_config.cc
@@ -212,7 +212,7 @@
 
 // static
 IceConfig IceConfig::Parse(const std::string& config_json) {
-  absl::optional<base::Value> json = base::JSONReader::Read(config_json);
+  std::optional<base::Value> json = base::JSONReader::Read(config_json);
   if (!json) {
     return IceConfig();
   }
diff --git a/remoting/protocol/pairing_registry.cc b/remoting/protocol/pairing_registry.cc
index caa9a7b..462fa70 100644
--- a/remoting/protocol/pairing_registry.cc
+++ b/remoting/protocol/pairing_registry.cc
@@ -58,7 +58,7 @@
 
 PairingRegistry::Pairing PairingRegistry::Pairing::CreateFromValue(
     const base::Value::Dict& pairing) {
-  absl::optional<double> created_time_value =
+  std::optional<double> created_time_value =
       pairing.FindDouble(kCreatedTimeKey);
   const std::string* client_name = pairing.FindString(kClientNameKey);
   const std::string* client_id = pairing.FindString(kClientIdKey);
diff --git a/remoting/protocol/peer_connection_controls.h b/remoting/protocol/peer_connection_controls.h
index 94e3590..ec6e109c 100644
--- a/remoting/protocol/peer_connection_controls.h
+++ b/remoting/protocol/peer_connection_controls.h
@@ -5,7 +5,7 @@
 #ifndef REMOTING_PROTOCOL_PEER_CONNECTION_CONTROLS_H_
 #define REMOTING_PROTOCOL_PEER_CONNECTION_CONTROLS_H_
 
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include <optional>
 
 namespace remoting::protocol {
 
@@ -17,8 +17,8 @@
 
   // Sets preferred min and max bitrates for the peer connection. nullopt means
   // no preference.
-  virtual void SetPreferredBitrates(absl::optional<int> min_bitrate_bps,
-                                    absl::optional<int> max_bitrate_bps) = 0;
+  virtual void SetPreferredBitrates(std::optional<int> min_bitrate_bps,
+                                    std::optional<int> max_bitrate_bps) = 0;
 
   // Performs an ICE restart. This causes the host to initiate a new SDP
   // offer/answer exchange, and restarts the ICE gathering/connection sequence.
diff --git a/remoting/protocol/webrtc_connection_to_client.cc b/remoting/protocol/webrtc_connection_to_client.cc
index 32cd84e..3f633bd 100644
--- a/remoting/protocol/webrtc_connection_to_client.cc
+++ b/remoting/protocol/webrtc_connection_to_client.cc
@@ -208,7 +208,7 @@
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   auto sctp_transport = transport_->peer_connection()->GetSctpTransport();
   if (sctp_transport) {
-    absl::optional<double> max_message_size =
+    std::optional<double> max_message_size =
         sctp_transport->Information().MaxMessageSize();
     if (max_message_size && *max_message_size > 0) {
       control_dispatcher_->set_max_message_size(*max_message_size);
diff --git a/remoting/protocol/webrtc_transport.cc b/remoting/protocol/webrtc_transport.cc
index 16cee7e..2f27815 100644
--- a/remoting/protocol/webrtc_transport.cc
+++ b/remoting/protocol/webrtc_transport.cc
@@ -113,7 +113,7 @@
 }
 
 // Returns true if the selected candidate-pair indicates a relay connection.
-absl::optional<bool> IsConnectionRelayed(
+std::optional<bool> IsConnectionRelayed(
     const cricket::CandidatePair& selected_candidate_pair) {
   const cricket::Candidate& local_candidate =
       selected_candidate_pair.local_candidate();
@@ -620,9 +620,8 @@
   return session_options_;
 }
 
-void WebrtcTransport::SetPreferredBitrates(
-    absl::optional<int> min_bitrate_bps,
-    absl::optional<int> max_bitrate_bps) {
+void WebrtcTransport::SetPreferredBitrates(std::optional<int> min_bitrate_bps,
+                                           std::optional<int> max_bitrate_bps) {
   preferred_min_bitrate_bps_ = min_bitrate_bps;
   preferred_max_bitrate_bps_ = max_bitrate_bps;
   if (connected_) {
@@ -741,7 +740,7 @@
 void WebrtcTransport::ApplySessionOptions(const SessionOptions& options) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   session_options_ = options;
-  absl::optional<std::string> video_codec = options.Get("Video-Codec");
+  std::optional<std::string> video_codec = options.Get("Video-Codec");
   if (video_codec) {
     preferred_video_codec_ = *video_codec;
   }
@@ -983,7 +982,7 @@
 
   // Unknown -> direct/relayed is treated as a
   // change, so the correct initial bitrate caps are set.
-  absl::optional<bool> connection_relayed =
+  std::optional<bool> connection_relayed =
       IsConnectionRelayed(event.selected_candidate_pair);
   if (connection_relayed != connection_relayed_) {
     connection_relayed_ = connection_relayed;
diff --git a/remoting/protocol/webrtc_transport.h b/remoting/protocol/webrtc_transport.h
index 94ff50d..d0ad0f1 100644
--- a/remoting/protocol/webrtc_transport.h
+++ b/remoting/protocol/webrtc_transport.h
@@ -10,6 +10,7 @@
 #include <tuple>
 #include <vector>
 
+#include <optional>
 #include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
@@ -25,7 +26,6 @@
 #include "remoting/protocol/webrtc_data_stream_adapter.h"
 #include "remoting/protocol/webrtc_event_log_data.h"
 #include "remoting/signaling/signal_strategy.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/webrtc/api/peer_connection_interface.h"
 #include "third_party/webrtc/api/video_codecs/video_encoder_factory.h"
 
@@ -113,8 +113,8 @@
   const SessionOptions& session_options() const override;
 
   // PeerConnectionControls implementations.
-  void SetPreferredBitrates(absl::optional<int> min_bitrate_bps,
-                            absl::optional<int> max_bitrate_bps) override;
+  void SetPreferredBitrates(std::optional<int> min_bitrate_bps,
+                            std::optional<int> max_bitrate_bps) override;
   void RequestIceRestart() override;
   void RequestSdpRestart() override;
 
@@ -238,7 +238,7 @@
 
   bool connected_ = false;
 
-  absl::optional<bool> connection_relayed_;
+  std::optional<bool> connection_relayed_;
 
   std::string transport_protocol_;
 
@@ -262,8 +262,8 @@
 
   // Preferred bitrates set by the client. nullopt if the client has not
   // provided any preferred bitrates.
-  absl::optional<int> preferred_min_bitrate_bps_;
-  absl::optional<int> preferred_max_bitrate_bps_;
+  std::optional<int> preferred_min_bitrate_bps_;
+  std::optional<int> preferred_max_bitrate_bps_;
 
   // Stores event log data generated by WebRTC for the PeerConnection.
   WebrtcEventLogData rtc_event_log_;
diff --git a/remoting/protocol/webrtc_video_encoder_wrapper.cc b/remoting/protocol/webrtc_video_encoder_wrapper.cc
index 9932c261..5a38cdc 100644
--- a/remoting/protocol/webrtc_video_encoder_wrapper.cc
+++ b/remoting/protocol/webrtc_video_encoder_wrapper.cc
@@ -111,7 +111,7 @@
       encoder_ = WebrtcVideoEncoderVpx::CreateForVP8();
       break;
     case webrtc::kVideoCodecVP9: {
-      absl::optional<webrtc::VP9Profile> profile =
+      std::optional<webrtc::VP9Profile> profile =
           webrtc::ParseSdpForVP9Profile(format.parameters);
       bool lossless_color = profile.has_value() &&
                             profile.value() == webrtc::VP9Profile::kProfile1;
@@ -119,7 +119,7 @@
               << (lossless_color ? "true" : "false");
       encoder_ = WebrtcVideoEncoderVpx::CreateForVP9();
       encoder_->SetLosslessColor(lossless_color);
-      absl::optional<int> encoder_speed =
+      std::optional<int> encoder_speed =
           session_options.GetInt("Vp9-Encoder-Speed");
       if (encoder_speed) {
         VLOG(0) << "Setting VP9 encoder speed to " << encoder_speed.value();
@@ -128,7 +128,7 @@
       break;
     }
     case webrtc::kVideoCodecAV1: {
-      absl::optional<webrtc::AV1Profile> profile =
+      std::optional<webrtc::AV1Profile> profile =
           webrtc::ParseSdpForAV1Profile(format.parameters);
       bool lossless_color = profile.has_value() &&
                             profile.value() == webrtc::AV1Profile::kProfile1;
@@ -136,7 +136,7 @@
               << (lossless_color ? "true" : "false");
       encoder_ = std::make_unique<WebrtcVideoEncoderAV1>();
       encoder_->SetLosslessColor(lossless_color);
-      absl::optional<int> encoder_speed =
+      std::optional<int> encoder_speed =
           session_options.GetInt("Av1-Encoder-Speed");
       if (encoder_speed) {
         VLOG(0) << "Setting AV1 encoder speed to " << encoder_speed.value();
diff --git a/remoting/protocol/webrtc_video_encoder_wrapper.h b/remoting/protocol/webrtc_video_encoder_wrapper.h
index 29198da..d999af8 100644
--- a/remoting/protocol/webrtc_video_encoder_wrapper.h
+++ b/remoting/protocol/webrtc_video_encoder_wrapper.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 
+#include <optional>
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
@@ -16,7 +17,6 @@
 #include "remoting/base/running_samples.h"
 #include "remoting/base/session_options.h"
 #include "remoting/codec/webrtc_video_encoder.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/webrtc/api/video/video_codec_type.h"
 #include "third_party/webrtc/api/video_codecs/sdp_video_format.h"
 #include "third_party/webrtc/api/video_codecs/video_encoder.h"
@@ -172,7 +172,7 @@
 
   // Represents the screen which is being encoded by this instance. Initialized
   // after the first captured frame has been received.
-  absl::optional<webrtc::ScreenId> screen_id_;
+  std::optional<webrtc::ScreenId> screen_id_;
 
   base::WeakPtr<VideoStreamEventRouter> video_stream_event_router_;
 
diff --git a/remoting/protocol/webrtc_video_encoder_wrapper_unittest.cc b/remoting/protocol/webrtc_video_encoder_wrapper_unittest.cc
index 7609e89e..980358a5 100644
--- a/remoting/protocol/webrtc_video_encoder_wrapper_unittest.cc
+++ b/remoting/protocol/webrtc_video_encoder_wrapper_unittest.cc
@@ -220,7 +220,7 @@
     expected_framerate_ = framerate;
   }
 
-  const absl::optional<int>& get_expected_framerate() const {
+  const std::optional<int>& get_expected_framerate() const {
     return expected_framerate_;
   }
 
@@ -229,7 +229,7 @@
 
   base::RunLoop run_loop_;
 
-  absl::optional<int> expected_framerate_;
+  std::optional<int> expected_framerate_;
 
   VideoStreamEventRouter video_stream_event_router_;
   NiceMock<MockVideoChannelStateObserver> observer_;
diff --git a/remoting/protocol/webrtc_video_track_source.cc b/remoting/protocol/webrtc_video_track_source.cc
index 16eceadc..bf12ed5 100644
--- a/remoting/protocol/webrtc_video_track_source.cc
+++ b/remoting/protocol/webrtc_video_track_source.cc
@@ -32,8 +32,8 @@
   return true;
 }
 
-absl::optional<bool> WebrtcVideoTrackSource::needs_denoising() const {
-  return absl::nullopt;
+std::optional<bool> WebrtcVideoTrackSource::needs_denoising() const {
+  return std::nullopt;
 }
 
 bool WebrtcVideoTrackSource::GetStats(
diff --git a/remoting/protocol/webrtc_video_track_source.h b/remoting/protocol/webrtc_video_track_source.h
index f71416e..53a6a764 100644
--- a/remoting/protocol/webrtc_video_track_source.h
+++ b/remoting/protocol/webrtc_video_track_source.h
@@ -36,7 +36,7 @@
   SourceState state() const override;
   bool remote() const override;
   bool is_screencast() const override;
-  absl::optional<bool> needs_denoising() const override;
+  std::optional<bool> needs_denoising() const override;
   bool GetStats(Stats* stats) override;
   void AddOrUpdateSink(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink,
                        const rtc::VideoSinkWants& wants) override;
diff --git a/remoting/test/it2me_cli_host.cc b/remoting/test/it2me_cli_host.cc
index fbfca23..b0e63b39 100644
--- a/remoting/test/it2me_cli_host.cc
+++ b/remoting/test/it2me_cli_host.cc
@@ -274,8 +274,7 @@
   }
 
   const std::string* code = message.FindString(kAccessCode);
-  const absl::optional<int> code_lifetime =
-      message.FindInt(kAccessCodeLifetime);
+  const std::optional<int> code_lifetime = message.FindInt(kAccessCodeLifetime);
   if (!code || !code_lifetime) {
     OnProtocolBroken("Can not obtain access code");
     return;
diff --git a/remoting/test/test_token_storage.cc b/remoting/test/test_token_storage.cc
index 690699b7..466d79e 100644
--- a/remoting/test/test_token_storage.cc
+++ b/remoting/test/test_token_storage.cc
@@ -4,6 +4,7 @@
 
 #include "remoting/test/test_token_storage.h"
 
+#include <optional>
 #include "base/files/file_util.h"
 #include "base/files/important_file_writer.h"
 #include "base/json/json_reader.h"
@@ -11,7 +12,6 @@
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 const base::FilePath::CharType kTokenFileName[] =
@@ -123,7 +123,7 @@
     return std::string();
   }
 
-  absl::optional<base::Value> token_data(base::JSONReader::Read(file_contents));
+  std::optional<base::Value> token_data(base::JSONReader::Read(file_contents));
   if (!token_data.has_value() || !token_data->is_dict()) {
     LOG(ERROR) << "File contents were not valid JSON, "
                << "could not retrieve token.";
@@ -162,7 +162,7 @@
     }
   }
 
-  absl::optional<base::Value> token_data(base::JSONReader::Read(file_contents));
+  std::optional<base::Value> token_data(base::JSONReader::Read(file_contents));
   if (!token_data.has_value() || !token_data->is_dict()) {
     LOG(ERROR) << "Invalid token file format, could not store token.";
     return false;
diff --git a/rlz/chromeos/lib/rlz_value_store_chromeos.cc b/rlz/chromeos/lib/rlz_value_store_chromeos.cc
index 059ea75..d527ff1 100644
--- a/rlz/chromeos/lib/rlz_value_store_chromeos.cc
+++ b/rlz/chromeos/lib/rlz_value_store_chromeos.cc
@@ -158,21 +158,21 @@
 }
 
 // Copy |value| without empty children.
-absl::optional<base::Value> CopyWithoutEmptyChildren(const base::Value& value) {
+std::optional<base::Value> CopyWithoutEmptyChildren(const base::Value& value) {
   switch (value.type()) {
     case base::Value::Type::DICT: {
       base::Value::Dict dict;
       const base::Value::Dict& dict_in = value.GetDict();
 
       for (auto it = dict_in.begin(); it != dict_in.end(); ++it) {
-        absl::optional<base::Value> item_copy =
+        std::optional<base::Value> item_copy =
             CopyWithoutEmptyChildren(it->second);
         if (item_copy)
           dict.Set(it->first, std::move(*item_copy));
       }
 
       if (dict.empty())
-        return absl::nullopt;
+        return std::nullopt;
 
       return base::Value(std::move(dict));
     }
@@ -182,13 +182,13 @@
       list.reserve(value.GetList().size());
 
       for (const base::Value& item : value.GetList()) {
-        absl::optional<base::Value> item_copy = CopyWithoutEmptyChildren(item);
+        std::optional<base::Value> item_copy = CopyWithoutEmptyChildren(item);
         if (item_copy)
           list.Append(std::move(*item_copy));
       }
 
       if (list.empty())
-        return absl::nullopt;
+        return std::nullopt;
 
       return base::Value(std::move(list));
     }
@@ -379,7 +379,7 @@
   if (strcmp(event_rlz, "CAF") == 0) {
     ash::system::StatisticsProvider* stats =
         ash::system::StatisticsProvider::GetInstance();
-    if (const absl::optional<base::StringPiece> should_send_rlz_ping_value =
+    if (const std::optional<base::StringPiece> should_send_rlz_ping_value =
             stats->GetMachineStatistic(ash::system::kShouldSendRlzPingKey)) {
       if (should_send_rlz_ping_value ==
           ash::system::kShouldSendRlzPingValueFalse) {
diff --git a/sandbox/linux/integration_tests/seccomp_broker_process_unittest.cc b/sandbox/linux/integration_tests/seccomp_broker_process_unittest.cc
index 967b507..d4838765 100644
--- a/sandbox/linux/integration_tests/seccomp_broker_process_unittest.cc
+++ b/sandbox/linux/integration_tests/seccomp_broker_process_unittest.cc
@@ -592,7 +592,7 @@
     BrokerTestDelegate::BrokerParams broker_params =
         broker_test_delegate_->ChildSetUpPreSandbox();
 
-    auto policy = absl::make_optional<syscall_broker::BrokerSandboxConfig>(
+    auto policy = std::make_optional<syscall_broker::BrokerSandboxConfig>(
         broker_params.allowed_command_set, broker_params.permissions,
         broker_params.denied_errno);
     broker_process_ = std::make_unique<BrokerProcess>(
diff --git a/sandbox/linux/syscall_broker/broker_host.cc b/sandbox/linux/syscall_broker/broker_host.cc
index 8447121..272dcbc 100644
--- a/sandbox/linux/syscall_broker/broker_host.cc
+++ b/sandbox/linux/syscall_broker/broker_host.cc
@@ -54,21 +54,21 @@
 
 // Applies a rewrite from /proc/self/ to /proc/[pid of sandboxed process]/.
 // Returns either a rewritten or the original pathname.
-absl::optional<std::string> BrokerHost::RewritePathname(const char* pathname) {
+std::optional<std::string> BrokerHost::RewritePathname(const char* pathname) {
   if (base::StartsWith(pathname, kProcSelf)) {
     return base::StringPrintf("/proc/%d/%s", sandboxed_process_pid_,
                               pathname + kProcSelfNumChars);
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<std::pair<const char*, int>> BrokerHost::GetPathAndFlags(
+std::optional<std::pair<const char*, int>> BrokerHost::GetPathAndFlags(
     BrokerSimpleMessage* message) {
   const char* pathname;
   int flags;
   if (!message->ReadString(&pathname) || !message->ReadInt(&flags)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return {{pathname, flags}};
 }
@@ -87,7 +87,7 @@
     return;
   }
 
-  absl::optional<std::string> rewritten_filename =
+  std::optional<std::string> rewritten_filename =
       RewritePathname(file_to_access);
   if (rewritten_filename.has_value()) {
     file_to_access = rewritten_filename.value().c_str();
@@ -115,7 +115,7 @@
     return;
   }
 
-  absl::optional<std::string> rewritten_filename =
+  std::optional<std::string> rewritten_filename =
       RewritePathname(file_to_access);
   if (rewritten_filename.has_value()) {
     file_to_access = rewritten_filename.value().c_str();
@@ -146,8 +146,7 @@
     return;
   }
 
-  absl::optional<std::string> rewritten_filename =
-      RewritePathname(file_to_open);
+  std::optional<std::string> rewritten_filename = RewritePathname(file_to_open);
   if (rewritten_filename.has_value()) {
     file_to_open = rewritten_filename.value().c_str();
   }
@@ -180,13 +179,13 @@
     return;
   }
 
-  absl::optional<std::string> old_rewritten_filename =
+  std::optional<std::string> old_rewritten_filename =
       RewritePathname(old_file_to_access);
   if (old_rewritten_filename) {
     old_file_to_access = old_rewritten_filename.value().c_str();
   }
 
-  absl::optional<std::string> new_rewritten_filename =
+  std::optional<std::string> new_rewritten_filename =
       RewritePathname(new_file_to_access);
   if (new_rewritten_filename) {
     new_file_to_access = new_rewritten_filename.value().c_str();
@@ -211,7 +210,7 @@
     return;
   }
 
-  absl::optional<std::string> rewritten_filename =
+  std::optional<std::string> rewritten_filename =
       RewritePathname(file_to_access);
   if (rewritten_filename.has_value()) {
     file_to_access = rewritten_filename.value().c_str();
@@ -238,7 +237,7 @@
     return;
   }
 
-  absl::optional<std::string> rewritten_filename =
+  std::optional<std::string> rewritten_filename =
       RewritePathname(file_to_access);
   if (rewritten_filename.has_value()) {
     file_to_access = rewritten_filename.value().c_str();
@@ -267,7 +266,7 @@
     return;
   }
 
-  absl::optional<std::string> rewritten_filename =
+  std::optional<std::string> rewritten_filename =
       RewritePathname(file_to_access);
   if (rewritten_filename.has_value()) {
     file_to_access = rewritten_filename.value().c_str();
@@ -318,7 +317,7 @@
     return;
   }
 
-  absl::optional<std::string> rewritten_filename =
+  std::optional<std::string> rewritten_filename =
       RewritePathname(file_to_access);
   if (rewritten_filename.has_value()) {
     file_to_access = rewritten_filename.value().c_str();
@@ -344,7 +343,7 @@
     return;
   }
 
-  absl::optional<std::string> rewritten_filename =
+  std::optional<std::string> rewritten_filename =
       RewritePathname(file_to_access);
   if (rewritten_filename.has_value()) {
     file_to_access = rewritten_filename.value().c_str();
diff --git a/sandbox/linux/syscall_broker/broker_host.h b/sandbox/linux/syscall_broker/broker_host.h
index ca49cce..9a6131e 100644
--- a/sandbox/linux/syscall_broker/broker_host.h
+++ b/sandbox/linux/syscall_broker/broker_host.h
@@ -5,12 +5,12 @@
 #ifndef SANDBOX_LINUX_SYSCALL_BROKER_BROKER_HOST_H_
 #define SANDBOX_LINUX_SYSCALL_BROKER_BROKER_HOST_H_
 
+#include <optional>
 #include "base/containers/span.h"
 #include "base/memory/raw_ref.h"
 #include "sandbox/linux/syscall_broker/broker_channel.h"
 #include "sandbox/linux/syscall_broker/broker_command.h"
 #include "sandbox/linux/syscall_broker/broker_sandbox_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sandbox {
 
@@ -36,9 +36,9 @@
   void LoopAndHandleRequests();
 
  private:
-  [[nodiscard]] absl::optional<std::string> RewritePathname(
+  [[nodiscard]] std::optional<std::string> RewritePathname(
       const char* pathname);
-  [[nodiscard]] absl::optional<std::pair<const char*, int>> GetPathAndFlags(
+  [[nodiscard]] std::optional<std::pair<const char*, int>> GetPathAndFlags(
       BrokerSimpleMessage* message);
 
   void AccessFileForIPC(const char* requested_filename,
diff --git a/sandbox/linux/syscall_broker/broker_process.cc b/sandbox/linux/syscall_broker/broker_process.cc
index a55b548..c6c1117 100644
--- a/sandbox/linux/syscall_broker/broker_process.cc
+++ b/sandbox/linux/syscall_broker/broker_process.cc
@@ -35,7 +35,7 @@
 
 namespace syscall_broker {
 
-BrokerProcess::BrokerProcess(absl::optional<BrokerSandboxConfig> policy,
+BrokerProcess::BrokerProcess(std::optional<BrokerSandboxConfig> policy,
                              BrokerType broker_type,
                              bool fast_check_in_client,
                              bool quiet_failures_for_tests)
diff --git a/sandbox/linux/syscall_broker/broker_process.h b/sandbox/linux/syscall_broker/broker_process.h
index 797ce6e5..4baaed1e 100644
--- a/sandbox/linux/syscall_broker/broker_process.h
+++ b/sandbox/linux/syscall_broker/broker_process.h
@@ -11,10 +11,10 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/functional/callback_forward.h"
 #include "sandbox/linux/syscall_broker/broker_sandbox_config.h"
 #include "sandbox/sandbox_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sandbox {
 
@@ -54,7 +54,7 @@
   // pipeline to the broker process, and it is not multi-threaded.
   //
   // |quiet_failures_for_tests| is reserved for unit tests, don't use it.
-  BrokerProcess(absl::optional<BrokerSandboxConfig> policy,
+  BrokerProcess(std::optional<BrokerSandboxConfig> policy,
                 BrokerType broker_type,
                 bool fast_check_in_client = true,
                 bool quiet_failures_for_tests = false);
@@ -106,7 +106,7 @@
   bool ForkSignalBasedBroker(BrokerSideCallback broker_process_init_callback);
 
   // Variables initialized by the constructor.
-  absl::optional<BrokerSandboxConfig>
+  std::optional<BrokerSandboxConfig>
       policy_;  // Can also be created by SendPolicy().
   const BrokerType broker_type_;
   const bool fast_check_in_client_;
diff --git a/sandbox/linux/syscall_broker/broker_process_unittest.cc b/sandbox/linux/syscall_broker/broker_process_unittest.cc
index cb85c87..10e7621 100644
--- a/sandbox/linux/syscall_broker/broker_process_unittest.cc
+++ b/sandbox/linux/syscall_broker/broker_process_unittest.cc
@@ -67,7 +67,7 @@
   {
     std::vector<BrokerFilePermission> permissions = {
         BrokerFilePermission::ReadOnly("/proc/cpuinfo")};
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         BrokerCommandSet(), permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED);
 
@@ -83,8 +83,8 @@
       MakeBrokerCommandSet({COMMAND_ACCESS, COMMAND_OPEN});
 
   std::vector<BrokerFilePermission> empty;
-  auto policy = absl::make_optional<BrokerSandboxConfig>(command_set, empty,
-                                                         kFakeErrnoSentinel);
+  auto policy = std::make_optional<BrokerSandboxConfig>(command_set, empty,
+                                                        kFakeErrnoSentinel);
   BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED);
 
   ASSERT_TRUE(open_broker.Fork(base::BindOnce(&NoOpCallback)));
@@ -113,7 +113,7 @@
       BrokerFilePermission::ReadOnly(kR_AllowListedButDenied),
       BrokerFilePermission::WriteOnly(kW_AllowListed),
       BrokerFilePermission::ReadWrite(kRW_AllowListed)};
-  auto policy = absl::make_optional<BrokerSandboxConfig>(
+  auto policy = std::make_optional<BrokerSandboxConfig>(
       command_set, permissions, denied_errno);
   BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                             fast_check_in_client);
@@ -302,7 +302,7 @@
 
   std::vector<BrokerFilePermission> permissions = {
       BrokerFilePermission::ReadOnlyRecursive("/proc/")};
-  auto policy = absl::make_optional<BrokerSandboxConfig>(
+  auto policy = std::make_optional<BrokerSandboxConfig>(
       command_set, permissions, kFakeErrnoSentinel);
   BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                             fast_check_in_client);
@@ -374,7 +374,7 @@
         recursive ? BrokerFilePermission::ReadOnlyRecursive(kDirProc)
                   : BrokerFilePermission::ReadOnly(kFileCpuInfo));
 
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -460,7 +460,7 @@
 
   std::vector<BrokerFilePermission> permissions = {
       BrokerFilePermission::ReadWrite(tempfile_name)};
-  auto policy = absl::make_optional<BrokerSandboxConfig>(
+  auto policy = std::make_optional<BrokerSandboxConfig>(
       command_set, permissions, kFakeErrnoSentinel);
   BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED);
 
@@ -502,7 +502,7 @@
 
   std::vector<BrokerFilePermission> permissions = {
       BrokerFilePermission::ReadOnly(kCpuInfo)};
-  auto policy = absl::make_optional<BrokerSandboxConfig>(
+  auto policy = std::make_optional<BrokerSandboxConfig>(
       command_set, permissions, kFakeErrnoSentinel);
   BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                             true /* fast_check_in_client */,
@@ -535,7 +535,7 @@
 
   std::vector<BrokerFilePermission> permissions = {
       BrokerFilePermission::ReadOnly(kCpuInfo)};
-  auto policy = absl::make_optional<BrokerSandboxConfig>(
+  auto policy = std::make_optional<BrokerSandboxConfig>(
       command_set, permissions, kFakeErrnoSentinel);
   BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                             fast_check_in_client);
@@ -635,7 +635,7 @@
 
   std::vector<BrokerFilePermission> permissions = {
       BrokerFilePermission::ReadOnly(kCpuInfo)};
-  auto policy = absl::make_optional<BrokerSandboxConfig>(
+  auto policy = std::make_optional<BrokerSandboxConfig>(
       command_set, permissions, kFakeErrnoSentinel);
   BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED);
 
@@ -691,7 +691,7 @@
 
   std::vector<BrokerFilePermission> permissions = {
       BrokerFilePermission::ReadOnly("/proc/cpuinfo")};
-  auto policy = absl::make_optional<BrokerSandboxConfig>(
+  auto policy = std::make_optional<BrokerSandboxConfig>(
       command_set, permissions, kFakeErrnoSentinel);
   BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                             true /* fast_check_in_client */,
@@ -730,7 +730,7 @@
 
   {
     // Nonexistent file with no permissions to see file.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, proc_status_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -800,7 +800,7 @@
       BrokerFilePermission::ReadWriteCreate(permfile_name),
   };
 
-  auto policy = absl::make_optional<BrokerSandboxConfig>(
+  auto policy = std::make_optional<BrokerSandboxConfig>(
       command_set, permissions, kFakeErrnoSentinel);
   BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED);
 
@@ -903,7 +903,7 @@
     // Actual file with permissions to see file but command not allowed.
     std::vector<BrokerFilePermission> permissions = {
         BrokerFilePermission::ReadOnly(tempfile_name)};
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         BrokerCommandSet(), permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -922,7 +922,7 @@
   {
     // Nonexistent file with no permissions to see file.
     std::vector<BrokerFilePermission> permissions;
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -937,7 +937,7 @@
   {
     // Actual file with no permission to see file.
     std::vector<BrokerFilePermission> permissions;
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -953,7 +953,7 @@
     // Nonexistent file with permissions to see file.
     std::vector<BrokerFilePermission> permissions = {
         BrokerFilePermission::ReadOnly(nonesuch_name)};
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1000,7 +1000,7 @@
     // Nonexistent file with permissions to create file.
     std::vector<BrokerFilePermission> permissions = {
         BrokerFilePermission::ReadWriteCreate(nonesuch_name)};
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1049,7 +1049,7 @@
     // Actual file with permissions to see file.
     std::vector<BrokerFilePermission> permissions = {
         BrokerFilePermission::ReadOnly(tempfile_name)};
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1119,7 +1119,7 @@
   {
     // Check rename fails with write permissions to both files but command
     // itself is not allowed.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         BrokerCommandSet(), rwc_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1140,7 +1140,7 @@
     // Check rename fails when no permission to new file.
     std::vector<BrokerFilePermission> permissions = {
         BrokerFilePermission::ReadWriteCreate(oldpath)};
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1158,7 +1158,7 @@
     // Check rename fails when no permission to old file.
     std::vector<BrokerFilePermission> permissions = {
         BrokerFilePermission::ReadWriteCreate(newpath)};
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1177,7 +1177,7 @@
     std::vector<BrokerFilePermission> permissions = {
         BrokerFilePermission::ReadOnly(oldpath),
         BrokerFilePermission::ReadWriteCreate(newpath)};
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1196,7 +1196,7 @@
     std::vector<BrokerFilePermission> permissions = {
         BrokerFilePermission::ReadWriteCreate(oldpath),
         BrokerFilePermission::ReadOnly(newpath)};
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1212,7 +1212,7 @@
   }
   {
     // Check rename passes with write permissions to both files.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, rwc_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1260,7 +1260,7 @@
     // Actual file with permissions to see file but command itself not allowed.
     std::vector<BrokerFilePermission> permissions = {
         BrokerFilePermission::ReadOnly(newpath_name)};
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         BrokerCommandSet(), permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1277,7 +1277,7 @@
   {
     // Nonexistent file with no permissions to see file.
     std::vector<BrokerFilePermission> permissions;
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1290,7 +1290,7 @@
   {
     // Actual file with no permissions to see file.
     std::vector<BrokerFilePermission> permissions;
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1304,7 +1304,7 @@
     // Nonexistent file with permissions to see file.
     std::vector<BrokerFilePermission> permissions = {
         BrokerFilePermission::ReadOnly(nonesuch_name)};
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1317,7 +1317,7 @@
     // Actual file with permissions to see file.
     std::vector<BrokerFilePermission> permissions = {
         BrokerFilePermission::ReadOnly(newpath_name)};
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1332,7 +1332,7 @@
     // Actual file with permissions to see file, but too small a buffer.
     std::vector<BrokerFilePermission> permissions = {
         BrokerFilePermission::ReadOnly(newpath_name)};
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1380,7 +1380,7 @@
 
   {
     // Actual file with permissions to use but command itself not allowed.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         BrokerCommandSet(), rw_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1394,7 +1394,7 @@
 
   {
     // Nonexistent file with no permissions to see file.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, no_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1406,7 +1406,7 @@
   }
   {
     // Actual file with no permissions to see file.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, no_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1417,7 +1417,7 @@
   }
   {
     // Nonexistent file with insufficient permissions to see file.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, ro_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1429,7 +1429,7 @@
   }
   {
     // Actual file with insufficient permissions to see file.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, ro_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1440,7 +1440,7 @@
   }
   {
     // Nonexistent file with insufficient permissions to see file, case 2.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, rw_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1452,7 +1452,7 @@
   }
   {
     // Actual file with insufficient permissions to see file, case 2.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, rw_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1463,7 +1463,7 @@
   }
   {
     // Nonexistent file with permissions to see file.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, rwc_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1474,7 +1474,7 @@
   }
   {
     // Actual file with permissions to see file.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, rwc_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1524,7 +1524,7 @@
 
   {
     // Actual dir with permissions to use but command itself not allowed.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         BrokerCommandSet(), rw_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1539,7 +1539,7 @@
 
   {
     // Nonexistent dir with no permissions to see dir.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, no_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1552,7 +1552,7 @@
 
   {
     // Actual dir with no permissions to see dir.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, no_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1565,7 +1565,7 @@
 
   {
     // Nonexistent dir with insufficient permissions to see dir.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, ro_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1578,7 +1578,7 @@
 
   {
     // Actual dir with insufficient permissions to see dir.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, ro_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1591,7 +1591,7 @@
 
   {
     // Nonexistent dir with insufficient permissions to see dir, case 2.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, rw_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1604,7 +1604,7 @@
 
   {
     // Actual dir with insufficient permissions to see dir, case 2.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, rw_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1617,7 +1617,7 @@
 
   {
     // Nonexistent dir with permissions to see dir.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, rwc_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1630,7 +1630,7 @@
 
   {
     // Actual dir with permissions to see dir.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, rwc_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1681,7 +1681,7 @@
 
   {
     // Actual file with permissions to use but command itself not allowed.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         BrokerCommandSet(), rwc_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1696,7 +1696,7 @@
 
   {
     // Nonexistent file with no permissions to see file.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, no_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1709,7 +1709,7 @@
 
   {
     // Actual file with no permissions to see file.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, no_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1722,7 +1722,7 @@
 
   {
     // Nonexistent file with insufficient permissions to see file.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, ro_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1735,7 +1735,7 @@
 
   {
     // Actual file with insufficient permissions to see file.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, ro_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1748,7 +1748,7 @@
 
   {
     // Nonexistent file with insufficient permissions to see file, case 2.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, rw_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1761,7 +1761,7 @@
 
   {
     // Actual file with insufficient permissions to see file, case 2.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, rw_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1774,7 +1774,7 @@
 
   {
     // Nonexistent file with permissions to see file.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, rwc_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1787,7 +1787,7 @@
 
   {
     // Actual file with permissions to see file.
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, rwc_permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1834,7 +1834,7 @@
     std::vector<BrokerFilePermission> permissions = {
         BrokerFilePermission::InotifyAddWatchWithIntermediateDirs(
             nested_temp_dir_str)};
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         BrokerCommandSet(), permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1855,7 +1855,7 @@
   {
     // Try to watch a directory with no permission.
     std::vector<BrokerFilePermission> permissions;
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1874,7 +1874,7 @@
     std::vector<BrokerFilePermission> permissions = {
         BrokerFilePermission::InotifyAddWatchWithIntermediateDirs(
             nested_temp_dir_str)};
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1894,7 +1894,7 @@
     std::vector<BrokerFilePermission> permissions = {
         BrokerFilePermission::InotifyAddWatchWithIntermediateDirs(
             nested_temp_dir_str)};
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -1926,7 +1926,7 @@
     std::vector<BrokerFilePermission> permissions = {
         BrokerFilePermission::InotifyAddWatchWithIntermediateDirs(
             nested_temp_dir_str)};
-    auto policy = absl::make_optional<BrokerSandboxConfig>(
+    auto policy = std::make_optional<BrokerSandboxConfig>(
         command_set, permissions, kFakeErrnoSentinel);
     BrokerProcess open_broker(std::move(policy), BrokerType::SIGNAL_BASED,
                               fast_check_in_client);
@@ -2058,7 +2058,7 @@
       BrokerCommand command = test.first;
       const base::flat_set<int>& sysnos = test.second;
       SCOPED_TRACE(base::StringPrintf("fast check, command=%d", command));
-      auto policy = absl::make_optional<BrokerSandboxConfig>(
+      auto policy = std::make_optional<BrokerSandboxConfig>(
           MakeBrokerCommandSet({command}), std::vector<BrokerFilePermission>(),
           ENOSYS);
       BrokerProcess process(std::move(policy), BrokerType::SIGNAL_BASED,
@@ -2075,7 +2075,7 @@
     {
       BrokerCommand command = test.first;
       SCOPED_TRACE(base::StringPrintf("no fast check, command=%d", command));
-      auto policy = absl::make_optional<BrokerSandboxConfig>(
+      auto policy = std::make_optional<BrokerSandboxConfig>(
           MakeBrokerCommandSet({command}), std::vector<BrokerFilePermission>(),
           ENOSYS);
       BrokerProcess process(std::move(policy), BrokerType::SIGNAL_BASED,
diff --git a/sandbox/mac/sandbox_test.h b/sandbox/mac/sandbox_test.h
index d74b68c2..fcac4be 100644
--- a/sandbox/mac/sandbox_test.h
+++ b/sandbox/mac/sandbox_test.h
@@ -7,11 +7,11 @@
 
 #include <string>
 
+#include <optional>
 #include "base/command_line.h"
 #include "base/functional/callback.h"
 #include "base/process/process.h"
 #include "base/test/multiprocess_test.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sandbox {
 
@@ -20,7 +20,7 @@
 class SandboxTest : public base::MultiProcessTest {
  public:
   using CommandLineModifier =
-      absl::optional<base::RepeatingCallback<void(base::CommandLine&)>>;
+      std::optional<base::RepeatingCallback<void(base::CommandLine&)>>;
 
   SandboxTest();
   ~SandboxTest() override;
@@ -32,12 +32,12 @@
   base::Process SpawnChildWithOptions(
       const std::string& procname,
       const base::LaunchOptions& options,
-      CommandLineModifier command_line_modifier = absl::nullopt);
+      CommandLineModifier command_line_modifier = std::nullopt);
 
   // Same as SpawnChildWithOptions, but uses a default LaunchOptions value.
   base::Process SpawnChild(
       const std::string& procname,
-      CommandLineModifier command_line_modifier = absl::nullopt);
+      CommandLineModifier command_line_modifier = std::nullopt);
 };
 
 }  // namespace sandbox
diff --git a/sandbox/policy/linux/sandbox_linux.cc b/sandbox/policy/linux/sandbox_linux.cc
index e574b7b..0bb1294 100644
--- a/sandbox/policy/linux/sandbox_linux.cc
+++ b/sandbox/policy/linux/sandbox_linux.cc
@@ -536,7 +536,7 @@
   // other LSMs like AppArmor and Landlock. Some userspace code, such as
   // glibc's |dlopen|, expect to see EACCES rather than EPERM. See
   // crbug.com/1233028 for an example.
-  auto policy = absl::make_optional<syscall_broker::BrokerSandboxConfig>(
+  auto policy = std::make_optional<syscall_broker::BrokerSandboxConfig>(
       allowed_command_set, std::move(permissions), EACCES);
   // Leaked at shutdown, so use bare |new|.
   broker_process_ = new syscall_broker::BrokerProcess(
diff --git a/sandbox/policy/win/sandbox_win.cc b/sandbox/policy/win/sandbox_win.cc
index 0aa0cdc..5eb2c633 100644
--- a/sandbox/policy/win/sandbox_win.cc
+++ b/sandbox/policy/win/sandbox_win.cc
@@ -15,6 +15,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/command_line.h"
 #include "base/containers/contains.h"
 #include "base/feature_list.h"
@@ -62,7 +63,6 @@
 #include "sandbox/win/src/app_container.h"
 #include "sandbox/win/src/process_mitigations.h"
 #include "sandbox/win/src/sandbox.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sandbox {
 namespace policy {
@@ -369,7 +369,7 @@
   std::wstring_view type_name(type_info->TypeName.Buffer,
                               type_info->TypeName.Length / sizeof(wchar_t));
 
-  absl::optional<ACCESS_MASK> granted_access =
+  std::optional<ACCESS_MASK> granted_access =
       base::win::GetGrantedAccess(handle);
   CHECK(granted_access.has_value());
 
@@ -785,7 +785,7 @@
   if (ret != SBOX_ALL_OK)
     return ret;
 
-  absl::optional<size_t> memory_limit = GetJobMemoryLimit(sandbox_type);
+  std::optional<size_t> memory_limit = GetJobMemoryLimit(sandbox_type);
   if (memory_limit) {
     config->SetJobMemoryLimit(*memory_limit);
   }
@@ -1136,7 +1136,7 @@
 }
 
 // static
-absl::optional<size_t> SandboxWin::GetJobMemoryLimit(Sandbox sandbox_type) {
+std::optional<size_t> SandboxWin::GetJobMemoryLimit(Sandbox sandbox_type) {
   // Trigger feature list initialization here to ensure no population bias in
   // the experimental and control groups.
   [[maybe_unused]] const bool high_renderer_limits =
@@ -1171,7 +1171,7 @@
   }
   return memory_limit;
 #else
-  return absl::nullopt;
+  return std::nullopt;
 #endif
 }
 
diff --git a/sandbox/policy/win/sandbox_win.h b/sandbox/policy/win/sandbox_win.h
index f45b798..81698da 100644
--- a/sandbox/policy/win/sandbox_win.h
+++ b/sandbox/policy/win/sandbox_win.h
@@ -9,6 +9,7 @@
 
 #include <string>
 
+#include <optional>
 #include "base/functional/bind.h"
 #include "base/functional/callback_forward.h"
 #include "base/process/launch.h"
@@ -19,7 +20,6 @@
 #include "sandbox/policy/sandbox_type.h"
 #include "sandbox/win/src/sandbox_types.h"
 #include "sandbox/win/src/security_level.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class CommandLine;
@@ -125,7 +125,7 @@
  private:
   FRIEND_TEST_ALL_PREFIXES(SandboxWinTest, GetJobMemoryLimit);
 
-  static absl::optional<size_t> GetJobMemoryLimit(
+  static std::optional<size_t> GetJobMemoryLimit(
       sandbox::mojom::Sandbox sandbox_type);
 };
 
diff --git a/sandbox/policy/win/sandbox_win_unittest.cc b/sandbox/policy/win/sandbox_win_unittest.cc
index 2c9cef97..cac37fd0 100644
--- a/sandbox/policy/win/sandbox_win_unittest.cc
+++ b/sandbox/policy/win/sandbox_win_unittest.cc
@@ -558,7 +558,7 @@
   // Test GPU with physical memory > 64GB.
   {
     base::test::ScopedAmountOfPhysicalMemoryOverride memory_override(k65GB);
-    absl::optional<size_t> memory_limit =
+    std::optional<size_t> memory_limit =
         SandboxWin::GetJobMemoryLimit(sandbox::mojom::Sandbox::kGpu);
     EXPECT_TRUE(memory_limit.has_value());
     EXPECT_EQ(memory_limit, 64 * kGB);
@@ -567,7 +567,7 @@
   // Test GPU with physical memory > 32GB
   {
     base::test::ScopedAmountOfPhysicalMemoryOverride memory_override(k33GB);
-    absl::optional<size_t> memory_limit =
+    std::optional<size_t> memory_limit =
         SandboxWin::GetJobMemoryLimit(sandbox::mojom::Sandbox::kGpu);
     EXPECT_TRUE(memory_limit.has_value());
     EXPECT_EQ(memory_limit, 32 * kGB);
@@ -576,7 +576,7 @@
   // Test GPU with physical memory > 16GB
   {
     base::test::ScopedAmountOfPhysicalMemoryOverride memory_override(k17GB);
-    absl::optional<size_t> memory_limit =
+    std::optional<size_t> memory_limit =
         SandboxWin::GetJobMemoryLimit(sandbox::mojom::Sandbox::kGpu);
     EXPECT_TRUE(memory_limit.has_value());
     EXPECT_EQ(memory_limit, 16 * kGB);
@@ -585,7 +585,7 @@
   // Test GPU with physical memory < 16GB
   {
     base::test::ScopedAmountOfPhysicalMemoryOverride memory_override(k8GB);
-    absl::optional<size_t> memory_limit =
+    std::optional<size_t> memory_limit =
         SandboxWin::GetJobMemoryLimit(sandbox::mojom::Sandbox::kGpu);
     EXPECT_TRUE(memory_limit.has_value());
     EXPECT_EQ(memory_limit, 8 * kGB);
@@ -597,7 +597,7 @@
     base::test::ScopedFeatureList scoped_feature_list;
     scoped_feature_list.InitAndDisableFeature(
         sandbox::policy::features::kWinSboxHighRendererJobMemoryLimits);
-    absl::optional<size_t> memory_limit =
+    std::optional<size_t> memory_limit =
         SandboxWin::GetJobMemoryLimit(sandbox::mojom::Sandbox::kRenderer);
     EXPECT_TRUE(memory_limit.has_value());
     EXPECT_EQ(memory_limit, 16 * kGB);
@@ -609,7 +609,7 @@
     base::test::ScopedFeatureList scoped_feature_list;
     scoped_feature_list.InitAndDisableFeature(
         sandbox::policy::features::kWinSboxHighRendererJobMemoryLimits);
-    absl::optional<size_t> memory_limit =
+    std::optional<size_t> memory_limit =
         SandboxWin::GetJobMemoryLimit(sandbox::mojom::Sandbox::kRenderer);
     EXPECT_TRUE(memory_limit.has_value());
     EXPECT_EQ(memory_limit, 8 * kGB);
@@ -621,7 +621,7 @@
     base::test::ScopedFeatureList scoped_feature_list;
     scoped_feature_list.InitAndEnableFeature(
         sandbox::policy::features::kWinSboxHighRendererJobMemoryLimits);
-    absl::optional<size_t> memory_limit =
+    std::optional<size_t> memory_limit =
         SandboxWin::GetJobMemoryLimit(sandbox::mojom::Sandbox::kRenderer);
     EXPECT_TRUE(memory_limit.has_value());
     EXPECT_EQ(memory_limit, 1024 * kGB);
@@ -630,7 +630,7 @@
   // Test 32-bit processes don't get a limit.
   {
     base::test::ScopedAmountOfPhysicalMemoryOverride memory_override(k8GB);
-    absl::optional<size_t> memory_limit =
+    std::optional<size_t> memory_limit =
         SandboxWin::GetJobMemoryLimit(sandbox::mojom::Sandbox::kRenderer);
     EXPECT_FALSE(memory_limit.has_value());
   }
diff --git a/sandbox/win/src/acl.cc b/sandbox/win/src/acl.cc
index a649d469..8c2c072 100644
--- a/sandbox/win/src/acl.cc
+++ b/sandbox/win/src/acl.cc
@@ -10,7 +10,7 @@
 
 namespace sandbox {
 
-absl::optional<DWORD> GetIntegrityLevelRid(IntegrityLevel integrity_level) {
+std::optional<DWORD> GetIntegrityLevelRid(IntegrityLevel integrity_level) {
   switch (integrity_level) {
     case INTEGRITY_LEVEL_SYSTEM:
       return DWORD{SECURITY_MANDATORY_SYSTEM_RID};
@@ -27,18 +27,18 @@
     case INTEGRITY_LEVEL_UNTRUSTED:
       return DWORD{SECURITY_MANDATORY_UNTRUSTED_RID};
     case INTEGRITY_LEVEL_LAST:
-      return absl::nullopt;
+      return std::nullopt;
   }
 
   NOTREACHED();
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 DWORD SetObjectIntegrityLabel(HANDLE handle,
                               base::win::SecurityObjectType object_type,
                               DWORD mandatory_policy,
                               IntegrityLevel integrity_level) {
-  absl::optional<DWORD> value = GetIntegrityLevelRid(integrity_level);
+  std::optional<DWORD> value = GetIntegrityLevelRid(integrity_level);
   if (!value) {
     return ERROR_INVALID_SID;
   }
diff --git a/sandbox/win/src/acl.h b/sandbox/win/src/acl.h
index 475e94428..59ce330 100644
--- a/sandbox/win/src/acl.h
+++ b/sandbox/win/src/acl.h
@@ -13,7 +13,7 @@
 
 // Returns the RID associated with a given IntegrityLevel value. This returns
 // an empty value if `integrity_level` is set to INTEGRITY_LEVEL_LAST.
-absl::optional<DWORD> GetIntegrityLevelRid(IntegrityLevel integrity_level);
+std::optional<DWORD> GetIntegrityLevelRid(IntegrityLevel integrity_level);
 
 // Sets the integrity label on a object.
 // `handle` should be an open handle with WRITE_OWNER access.
diff --git a/sandbox/win/src/acl_unittest.cc b/sandbox/win/src/acl_unittest.cc
index 7584624a..65042d6 100644
--- a/sandbox/win/src/acl_unittest.cc
+++ b/sandbox/win/src/acl_unittest.cc
@@ -16,10 +16,9 @@
 
 void CheckGetIntegrityLevelSid(IntegrityLevel integrity_level,
                                const wchar_t* sddl) {
-  absl::optional<base::win::Sid> sddl_sid =
-      base::win::Sid::FromSddlString(sddl);
+  std::optional<base::win::Sid> sddl_sid = base::win::Sid::FromSddlString(sddl);
   ASSERT_TRUE(sddl_sid);
-  absl::optional<DWORD> integrity_value = GetIntegrityLevelRid(integrity_level);
+  std::optional<DWORD> integrity_value = GetIntegrityLevelRid(integrity_level);
   ASSERT_TRUE(integrity_value);
   EXPECT_EQ(*sddl_sid, base::win::Sid::FromIntegrityLevel(*integrity_value));
 }
@@ -34,7 +33,7 @@
   EXPECT_EQ(result, expected_error);
   if (result != ERROR_SUCCESS)
     return;
-  absl::optional<base::win::SecurityDescriptor> sd =
+  std::optional<base::win::SecurityDescriptor> sd =
       base::win::SecurityDescriptor::FromHandle(
           job.get(), base::win::SecurityObjectType::kKernel,
           LABEL_SECURITY_INFORMATION);
@@ -48,7 +47,7 @@
   ASSERT_EQ(ace->Header.AceType, SYSTEM_MANDATORY_LABEL_ACE_TYPE);
   EXPECT_EQ(ace->Header.AceFlags, 0);
   EXPECT_EQ(ace->Mask, mandatory_policy);
-  absl::optional<DWORD> rid = GetIntegrityLevelRid(integrity_level);
+  std::optional<DWORD> rid = GetIntegrityLevelRid(integrity_level);
   base::win::Sid sid = base::win::Sid::FromIntegrityLevel(*rid);
   ASSERT_TRUE(::IsValidSid(&ace->SidStart));
   EXPECT_TRUE(sid.Equal(&ace->SidStart));
diff --git a/sandbox/win/src/app_container_base.cc b/sandbox/win/src/app_container_base.cc
index 37cc8fa..8fd0b01 100644
--- a/sandbox/win/src/app_container_base.cc
+++ b/sandbox/win/src/app_container_base.cc
@@ -107,7 +107,7 @@
     return false;
   }
 
-  absl::optional<base::win::SecurityDescriptor> sd =
+  std::optional<base::win::SecurityDescriptor> sd =
       base::win::SecurityDescriptor::FromName(
           object_name, object_type,
           OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
@@ -125,24 +125,24 @@
     }
   }
 
-  absl::optional<base::win::AccessToken> primary =
+  std::optional<base::win::AccessToken> primary =
       base::win::AccessToken::FromCurrentProcess(
           /*impersonation=*/false, TOKEN_DUPLICATE);
   if (!primary.has_value()) {
     return false;
   }
-  absl::optional<base::win::AccessToken> lowbox = BuildPrimaryToken(*primary);
+  std::optional<base::win::AccessToken> lowbox = BuildPrimaryToken(*primary);
   if (!lowbox) {
     return false;
   }
-  absl::optional<base::win::AccessToken> token_query =
+  std::optional<base::win::AccessToken> token_query =
       lowbox->DuplicateImpersonation(
           base::win::SecurityImpersonationLevel::kIdentification);
   if (!token_query) {
     return false;
   }
 
-  absl::optional<base::win::AccessCheckResult> result =
+  std::optional<base::win::AccessCheckResult> result =
       sd->AccessCheck(*token_query, desired_access, object_type);
   if (!result) {
     return false;
@@ -166,7 +166,7 @@
 }
 
 bool AppContainerBase::AddCapability(
-    const absl::optional<base::win::Sid>& capability_sid,
+    const std::optional<base::win::Sid>& capability_sid,
     bool impersonation_only) {
   if (!capability_sid)
     return false;
@@ -220,38 +220,38 @@
   return std::make_unique<SecurityCapabilities>(package_sid_, capabilities_);
 }
 
-absl::optional<base::win::AccessToken>
-AppContainerBase::BuildImpersonationToken(const base::win::AccessToken& token) {
-  absl::optional<base::win::AccessToken> lowbox = token.CreateAppContainer(
+std::optional<base::win::AccessToken> AppContainerBase::BuildImpersonationToken(
+    const base::win::AccessToken& token) {
+  std::optional<base::win::AccessToken> lowbox = token.CreateAppContainer(
       package_sid_, impersonation_capabilities_, TOKEN_ALL_ACCESS);
   ;
   if (!lowbox.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  absl::optional<base::win::SecurityDescriptor> sd =
+  std::optional<base::win::SecurityDescriptor> sd =
       base::win::SecurityDescriptor::FromHandle(
           lowbox->get(), base::win::SecurityObjectType::kKernel,
           DACL_SECURITY_INFORMATION);
   if (!sd) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   lowbox = lowbox->DuplicateImpersonation(
       base::win::SecurityImpersonationLevel::kImpersonation, TOKEN_ALL_ACCESS);
   if (!lowbox.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (!sd->WriteToHandle(lowbox->get(), base::win::SecurityObjectType::kKernel,
                          DACL_SECURITY_INFORMATION)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return lowbox;
 }
 
-absl::optional<base::win::AccessToken> AppContainerBase::BuildPrimaryToken(
+std::optional<base::win::AccessToken> AppContainerBase::BuildPrimaryToken(
     const base::win::AccessToken& token) {
   return token.CreateAppContainer(package_sid_, capabilities_,
                                   TOKEN_ALL_ACCESS);
diff --git a/sandbox/win/src/app_container_base.h b/sandbox/win/src/app_container_base.h
index 73998cf..174f247 100644
--- a/sandbox/win/src/app_container_base.h
+++ b/sandbox/win/src/app_container_base.h
@@ -8,13 +8,13 @@
 #include <memory>
 #include <vector>
 
+#include <optional>
 #include "base/win/access_token.h"
 #include "base/win/security_descriptor.h"
 #include "base/win/sid.h"
 #include "base/win/windows_types.h"
 #include "sandbox/win/src/app_container.h"
 #include "sandbox/win/src/sandbox_types.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sandbox {
 
@@ -70,21 +70,21 @@
   // `token` specify the base token to create the new token from. Must have
   // TOKEN_DUPLICATE access. The token is created with the impersonation
   // capabilities list.
-  absl::optional<base::win::AccessToken> BuildImpersonationToken(
+  std::optional<base::win::AccessToken> BuildImpersonationToken(
       const base::win::AccessToken& token);
 
   // Build a primary token from an existing token.
   // `token` specify the base token to create the new token from. Must have
   // TOKEN_DUPLICATE access. The token is created with the normal capabilities
   // list.
-  absl::optional<base::win::AccessToken> BuildPrimaryToken(
+  std::optional<base::win::AccessToken> BuildPrimaryToken(
       const base::win::AccessToken& token);
 
  private:
   AppContainerBase(base::win::Sid& package_sid, AppContainerType type);
   ~AppContainerBase();
 
-  bool AddCapability(const absl::optional<base::win::Sid>& capability_sid,
+  bool AddCapability(const std::optional<base::win::Sid>& capability_sid,
                      bool impersonation_only);
 
   // Standard object-lifetime reference counter.
diff --git a/sandbox/win/src/app_container_test.cc b/sandbox/win/src/app_container_test.cc
index ed78a6d1..c1ca465 100644
--- a/sandbox/win/src/app_container_test.cc
+++ b/sandbox/win/src/app_container_test.cc
@@ -51,7 +51,7 @@
   return impersonation ? "Impersonation Token" : "Primary Token";
 }
 
-void CheckToken(const absl::optional<base::win::AccessToken>& token,
+void CheckToken(const std::optional<base::win::AccessToken>& token,
                 bool impersonation,
                 PSECURITY_CAPABILITIES security_capabilities,
                 bool restricted) {
@@ -65,7 +65,7 @@
     EXPECT_FALSE(token->IsIdentification()) << TokenTypeToName(impersonation);
   }
 
-  absl::optional<base::win::Sid> package_sid = token->AppContainerSid();
+  std::optional<base::win::Sid> package_sid = token->AppContainerSid();
   ASSERT_TRUE(package_sid) << TokenTypeToName(impersonation);
   EXPECT_TRUE(package_sid->Equal(security_capabilities->AppContainerSid))
       << TokenTypeToName(impersonation);
diff --git a/sandbox/win/src/app_container_unittest.cc b/sandbox/win/src/app_container_unittest.cc
index 34803f9..6ca40e91 100644
--- a/sandbox/win/src/app_container_unittest.cc
+++ b/sandbox/win/src/app_container_unittest.cc
@@ -179,7 +179,7 @@
                       const base::win::AccessToken& base_token,
                       bool impersonation,
                       size_t expected_cap_count) {
-  absl::optional<base::win::AccessToken> token =
+  std::optional<base::win::AccessToken> token =
       impersonation ? container->BuildImpersonationToken(base_token)
                     : container->BuildPrimaryToken(base_token);
   ASSERT_TRUE(token);
@@ -418,7 +418,7 @@
   if (!features::IsAppContainerSandboxSupported()) {
     return;
   }
-  absl::optional<base::win::AccessToken> base_token =
+  std::optional<base::win::AccessToken> base_token =
       base::win::AccessToken::FromCurrentProcess(
           /*impersonation=*/false, TOKEN_DUPLICATE);
   ASSERT_TRUE(base_token);
@@ -438,7 +438,7 @@
   if (!features::IsAppContainerSandboxSupported()) {
     return;
   }
-  absl::optional<base::win::AccessToken> base_token =
+  std::optional<base::win::AccessToken> base_token =
       base::win::AccessToken::FromCurrentProcess(
           /*impersonation=*/false, TOKEN_DUPLICATE);
   ASSERT_TRUE(base_token);
diff --git a/sandbox/win/src/broker_services.cc b/sandbox/win/src/broker_services.cc
index 9dfe4b3..95a6e5d3 100644
--- a/sandbox/win/src/broker_services.cc
+++ b/sandbox/win/src/broker_services.cc
@@ -6,6 +6,7 @@
 
 #include <stddef.h>
 
+#include <optional>
 #include <utility>
 #include "base/check_op.h"
 #include "base/containers/contains.h"
@@ -27,7 +28,6 @@
 #include "sandbox/win/src/target_process.h"
 #include "sandbox/win/src/threadpool.h"
 #include "sandbox/win/src/win_utils.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -408,8 +408,8 @@
 
   // Construct the tokens and the job object that we are going to associate
   // with the soon to be created target process.
-  absl::optional<base::win::AccessToken> initial_token;
-  absl::optional<base::win::AccessToken> lockdown_token;
+  std::optional<base::win::AccessToken> initial_token;
+  std::optional<base::win::AccessToken> lockdown_token;
   ResultCode result = SBOX_ALL_OK;
 
   result = policy_base->MakeTokens(initial_token, lockdown_token);
diff --git a/sandbox/win/src/handle_closer_agent.cc b/sandbox/win/src/handle_closer_agent.cc
index 11f1950..98529e3 100644
--- a/sandbox/win/src/handle_closer_agent.cc
+++ b/sandbox/win/src/handle_closer_agent.cc
@@ -6,12 +6,12 @@
 
 #include <stddef.h>
 
+#include <optional>
 #include "base/check.h"
 #include "base/logging.h"
 #include "base/win/static_constants.h"
 #include "base/win/win_util.h"
 #include "sandbox/win/src/win_utils.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sandbox {
 
@@ -148,7 +148,7 @@
   if (base::win::IsAppVerifierLoaded())
     return true;
 
-  absl::optional<ProcessHandleMap> handle_map = GetCurrentProcessHandles();
+  std::optional<ProcessHandleMap> handle_map = GetCurrentProcessHandles();
   if (!handle_map)
     return false;
 
diff --git a/sandbox/win/src/integrity_level_test.cc b/sandbox/win/src/integrity_level_test.cc
index 5f79e53..42e9871 100644
--- a/sandbox/win/src/integrity_level_test.cc
+++ b/sandbox/win/src/integrity_level_test.cc
@@ -6,6 +6,7 @@
 
 #include <atlsecurity.h>
 
+#include <optional>
 #include "base/process/process_info.h"
 #include "base/win/access_token.h"
 #include "sandbox/win/src/sandbox.h"
@@ -13,7 +14,6 @@
 #include "sandbox/win/src/sandbox_policy.h"
 #include "sandbox/win/tests/common/controller.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sandbox {
 
@@ -30,7 +30,7 @@
 }
 
 SBOX_TESTS_COMMAND int CheckIntegrityLevel(int argc, wchar_t** argv) {
-  absl::optional<base::win::AccessToken> token =
+  std::optional<base::win::AccessToken> token =
       base::win::AccessToken::FromEffective();
   if (!token)
     return SBOX_TEST_FAILED;
diff --git a/sandbox/win/src/process_mitigations.cc b/sandbox/win/src/process_mitigations.cc
index 79ca46ee..2b870c0 100644
--- a/sandbox/win/src/process_mitigations.cc
+++ b/sandbox/win/src/process_mitigations.cc
@@ -127,7 +127,7 @@
   }
 
   if (flags & MITIGATION_HARDEN_TOKEN_IL_POLICY) {
-    absl::optional<base::win::AccessToken> token =
+    std::optional<base::win::AccessToken> token =
         base::win::AccessToken::FromCurrentProcess(/*impersonation=*/false,
                                                    READ_CONTROL | WRITE_OWNER);
     if (!token) {
diff --git a/sandbox/win/src/process_thread_interception.cc b/sandbox/win/src/process_thread_interception.cc
index 7ab4d37f..308a519 100644
--- a/sandbox/win/src/process_thread_interception.cc
+++ b/sandbox/win/src/process_thread_interception.cc
@@ -6,6 +6,7 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include "sandbox/win/src/crosscall_client.h"
 #include "sandbox/win/src/ipc_tags.h"
 #include "sandbox/win/src/policy_params.h"
@@ -14,7 +15,6 @@
 #include "sandbox/win/src/sandbox_nt_util.h"
 #include "sandbox/win/src/sharedmem_ipc_client.h"
 #include "sandbox/win/src/target_services.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sandbox {
 
@@ -33,21 +33,21 @@
 }
 
 template <typename T>
-absl::optional<T> CaptureParameter(const T* parameter) {
+std::optional<T> CaptureParameter(const T* parameter) {
   if (parameter) {
     __try {
       return *parameter;
     } __except (EXCEPTION_EXECUTE_HANDLER) {
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool ValidObjectAttributes(const OBJECT_ATTRIBUTES* object_attributes) {
   if (!object_attributes) {
     return true;
   }
-  absl::optional<OBJECT_ATTRIBUTES> valid_obj_attr =
+  std::optional<OBJECT_ATTRIBUTES> valid_obj_attr =
       CaptureParameter(object_attributes);
   return valid_obj_attr.has_value() && !valid_obj_attr->Attributes &&
          !valid_obj_attr->ObjectName && !valid_obj_attr->RootDirectory &&
@@ -124,7 +124,7 @@
     return status;
   }
 
-  absl::optional<CLIENT_ID> valid_client_id = CaptureParameter(client_id);
+  std::optional<CLIENT_ID> valid_client_id = CaptureParameter(client_id);
   if (!valid_client_id.has_value() || valid_client_id->UniqueProcess) {
     return status;
   }
@@ -187,7 +187,7 @@
     return status;
   }
 
-  absl::optional<CLIENT_ID> valid_client_id = CaptureParameter(client_id);
+  std::optional<CLIENT_ID> valid_client_id = CaptureParameter(client_id);
   if (!valid_client_id.has_value() ||
       valid_client_id->UniqueProcess != GetCurrentClientId().UniqueProcess) {
     return status;
diff --git a/sandbox/win/src/restricted_token.cc b/sandbox/win/src/restricted_token.cc
index ffaa725..07c84b5 100644
--- a/sandbox/win/src/restricted_token.cc
+++ b/sandbox/win/src/restricted_token.cc
@@ -23,13 +23,13 @@
 RestrictedToken::RestrictedToken() = default;
 RestrictedToken::~RestrictedToken() = default;
 
-absl::optional<base::win::AccessToken> RestrictedToken::GetRestrictedToken()
+std::optional<base::win::AccessToken> RestrictedToken::GetRestrictedToken()
     const {
-  absl::optional<base::win::AccessToken> token =
+  std::optional<base::win::AccessToken> token =
       base::win::AccessToken::FromCurrentProcess(/*impersonation=*/false,
                                                  TOKEN_ALL_ACCESS);
   if (!token) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return CreateRestricted(*token);
 }
@@ -100,7 +100,7 @@
   sids_for_default_dacl_.emplace_back(known_sid, access_mode, access, 0);
 }
 
-absl::optional<base::win::AccessToken>
+std::optional<base::win::AccessToken>
 RestrictedToken::GetRestrictedTokenForTesting(base::win::AccessToken& token) {
   return CreateRestricted(token);
 }
@@ -143,7 +143,7 @@
     }
   }
   if (add_restricting_sid_logon_session_) {
-    absl::optional<base::win::Sid> logon_sid = token.LogonId();
+    std::optional<base::win::Sid> logon_sid = token.LogonId();
     if (logon_sid.has_value()) {
       sids.push_back(std::move(*logon_sid));
     }
@@ -151,9 +151,9 @@
   return sids;
 }
 
-absl::optional<base::win::AccessToken> RestrictedToken::CreateRestricted(
+std::optional<base::win::AccessToken> RestrictedToken::CreateRestricted(
     const base::win::AccessToken& token) const {
-  absl::optional<base::win::AccessToken> new_token;
+  std::optional<base::win::AccessToken> new_token;
 
   std::vector<base::win::Sid> deny_sids = BuildDenyOnlySids(token);
   std::vector<base::win::Sid> restrict_sids = BuildRestrictedSids(token);
@@ -169,31 +169,31 @@
   }
 
   if (!new_token) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (delete_all_privileges_ && remove_traversal_privilege_ &&
       !new_token->RemovePrivilege(SE_CHANGE_NOTIFY_NAME)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   std::vector<base::win::ExplicitAccessEntry> dacl_entries;
 
-  absl::optional<base::win::AccessControlList> dacl = new_token->DefaultDacl();
+  std::optional<base::win::AccessControlList> dacl = new_token->DefaultDacl();
   if (!dacl) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (lockdown_default_dacl_) {
     // Don't add Restricted sid and also remove logon sid access.
-    absl::optional<base::win::Sid> logon_sid = new_token->LogonId();
+    std::optional<base::win::Sid> logon_sid = new_token->LogonId();
     if (logon_sid.has_value()) {
       dacl_entries.emplace_back(*logon_sid,
                                 base::win::SecurityAccessMode::kRevoke, 0, 0);
     } else {
       DWORD last_error = ::GetLastError();
       if (last_error != ERROR_NOT_FOUND) {
-        return absl::nullopt;
+        return std::nullopt;
       }
     }
   } else {
@@ -210,16 +210,16 @@
       new_token->User(), base::win::SecurityAccessMode::kGrant, GENERIC_ALL, 0);
 
   if (!dacl->SetEntries(dacl_entries)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (!new_token->SetDefaultDacl(*dacl)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (integrity_rid_.has_value()) {
     if (!new_token->SetIntegrityLevel(*integrity_rid_)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
 
diff --git a/sandbox/win/src/restricted_token.h b/sandbox/win/src/restricted_token.h
index 5e0c70bf..1d7925eb 100644
--- a/sandbox/win/src/restricted_token.h
+++ b/sandbox/win/src/restricted_token.h
@@ -7,12 +7,12 @@
 
 #include <vector>
 
+#include <optional>
 #include "base/win/access_control_list.h"
 #include "base/win/access_token.h"
 #include "base/win/sid.h"
 #include "base/win/windows_types.h"
 #include "sandbox/win/src/security_level.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sandbox {
 
@@ -38,7 +38,7 @@
 
   // Creates a restricted token. This creates a primary token for process
   // creation. If the function fails an empty value is returned.
-  absl::optional<base::win::AccessToken> GetRestrictedToken() const;
+  std::optional<base::win::AccessToken> GetRestrictedToken() const;
 
   // Lists all sids in the token and mark them as Deny Only except for those
   // present in the exceptions parameter. If there is no exception needed,
@@ -129,7 +129,7 @@
 
   // Creates a restricted token. This is only used for testing to change the
   // token used to build the restricted token.
-  absl::optional<base::win::AccessToken> GetRestrictedTokenForTesting(
+  std::optional<base::win::AccessToken> GetRestrictedTokenForTesting(
       base::win::AccessToken& token);
 
  private:
@@ -137,7 +137,7 @@
       const base::win::AccessToken& token) const;
   std::vector<base::win::Sid> BuildRestrictedSids(
       const base::win::AccessToken& token) const;
-  absl::optional<base::win::AccessToken> CreateRestricted(
+  std::optional<base::win::AccessToken> CreateRestricted(
       const base::win::AccessToken& token) const;
 
   // The list of restricting sids in the restricted token.
@@ -147,9 +147,9 @@
   // The list of sids to add to the default DACL of the restricted token.
   std::vector<base::win::ExplicitAccessEntry> sids_for_default_dacl_;
   // The token to restrict, this is only used for testing.
-  absl::optional<base::win::AccessToken> effective_token_;
+  std::optional<base::win::AccessToken> effective_token_;
   // The token integrity level RID.
-  absl::optional<DWORD> integrity_rid_;
+  std::optional<DWORD> integrity_rid_;
   // Lockdown the default DACL when creating new tokens.
   bool lockdown_default_dacl_ = false;
   // Delete all privileges except for SeChangeNotifyPrivilege.
diff --git a/sandbox/win/src/restricted_token_test.cc b/sandbox/win/src/restricted_token_test.cc
index 639dca6..c13b477 100644
--- a/sandbox/win/src/restricted_token_test.cc
+++ b/sandbox/win/src/restricted_token_test.cc
@@ -7,6 +7,7 @@
 #include <stddef.h>
 #include <string>
 
+#include <optional>
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/win/access_token.h"
@@ -16,7 +17,6 @@
 #include "sandbox/win/src/target_services.h"
 #include "sandbox/win/tests/common/controller.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sandbox {
 
@@ -156,7 +156,7 @@
 // Opens a the process token and checks if it's restricted.
 SBOX_TESTS_COMMAND int RestrictedTokenTest_IsRestricted(int argc,
                                                         wchar_t** argv) {
-  absl::optional<base::win::AccessToken> token =
+  std::optional<base::win::AccessToken> token =
       base::win::AccessToken::FromCurrentProcess();
   if (!token)
     return SBOX_TEST_FIRST_ERROR;
diff --git a/sandbox/win/src/restricted_token_unittest.cc b/sandbox/win/src/restricted_token_unittest.cc
index 7475cf2..29e679835 100644
--- a/sandbox/win/src/restricted_token_unittest.cc
+++ b/sandbox/win/src/restricted_token_unittest.cc
@@ -11,6 +11,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/ranges/algorithm.h"
 #include "base/win/access_control_list.h"
 #include "base/win/access_token.h"
@@ -22,7 +23,6 @@
 #include "sandbox/win/src/restricted_token_utils.h"
 #include "sandbox/win/tests/common/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sandbox {
 
@@ -56,7 +56,7 @@
   auto logon_sid = restricted_token.LogonId();
   if (logon_sid) {
     EXPECT_EQ(restricted_required,
-              IsSidInDacl(dacl, true, absl::nullopt, *logon_sid));
+              IsSidInDacl(dacl, true, std::nullopt, *logon_sid));
   }
 }
 
@@ -89,7 +89,7 @@
 }
 
 DWORD GetMandatoryPolicy(const base::win::AccessToken& token) {
-  absl::optional<base::win::SecurityDescriptor> sd =
+  std::optional<base::win::SecurityDescriptor> sd =
       base::win::SecurityDescriptor::FromHandle(
           token.get(), base::win::SecurityObjectType::kKernel,
           LABEL_SECURITY_INFORMATION);
@@ -112,7 +112,7 @@
 }
 
 void CheckUniqueSid(TokenLevel level, bool check_present) {
-  absl::optional<base::win::Sid> random_sid =
+  std::optional<base::win::Sid> random_sid =
       base::win::Sid::GenerateRandomSid();
   auto token = *CreateRestrictedToken(level, INTEGRITY_LEVEL_LAST,
                                       TokenType::kPrimary, false, random_sid);
@@ -125,11 +125,10 @@
 }
 
 void CheckIntegrityLevel(IntegrityLevel integrity_level) {
-  absl::optional<base::win::AccessToken> token =
-      CreateRestrictedToken(USER_LOCKDOWN, integrity_level, TokenType::kPrimary,
-                            false, absl::nullopt);
+  std::optional<base::win::AccessToken> token = CreateRestrictedToken(
+      USER_LOCKDOWN, integrity_level, TokenType::kPrimary, false, std::nullopt);
   ASSERT_TRUE(token);
-  absl::optional<DWORD> rid = GetIntegrityLevelRid(integrity_level);
+  std::optional<DWORD> rid = GetIntegrityLevelRid(integrity_level);
   if (rid) {
     EXPECT_EQ(token->IntegrityLevel(), *rid);
   } else {
@@ -138,8 +137,8 @@
 }
 
 void CheckPrivileges(TokenLevel level, bool delete_all, bool remove_traversal) {
-  absl::optional<base::win::AccessToken> token = CreateRestrictedToken(
-      level, INTEGRITY_LEVEL_LAST, TokenType::kPrimary, false, absl::nullopt);
+  std::optional<base::win::AccessToken> token = CreateRestrictedToken(
+      level, INTEGRITY_LEVEL_LAST, TokenType::kPrimary, false, std::nullopt);
   ASSERT_TRUE(token);
   std::vector<base::win::AccessToken::Privilege> privs = token->Privileges();
   if (remove_traversal) {
@@ -173,15 +172,15 @@
                      const std::vector<base::win::WellKnownSid>& known_sids,
                      bool user,
                      bool logon) {
-  absl::optional<base::win::AccessToken> token = CreateRestrictedToken(
-      level, INTEGRITY_LEVEL_LAST, TokenType::kPrimary, false, absl::nullopt);
+  std::optional<base::win::AccessToken> token = CreateRestrictedToken(
+      level, INTEGRITY_LEVEL_LAST, TokenType::kPrimary, false, std::nullopt);
   std::vector<base::win::Sid> sids =
       base::win::Sid::FromKnownSidVector(known_sids);
   if (user) {
     sids.push_back(token->User());
   }
   if (logon) {
-    absl::optional<base::win::Sid> logon_sid = token->LogonId();
+    std::optional<base::win::Sid> logon_sid = token->LogonId();
     if (logon_sid) {
       sids.push_back(logon_sid->Clone());
     }
@@ -194,8 +193,8 @@
     const std::vector<base::win::WellKnownSid>& known_exceptions,
     bool allow_all,
     bool user) {
-  absl::optional<base::win::AccessToken> token = CreateRestrictedToken(
-      level, INTEGRITY_LEVEL_LAST, TokenType::kPrimary, false, absl::nullopt);
+  std::optional<base::win::AccessToken> token = CreateRestrictedToken(
+      level, INTEGRITY_LEVEL_LAST, TokenType::kPrimary, false, std::nullopt);
   ASSERT_TRUE(token);
   std::vector<base::win::Sid> exceptions =
       base::win::Sid::FromKnownSidVector(known_exceptions);
@@ -220,12 +219,12 @@
 // Tests default initialization of the class.
 TEST(RestrictedTokenTest, DefaultInit) {
   RestrictedToken token_default;
-  absl::optional<base::win::AccessToken> restricted_token =
+  std::optional<base::win::AccessToken> restricted_token =
       token_default.GetRestrictedToken();
   ASSERT_TRUE(restricted_token);
 
   // Get the current process token.
-  absl::optional<base::win::AccessToken> access_token =
+  std::optional<base::win::AccessToken> access_token =
       base::win::AccessToken::FromCurrentProcess();
   ASSERT_TRUE(access_token);
   // Check if both token have the same owner and user.
@@ -242,7 +241,7 @@
   RestrictedToken token;
   token.AddRestrictingSid(base::win::WellKnownSid::kWorld);
 
-  absl::optional<base::win::AccessToken> restricted_token =
+  std::optional<base::win::AccessToken> restricted_token =
       token.GetRestrictedToken();
   ASSERT_TRUE(restricted_token);
   EXPECT_TRUE(restricted_token->IsRestricted());
@@ -276,7 +275,7 @@
   RestrictedToken token;
 
   token.AddSidForDenyOnly(base::win::WellKnownSid::kWorld);
-  absl::optional<base::win::AccessToken> restricted_token =
+  std::optional<base::win::AccessToken> restricted_token =
       token.GetRestrictedToken();
   ASSERT_TRUE(restricted_token);
   base::win::Sid sid(base::win::WellKnownSid::kWorld);
@@ -435,7 +434,7 @@
 
 TEST(RestrictedTokenTest, LockdownDefaultDaclNoLogonSid) {
   ASSERT_TRUE(::ImpersonateAnonymousToken(::GetCurrentThread()));
-  absl::optional<base::win::AccessToken> anonymous_token =
+  std::optional<base::win::AccessToken> anonymous_token =
       base::win::AccessToken::FromCurrentThread(/*open_as_self=*/true,
                                                 TOKEN_ALL_ACCESS);
   ::RevertToSelf();
@@ -461,15 +460,14 @@
 }
 
 TEST(RestrictedTokenTest, TokenType) {
-  absl::optional<base::win::AccessToken> token =
+  std::optional<base::win::AccessToken> token =
       CreateRestrictedToken(USER_LOCKDOWN, INTEGRITY_LEVEL_LAST,
-                            TokenType::kPrimary, false, absl::nullopt);
+                            TokenType::kPrimary, false, std::nullopt);
   ASSERT_TRUE(token);
   EXPECT_FALSE(token->IsImpersonation());
   EXPECT_EQ(DWORD{TOKEN_ALL_ACCESS}, base::win::GetGrantedAccess(token->get()));
-  token =
-      CreateRestrictedToken(USER_LOCKDOWN, INTEGRITY_LEVEL_LAST,
-                            TokenType::kImpersonation, false, absl::nullopt);
+  token = CreateRestrictedToken(USER_LOCKDOWN, INTEGRITY_LEVEL_LAST,
+                                TokenType::kImpersonation, false, std::nullopt);
   ASSERT_TRUE(token);
   EXPECT_TRUE(token->IsImpersonation());
   EXPECT_EQ(token->ImpersonationLevel(),
@@ -526,9 +524,9 @@
   CheckRestricted(USER_LOCKDOWN, {base::win::WellKnownSid::kNull}, false,
                   false);
 
-  absl::optional<base::win::AccessToken> token =
+  std::optional<base::win::AccessToken> token =
       CreateRestrictedToken(USER_RESTRICTED_SAME_ACCESS, INTEGRITY_LEVEL_LAST,
-                            TokenType::kPrimary, false, absl::nullopt);
+                            TokenType::kPrimary, false, std::nullopt);
   ASSERT_TRUE(token);
   std::vector<base::win::Sid> sids;
   sids.push_back(token->User());
diff --git a/sandbox/win/src/restricted_token_utils.cc b/sandbox/win/src/restricted_token_utils.cc
index 050d9d5..9cefa09 100644
--- a/sandbox/win/src/restricted_token_utils.cc
+++ b/sandbox/win/src/restricted_token_utils.cc
@@ -7,6 +7,7 @@
 #include <memory>
 #include <vector>
 
+#include <optional>
 #include "base/check.h"
 #include "base/notreached.h"
 #include "base/win/access_token.h"
@@ -16,7 +17,6 @@
 #include "sandbox/win/src/sandbox_nt_util.h"
 #include "sandbox/win/src/security_level.h"
 #include "sandbox/win/src/win_utils.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sandbox {
 
@@ -29,12 +29,12 @@
 
 }  // namespace
 
-absl::optional<base::win::AccessToken> CreateRestrictedToken(
+std::optional<base::win::AccessToken> CreateRestrictedToken(
     TokenLevel security_level,
     IntegrityLevel integrity_level,
     TokenType token_type,
     bool lockdown_default_dacl,
-    const absl::optional<base::win::Sid>& unique_restricted_sid) {
+    const std::optional<base::win::Sid>& unique_restricted_sid) {
   RestrictedToken restricted_token;
   if (lockdown_default_dacl) {
     restricted_token.SetLockdownDefaultDacl();
@@ -126,7 +126,7 @@
       }
       break;
     case USER_LAST:
-      return absl::nullopt;
+      return std::nullopt;
   }
 
   if (deny_sids) {
@@ -138,10 +138,10 @@
   }
 
   restricted_token.SetIntegrityLevel(integrity_level);
-  absl::optional<base::win::AccessToken> result =
+  std::optional<base::win::AccessToken> result =
       restricted_token.GetRestrictedToken();
   if (!result) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (token_type == TokenType::kPrimary) {
@@ -151,14 +151,14 @@
   result = result->DuplicateImpersonation(
       base::win::SecurityImpersonationLevel::kImpersonation, TOKEN_ALL_ACCESS);
   if (!result) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return result;
 }
 
 DWORD HardenTokenIntegrityLevelPolicy(const base::win::AccessToken& token) {
-  absl::optional<base::win::SecurityDescriptor> sd =
+  std::optional<base::win::SecurityDescriptor> sd =
       base::win::SecurityDescriptor::FromHandle(
           token.get(), base::win::SecurityObjectType::kKernel,
           LABEL_SECURITY_INFORMATION);
diff --git a/sandbox/win/src/restricted_token_utils.h b/sandbox/win/src/restricted_token_utils.h
index a3eb4b4..a638f772 100644
--- a/sandbox/win/src/restricted_token_utils.h
+++ b/sandbox/win/src/restricted_token_utils.h
@@ -5,12 +5,12 @@
 #ifndef SANDBOX_WIN_SRC_RESTRICTED_TOKEN_UTILS_H_
 #define SANDBOX_WIN_SRC_RESTRICTED_TOKEN_UTILS_H_
 
+#include <optional>
 #include "base/win/access_token.h"
 #include "base/win/sid.h"
 #include "base/win/windows_types.h"
 #include "sandbox/win/src/restricted_token.h"
 #include "sandbox/win/src/security_level.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // Contains the utility functions to be able to create restricted tokens based
 // on a security profiles.
@@ -34,12 +34,12 @@
 // other sandboxed processes at the same security level.
 // If the function succeeds, the return value is the restricted token. If it
 // fails then the return value is empty.
-absl::optional<base::win::AccessToken> CreateRestrictedToken(
+std::optional<base::win::AccessToken> CreateRestrictedToken(
     TokenLevel security_level,
     IntegrityLevel integrity_level,
     TokenType token_type,
     bool lockdown_default_dacl,
-    const absl::optional<base::win::Sid>& unique_restricted_sid);
+    const std::optional<base::win::Sid>& unique_restricted_sid);
 
 // Hardens the integrity level policy on a token. Specifically it sets the
 // policy to block read and execute so that a lower privileged process cannot
diff --git a/sandbox/win/src/sandbox.h b/sandbox/win/src/sandbox.h
index b73b7f0..41b70a0 100644
--- a/sandbox/win/src/sandbox.h
+++ b/sandbox/win/src/sandbox.h
@@ -23,12 +23,12 @@
 #include <memory>
 #include <vector>
 
+#include <optional>
 #include "base/containers/span.h"
 #include "base/strings/string_piece.h"
 #include "base/win/windows_types.h"
 #include "sandbox/win/src/sandbox_policy.h"
 #include "sandbox/win/src/sandbox_types.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // sandbox: Google User-Land Application Sandbox
 namespace sandbox {
@@ -194,7 +194,7 @@
   // If no data was provided the span will have a size of zero. This method can
   // be called at any time after Init(), but it is intended to be used sparingly
   // prior to calling LowerToken().
-  virtual absl::optional<base::span<const uint8_t>> GetDelegateData() = 0;
+  virtual std::optional<base::span<const uint8_t>> GetDelegateData() = 0;
 
   // Discards the impersonation token and uses the lower token, call before
   // processing any untrusted data or running third-party code. If this call
diff --git a/sandbox/win/src/sandbox_nt_util.cc b/sandbox/win/src/sandbox_nt_util.cc
index 82e911d..27942c9 100644
--- a/sandbox/win/src/sandbox_nt_util.cc
+++ b/sandbox/win/src/sandbox_nt_util.cc
@@ -10,6 +10,7 @@
 
 #include <string>
 
+#include <optional>
 #include "base/compiler_specific.h"
 #include "base/containers/span.h"
 #include "base/win/pe_image.h"
@@ -17,7 +18,6 @@
 #include "sandbox/win/src/nt_internals.h"
 #include "sandbox/win/src/sandbox_factory.h"
 #include "sandbox/win/src/target_services.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sandbox {
 
@@ -245,12 +245,12 @@
   return g_shared_policy_memory;
 }
 
-absl::optional<base::span<const uint8_t>> GetGlobalDelegateData() {
+std::optional<base::span<const uint8_t>> GetGlobalDelegateData() {
   if (!g_delegate_data_size) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   if (!MapGlobalMemory()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return base::make_span(
       reinterpret_cast<const uint8_t*>(g_shared_delegate_data),
diff --git a/sandbox/win/src/sandbox_nt_util.h b/sandbox/win/src/sandbox_nt_util.h
index 9a42aa9..999c989 100644
--- a/sandbox/win/src/sandbox_nt_util.h
+++ b/sandbox/win/src/sandbox_nt_util.h
@@ -10,11 +10,11 @@
 #include <stdint.h>
 #include <memory>
 
+#include <optional>
 #include "base/containers/span.h"
 #include "base/memory/raw_ptr_exclusion.h"
 #include "sandbox/win/src/nt_internals.h"
 #include "sandbox/win/src/sandbox_nt_types.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // Placement new and delete to be used from ntdll interception code.
 void* __cdecl operator new(size_t size,
@@ -105,7 +105,7 @@
 void* GetGlobalPolicyMemoryForTesting();
 
 // Returns a view of the shared delegate data, or nullopt if none was provided.
-absl::optional<base::span<const uint8_t>> GetGlobalDelegateData();
+std::optional<base::span<const uint8_t>> GetGlobalDelegateData();
 
 // Returns a reference to imported NT functions.
 const NtExports* GetNtExports();
diff --git a/sandbox/win/src/sandbox_policy_base.cc b/sandbox/win/src/sandbox_policy_base.cc
index 4151077e..4e6c0f1 100644
--- a/sandbox/win/src/sandbox_policy_base.cc
+++ b/sandbox/win/src/sandbox_policy_base.cc
@@ -11,6 +11,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/containers/span.h"
 #include "base/functional/callback.h"
 #include "base/logging.h"
@@ -38,7 +39,6 @@
 #include "sandbox/win/src/signed_policy.h"
 #include "sandbox/win/src/target_process.h"
 #include "sandbox/win/src/top_level_dispatcher.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sandbox {
 namespace {
@@ -83,7 +83,7 @@
 bool ReplacePackageSidInDacl(HANDLE token,
                              const base::win::Sid& package_sid,
                              ACCESS_MASK access) {
-  absl::optional<base::win::SecurityDescriptor> sd =
+  std::optional<base::win::SecurityDescriptor> sd =
       base::win::SecurityDescriptor::FromHandle(
           token, base::win::SecurityObjectType::kKernel,
           DACL_SECURITY_INFORMATION);
@@ -190,14 +190,14 @@
   return policy_;
 }
 
-absl::optional<base::span<const uint8_t>> ConfigBase::policy_span() {
+std::optional<base::span<const uint8_t>> ConfigBase::policy_span() {
   if (policy_) {
     // Note: this is not policy().data_size as that relates to internal data,
     // not the entire allocated policy area.
     return base::span<const uint8_t>(reinterpret_cast<uint8_t*>(policy_.get()),
                                      kPolMemSize);
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 std::vector<std::wstring>& ConfigBase::blocklisted_dlls() {
@@ -565,9 +565,9 @@
 }
 
 ResultCode PolicyBase::MakeTokens(
-    absl::optional<base::win::AccessToken>& initial,
-    absl::optional<base::win::AccessToken>& lockdown) {
-  absl::optional<base::win::Sid> random_sid;
+    std::optional<base::win::AccessToken>& initial,
+    std::optional<base::win::AccessToken>& lockdown) {
+  std::optional<base::win::Sid> random_sid;
   if (config()->add_restricting_random_sid()) {
     random_sid = base::win::Sid::GenerateRandomSid();
   }
@@ -576,7 +576,7 @@
   bool lockdown_default_dacl = config()->lockdown_default_dacl();
   // Create the 'naked' token. This will be the permanent token associated
   // with the process and therefore with any thread that is not impersonating.
-  absl::optional<base::win::AccessToken> primary = CreateRestrictedToken(
+  std::optional<base::win::AccessToken> primary = CreateRestrictedToken(
       config()->GetLockdownTokenLevel(), integrity_level, TokenType::kPrimary,
       lockdown_default_dacl, random_sid);
   if (!primary) {
@@ -603,7 +603,7 @@
   // Create the 'better' token. We use this token as the one that the main
   // thread uses when booting up the process. It should contain most of
   // what we need (before reaching main( ))
-  absl::optional<base::win::AccessToken> impersonation = CreateRestrictedToken(
+  std::optional<base::win::AccessToken> impersonation = CreateRestrictedToken(
       config()->GetInitialTokenLevel(), integrity_level,
       TokenType::kImpersonation, lockdown_default_dacl, random_sid);
   if (!impersonation) {
@@ -760,11 +760,11 @@
   return handle_closer->InitializeTargetHandles(target);
 }
 
-absl::optional<base::span<const uint8_t>> PolicyBase::delegate_data_span() {
+std::optional<base::span<const uint8_t>> PolicyBase::delegate_data_span() {
   if (delegate_data_) {
     return base::make_span(*delegate_data_);
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void PolicyBase::AddDelegateData(base::span<const uint8_t> data) {
diff --git a/sandbox/win/src/sandbox_policy_base.h b/sandbox/win/src/sandbox_policy_base.h
index 22f872d..4246a43 100644
--- a/sandbox/win/src/sandbox_policy_base.h
+++ b/sandbox/win/src/sandbox_policy_base.h
@@ -13,6 +13,7 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/compiler_specific.h"
 #include "base/containers/span.h"
 #include "base/dcheck_is_on.h"
@@ -30,7 +31,6 @@
 #include "sandbox/win/src/policy_engine_opcodes.h"
 #include "sandbox/win/src/policy_engine_params.h"
 #include "sandbox/win/src/sandbox_policy.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sandbox {
 
@@ -117,7 +117,7 @@
 
   // Should only be called once the object is configured.
   PolicyGlobal* policy();
-  absl::optional<base::span<const uint8_t>> policy_span();
+  std::optional<base::span<const uint8_t>> policy_span();
   std::vector<std::wstring>& blocklisted_dlls();
   AppContainerBase* app_container();
   IntegrityLevel integrity_level() { return integrity_level_; }
@@ -196,8 +196,8 @@
 
   // Creates the two tokens with the levels specified in a previous call to
   // SetTokenLevel().
-  ResultCode MakeTokens(absl::optional<base::win::AccessToken>& initial,
-                        absl::optional<base::win::AccessToken>& lockdown);
+  ResultCode MakeTokens(std::optional<base::win::AccessToken>& initial,
+                        std::optional<base::win::AccessToken>& lockdown);
 
   // Applies the sandbox to |target| and takes ownership. Internally a
   // call to TargetProcess::Init() is issued.
@@ -239,7 +239,7 @@
   // time.
 
   // Returns nullopt if no data has been set, or a view into the data.
-  absl::optional<base::span<const uint8_t>> delegate_data_span();
+  std::optional<base::span<const uint8_t>> delegate_data_span();
 
   // The user-defined global policy settings.
   HANDLE stdout_handle_;
diff --git a/sandbox/win/src/sandbox_policy_diagnostic.cc b/sandbox/win/src/sandbox_policy_diagnostic.cc
index 1b4c459..e9a52fb 100644
--- a/sandbox/win/src/sandbox_policy_diagnostic.cc
+++ b/sandbox/win/src/sandbox_policy_diagnostic.cc
@@ -108,7 +108,7 @@
 }
 
 std::wstring GetSidAsString(const base::win::Sid& sid) {
-  absl::optional<std::wstring> result = sid.ToSddlString();
+  std::optional<std::wstring> result = sid.ToSddlString();
   if (!result) {
     DCHECK(false) << "Failed to make sddl string";
     return L"";
diff --git a/sandbox/win/src/sandbox_policy_diagnostic.h b/sandbox/win/src/sandbox_policy_diagnostic.h
index 0277435..17564e8 100644
--- a/sandbox/win/src/sandbox_policy_diagnostic.h
+++ b/sandbox/win/src/sandbox_policy_diagnostic.h
@@ -11,6 +11,7 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/win/sid.h"
 #include "sandbox/win/src/app_container.h"
 #include "sandbox/win/src/handle_closer.h"
@@ -18,7 +19,6 @@
 #include "sandbox/win/src/process_mitigations.h"
 #include "sandbox/win/src/sandbox.h"
 #include "sandbox/win/src/security_level.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sandbox {
 
@@ -46,7 +46,7 @@
   JobLevel job_level_ = JobLevel::kUnprotected;
   IntegrityLevel desired_integrity_level_ = INTEGRITY_LEVEL_LAST;
   MitigationFlags desired_mitigations_ = 0;
-  absl::optional<base::win::Sid> app_container_sid_;
+  std::optional<base::win::Sid> app_container_sid_;
   // Only populated if |app_container_sid_| is present.
   std::vector<base::win::Sid> capabilities_;
   // Only populated if |app_container_sid_| is present.
diff --git a/sandbox/win/src/target_process.cc b/sandbox/win/src/target_process.cc
index d3c1324..d2172fe 100644
--- a/sandbox/win/src/target_process.cc
+++ b/sandbox/win/src/target_process.cc
@@ -79,7 +79,7 @@
 // Checks that the impersonation token was applied successfully and hasn't been
 // reverted to an identification level token.
 bool CheckImpersonationToken(HANDLE thread) {
-  absl::optional<base::win::AccessToken> token =
+  std::optional<base::win::AccessToken> token =
       base::win::AccessToken::FromThread(thread);
   if (!token.has_value()) {
     return false;
@@ -252,8 +252,8 @@
 // an IPC it will eventually call the dispatcher.
 ResultCode TargetProcess::Init(
     Dispatcher* ipc_dispatcher,
-    absl::optional<base::span<const uint8_t>> policy,
-    absl::optional<base::span<const uint8_t>> delegate_data,
+    std::optional<base::span<const uint8_t>> policy,
+    std::optional<base::span<const uint8_t>> delegate_data,
     uint32_t shared_IPC_size,
     DWORD* win_error) {
   ResultCode ret = VerifySentinels();
diff --git a/sandbox/win/src/target_process.h b/sandbox/win/src/target_process.h
index aea55b2..6b0efac 100644
--- a/sandbox/win/src/target_process.h
+++ b/sandbox/win/src/target_process.h
@@ -59,8 +59,8 @@
   // Creates the IPC objects such as the BrokerDispatcher and the
   // IPC server. The IPC server uses the services of the thread_pool.
   ResultCode Init(Dispatcher* ipc_dispatcher,
-                  absl::optional<base::span<const uint8_t>> policy,
-                  absl::optional<base::span<const uint8_t>> delegate_data,
+                  std::optional<base::span<const uint8_t>> policy,
+                  std::optional<base::span<const uint8_t>> delegate_data,
                   uint32_t shared_IPC_size,
                   DWORD* win_error);
 
diff --git a/sandbox/win/src/target_services.cc b/sandbox/win/src/target_services.cc
index 4429a2d5..603ed9b 100644
--- a/sandbox/win/src/target_services.cc
+++ b/sandbox/win/src/target_services.cc
@@ -12,6 +12,7 @@
 #include <process.h>
 #include <stdint.h>
 
+#include <optional>
 #include "base/containers/span.h"
 #include "base/logging.h"
 #include "base/win/access_token.h"
@@ -26,7 +27,6 @@
 #include "sandbox/win/src/sandbox_nt_util.h"
 #include "sandbox/win/src/sandbox_types.h"
 #include "sandbox/win/src/sharedmem_ipc_client.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sandbox {
 namespace {
@@ -115,13 +115,13 @@
 }
 
 bool SetProcessIntegrityLevel(IntegrityLevel integrity_level) {
-  absl::optional<DWORD> rid = GetIntegrityLevelRid(integrity_level);
+  std::optional<DWORD> rid = GetIntegrityLevelRid(integrity_level);
   if (!rid) {
     // No mandatory level specified, we don't change it.
     return true;
   }
 
-  absl::optional<base::win::AccessToken> token =
+  std::optional<base::win::AccessToken> token =
       base::win::AccessToken::FromCurrentProcess(/*impersonation=*/false,
                                                  TOKEN_ADJUST_DEFAULT);
   if (!token) {
@@ -149,8 +149,7 @@
   return SBOX_ALL_OK;
 }
 
-absl::optional<base::span<const uint8_t>>
-TargetServicesBase::GetDelegateData() {
+std::optional<base::span<const uint8_t>> TargetServicesBase::GetDelegateData() {
   CHECK(process_state_.InitCalled());
   return sandbox::GetGlobalDelegateData();
 }
diff --git a/sandbox/win/src/target_services.h b/sandbox/win/src/target_services.h
index 45b98fc..a6c2bdede 100644
--- a/sandbox/win/src/target_services.h
+++ b/sandbox/win/src/target_services.h
@@ -5,10 +5,10 @@
 #ifndef SANDBOX_WIN_SRC_TARGET_SERVICES_H_
 #define SANDBOX_WIN_SRC_TARGET_SERVICES_H_
 
+#include <optional>
 #include "base/containers/span.h"
 #include "sandbox/win/src/sandbox.h"
 #include "sandbox/win/src/win_utils.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sandbox {
 
@@ -50,7 +50,7 @@
 
   // Public interface of TargetServices. See comments in sandbox.h.
   ResultCode Init() override;
-  absl::optional<base::span<const uint8_t>> GetDelegateData() override;
+  std::optional<base::span<const uint8_t>> GetDelegateData() override;
   void LowerToken() override;
   ProcessState* GetState() override;
 
diff --git a/sandbox/win/src/win_utils.cc b/sandbox/win/src/win_utils.cc
index afdddac..9af6506d 100644
--- a/sandbox/win/src/win_utils.cc
+++ b/sandbox/win/src/win_utils.cc
@@ -205,7 +205,7 @@
   return EqualPath(path, start, kPipe, std::size(kPipe) - 1);
 }
 
-absl::optional<std::wstring> ResolveRegistryName(std::wstring name) {
+std::optional<std::wstring> ResolveRegistryName(std::wstring name) {
   for (size_t i = 0; i < std::size(kKnownKey); ++i) {
     if (name.find(kKnownKey[i].name) == 0) {
       HKEY key;
@@ -213,20 +213,20 @@
       if (ERROR_SUCCESS != ::RegCreateKeyEx(kKnownKey[i].key, L"", 0, nullptr,
                                             0, MAXIMUM_ALLOWED, nullptr, &key,
                                             &disposition)) {
-        return absl::nullopt;
+        return std::nullopt;
       }
 
       auto result = GetPathFromHandle(key);
       ::RegCloseKey(key);
 
       if (!result)
-        return absl::nullopt;
+        return std::nullopt;
 
       result->append(name.substr(wcslen(kKnownKey[i].name)));
       return result;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 // |full_path| can have any of the following forms:
@@ -442,19 +442,19 @@
   return false;
 }
 
-absl::optional<std::wstring> GetNtPathFromWin32Path(const std::wstring& path) {
+std::optional<std::wstring> GetNtPathFromWin32Path(const std::wstring& path) {
   base::win::ScopedHandle file(::CreateFileW(
       path.c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
       nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr));
   if (!file.IsValid())
-    return absl::nullopt;
+    return std::nullopt;
   return GetPathFromHandle(file.Get());
 }
 
-absl::optional<std::wstring> GetPathFromHandle(HANDLE handle) {
+std::optional<std::wstring> GetPathFromHandle(HANDLE handle) {
   auto buffer = QueryObjectInformation(handle, ObjectNameInformation, 512);
   if (!buffer)
-    return absl::nullopt;
+    return std::nullopt;
   OBJECT_NAME_INFORMATION* name =
       reinterpret_cast<OBJECT_NAME_INFORMATION*>(buffer->data());
   return std::wstring(
@@ -462,12 +462,12 @@
       name->ObjectName.Length / sizeof(name->ObjectName.Buffer[0]));
 }
 
-absl::optional<std::wstring> GetTypeNameFromHandle(HANDLE handle) {
+std::optional<std::wstring> GetTypeNameFromHandle(HANDLE handle) {
   // No typename is currently longer than 32 characters on Windows 11, so use a
   // hint of 128 bytes.
   auto buffer = QueryObjectInformation(handle, ObjectTypeInformation, 128);
   if (!buffer)
-    return absl::nullopt;
+    return std::nullopt;
   OBJECT_TYPE_INFORMATION* name =
       reinterpret_cast<OBJECT_TYPE_INFORMATION*>(buffer->data());
   return std::wstring(name->Name.Buffer,
@@ -539,10 +539,10 @@
   return base_address;
 }
 
-absl::optional<ProcessHandleMap> GetCurrentProcessHandles() {
+std::optional<ProcessHandleMap> GetCurrentProcessHandles() {
   DWORD handle_count;
   if (!::GetProcessHandleCount(::GetCurrentProcess(), &handle_count))
-    return absl::nullopt;
+    return std::nullopt;
 
   // The system call will return only handles up to the buffer size so add a
   // margin of error of an additional 1000 handles.
@@ -554,7 +554,7 @@
 
   if (!NT_SUCCESS(status)) {
     ::SetLastError(GetLastErrorFromNtStatus(status));
-    return absl::nullopt;
+    return std::nullopt;
   }
   DCHECK(buffer.size() >= return_length);
   DCHECK((buffer.size() % sizeof(uint32_t)) == 0);
diff --git a/sandbox/win/src/win_utils.h b/sandbox/win/src/win_utils.h
index e416d6c..0f62c236 100644
--- a/sandbox/win/src/win_utils.h
+++ b/sandbox/win/src/win_utils.h
@@ -12,8 +12,8 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/win/windows_types.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sandbox {
 
@@ -71,20 +71,20 @@
 bool SameObject(HANDLE handle, const wchar_t* full_path);
 
 // Resolves a handle to an nt path or nullopt if the path cannot be resolved.
-absl::optional<std::wstring> GetPathFromHandle(HANDLE handle);
+std::optional<std::wstring> GetPathFromHandle(HANDLE handle);
 
 // Resolves a win32 path to an nt path using GetPathFromHandle. The path must
 // exist. Returns the path if the translation was successful.
-absl::optional<std::wstring> GetNtPathFromWin32Path(const std::wstring& path);
+std::optional<std::wstring> GetNtPathFromWin32Path(const std::wstring& path);
 
 // Resolves a handle to its type name. Returns the typename if successful.
-absl::optional<std::wstring> GetTypeNameFromHandle(HANDLE handle);
+std::optional<std::wstring> GetTypeNameFromHandle(HANDLE handle);
 
 // Resolves a user-readable registry path to a system-readable registry path.
 // For example, HKEY_LOCAL_MACHINE\\Software\\microsoft is translated to
 // \\registry\\machine\\software\\microsoft. Returns nullopt if the path
 // cannot be resolved.
-absl::optional<std::wstring> ResolveRegistryName(std::wstring name);
+std::optional<std::wstring> ResolveRegistryName(std::wstring name);
 
 // Allocates |buffer_bytes| in child (PAGE_READWRITE) and copies data
 // from |local_buffer| in this process into |child|. |remote_buffer|
@@ -113,7 +113,7 @@
 // value is returned. Note that unless all threads are suspended in the process
 // the valid handles could change between the return of the list and when you
 // use them.
-absl::optional<ProcessHandleMap> GetCurrentProcessHandles();
+std::optional<ProcessHandleMap> GetCurrentProcessHandles();
 
 }  // namespace sandbox
 
diff --git a/sandbox/win/src/win_utils_unittest.cc b/sandbox/win/src/win_utils_unittest.cc
index 400f09b..4ca9e3a 100644
--- a/sandbox/win/src/win_utils_unittest.cc
+++ b/sandbox/win/src/win_utils_unittest.cc
@@ -99,7 +99,7 @@
   EXPECT_TRUE(base::Contains(entry->second, handle.Get()));
 }
 
-void TestCurrentProcessHandles(absl::optional<ProcessHandleMap> (*func)()) {
+void TestCurrentProcessHandles(std::optional<ProcessHandleMap> (*func)()) {
   std::wstring random_name = GetRandomName();
   ASSERT_FALSE(random_name.empty());
   base::win::ScopedHandle event_handle(
@@ -111,7 +111,7 @@
       PIPE_UNLIMITED_INSTANCES, 0, 0, NMPWAIT_USE_DEFAULT_WAIT, nullptr));
   ASSERT_TRUE(pipe_handle.IsValid());
 
-  absl::optional<ProcessHandleMap> handle_map = func();
+  std::optional<ProcessHandleMap> handle_map = func();
   ASSERT_TRUE(handle_map);
   EXPECT_LE(2U, handle_map->size());
   FindHandle(*handle_map, L"Event", event_handle);
diff --git a/sandbox/win/src/window.cc b/sandbox/win/src/window.cc
index ad552760..95a1f1c 100644
--- a/sandbox/win/src/window.cc
+++ b/sandbox/win/src/window.cc
@@ -6,11 +6,11 @@
 
 #include <windows.h>
 
+#include <optional>
 #include "base/notreached.h"
 #include "base/win/security_descriptor.h"
 #include "base/win/sid.h"
 #include "base/win/win_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sandbox {
 
@@ -21,7 +21,7 @@
   if (!current_winsta)
     return SBOX_ERROR_CANNOT_GET_WINSTATION;
 
-  absl::optional<base::win::SecurityDescriptor> sd =
+  std::optional<base::win::SecurityDescriptor> sd =
       base::win::SecurityDescriptor::FromHandle(
           current_winsta, base::win::SecurityObjectType::kWindowStation,
           DACL_SECURITY_INFORMATION);
@@ -69,7 +69,7 @@
 
   // Get the security attributes from the current desktop, we will use this as
   // the base security attributes for the new desktop.
-  absl::optional<base::win::SecurityDescriptor> sd =
+  std::optional<base::win::SecurityDescriptor> sd =
       base::win::SecurityDescriptor::FromHandle(
           current_desktop, base::win::SecurityObjectType::kDesktop,
           DACL_SECURITY_INFORMATION);
diff --git a/sandbox/win/tests/common/test_utils.cc b/sandbox/win/tests/common/test_utils.cc
index 6adb1767..8df7b1d 100644
--- a/sandbox/win/tests/common/test_utils.cc
+++ b/sandbox/win/tests/common/test_utils.cc
@@ -80,7 +80,7 @@
 
 bool IsSidInDacl(const base::win::AccessControlList& dacl,
                  bool allowed,
-                 absl::optional<ACCESS_MASK> mask,
+                 std::optional<ACCESS_MASK> mask,
                  const base::win::Sid& sid) {
   DWORD ace_type = allowed ? ACCESS_ALLOWED_ACE_TYPE : ACCESS_DENIED_ACE_TYPE;
   PACL pacl = dacl.get();
diff --git a/sandbox/win/tests/common/test_utils.h b/sandbox/win/tests/common/test_utils.h
index 8560269..7788155 100644
--- a/sandbox/win/tests/common/test_utils.h
+++ b/sandbox/win/tests/common/test_utils.h
@@ -5,9 +5,9 @@
 #ifndef SANDBOX_WIN_TESTS_COMMON_TEST_UTILS_H_
 #define SANDBOX_WIN_TESTS_COMMON_TEST_UTILS_H_
 
+#include <optional>
 #include "base/win/access_control_list.h"
 #include "base/win/windows_types.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sandbox {
 
@@ -27,7 +27,7 @@
 // Returns true if the SID and access mask is present.
 bool IsSidInDacl(const base::win::AccessControlList& dacl,
                  bool allowed,
-                 absl::optional<ACCESS_MASK> mask,
+                 std::optional<ACCESS_MASK> mask,
                  const base::win::Sid& sid);
 
 }  // namespace sandbox
diff --git a/skia/public/mojom/image_info_mojom_traits.cc b/skia/public/mojom/image_info_mojom_traits.cc
index fe5a01a..25c8dab 100644
--- a/skia/public/mojom/image_info_mojom_traits.cc
+++ b/skia/public/mojom/image_info_mojom_traits.cc
@@ -4,11 +4,11 @@
 
 #include "skia/public/mojom/image_info_mojom_traits.h"
 
+#include <optional>
 #include "base/notreached.h"
 #include "base/numerics/checked_math.h"
 #include "base/numerics/safe_conversions.h"
 #include "mojo/public/cpp/bindings/array_data_view.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkColorSpace.h"
 #include "third_party/skia/modules/skcms/skcms.h"
 
@@ -16,7 +16,7 @@
 
 namespace {
 
-absl::optional<SkImageInfo> MakeSkImageInfo(
+std::optional<SkImageInfo> MakeSkImageInfo(
     SkColorType color_type,
     SkAlphaType alpha_type,
     int width,
@@ -24,7 +24,7 @@
     mojo::ArrayDataView<float> color_transfer_function,
     mojo::ArrayDataView<float> color_to_xyz_matrix) {
   if (width < 0 || height < 0) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   sk_sp<SkColorSpace> color_space;
   if (!color_transfer_function.is_null() && !color_to_xyz_matrix.is_null()) {
@@ -33,7 +33,7 @@
     // TODO(crbug.com/1394542): Mojo should validate this array size. We can CHECK it instead
     // when it does.
     if (color_transfer_function.size() != 7u) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     transfer_function.g = data[0];
     transfer_function.a = data[1];
@@ -47,7 +47,7 @@
     // TODO(crbug.com/1394542): Mojo should validate this array size. We can CHECK it instead
     // when it does.
     if (color_to_xyz_matrix.size() != 9u) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     memcpy(to_xyz_matrix.vals, color_to_xyz_matrix.data(), 9 * sizeof(float));
     color_space = SkColorSpace::MakeRGB(transfer_function, to_xyz_matrix);
@@ -168,12 +168,12 @@
 }
 
 // static
-absl::optional<std::vector<float>>
+std::optional<std::vector<float>>
 StructTraits<skia::mojom::ImageInfoDataView,
              SkImageInfo>::color_transfer_function(const SkImageInfo& info) {
   SkColorSpace* color_space = info.colorSpace();
   if (!color_space) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   skcms_TransferFunction fn;
   color_space->transferFn(&fn);
@@ -181,12 +181,12 @@
 }
 
 // static
-absl::optional<std::vector<float>>
+std::optional<std::vector<float>>
 StructTraits<skia::mojom::ImageInfoDataView, SkImageInfo>::color_to_xyz_matrix(
     const SkImageInfo& info) {
   SkColorSpace* color_space = info.colorSpace();
   if (!color_space) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   skcms_Matrix3x3 to_xyz_matrix;
   CHECK(color_space->toXYZD50(&to_xyz_matrix));
@@ -222,7 +222,7 @@
     return false;
   }
 
-  absl::optional<SkImageInfo> maybe_info = MakeSkImageInfo(
+  std::optional<SkImageInfo> maybe_info = MakeSkImageInfo(
       color_type, alpha_type, width.ValueOrDie(), height.ValueOrDie(),
       std::move(color_transfer_function), std::move(color_to_xyz_matrix));
   if (!maybe_info.has_value()) {
@@ -254,7 +254,7 @@
     return false;
   }
 
-  absl::optional<SkImageInfo> maybe_info = MakeSkImageInfo(
+  std::optional<SkImageInfo> maybe_info = MakeSkImageInfo(
       kN32_SkColorType, alpha_type, width.ValueOrDie(), height.ValueOrDie(),
       std::move(color_transfer_function), std::move(color_to_xyz_matrix));
   if (!maybe_info.has_value()) {
diff --git a/skia/public/mojom/image_info_mojom_traits.h b/skia/public/mojom/image_info_mojom_traits.h
index 25f3f3a..e1269f9 100644
--- a/skia/public/mojom/image_info_mojom_traits.h
+++ b/skia/public/mojom/image_info_mojom_traits.h
@@ -7,9 +7,9 @@
 
 #include <vector>
 
+#include <optional>
 #include "base/component_export.h"
 #include "skia/public/mojom/image_info.mojom-shared.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkImageInfo.h"
 
 namespace mojo {
@@ -39,9 +39,9 @@
   }
   static uint32_t width(const SkImageInfo& info);
   static uint32_t height(const SkImageInfo& info);
-  static absl::optional<std::vector<float>> color_transfer_function(
+  static std::optional<std::vector<float>> color_transfer_function(
       const SkImageInfo& info);
-  static absl::optional<std::vector<float>> color_to_xyz_matrix(
+  static std::optional<std::vector<float>> color_to_xyz_matrix(
       const SkImageInfo& info);
 
   static bool Read(skia::mojom::ImageInfoDataView data, SkImageInfo* info);
@@ -61,11 +61,11 @@
   static uint32_t height(const SkImageInfo& info) {
     return ImageInfoStructTraits::height(info);
   }
-  static absl::optional<std::vector<float>> color_transfer_function(
+  static std::optional<std::vector<float>> color_transfer_function(
       const SkImageInfo& info) {
     return ImageInfoStructTraits::color_transfer_function(info);
   }
-  static absl::optional<std::vector<float>> color_to_xyz_matrix(
+  static std::optional<std::vector<float>> color_to_xyz_matrix(
       const SkImageInfo& info) {
     return ImageInfoStructTraits::color_to_xyz_matrix(info);
   }
diff --git a/sql/database.cc b/sql/database.cc
index 2b71910..751dd17 100644
--- a/sql/database.cc
+++ b/sql/database.cc
@@ -254,7 +254,7 @@
     // allowing disk access.
     // TODO(paivanof@gmail.com): This should move to the beginning
     // of the function. http://crbug.com/136655.
-    absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
+    std::optional<base::ScopedBlockingCall> scoped_blocking_call;
     InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
 
     // `stmt_` references memory loaned from the sqlite3 library. Stop
@@ -387,7 +387,7 @@
     // will happen on thread not allowing disk access.
     // TODO(paivanof@gmail.com): This should move to the beginning
     // of the function. http://crbug.com/136655.
-    absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
+    std::optional<base::ScopedBlockingCall> scoped_blocking_call;
     InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
 
     // Resetting acquires a lock to ensure no dump is happening on the database
@@ -446,7 +446,7 @@
   CHECK(!options_.exclusive_database_file_lock)
       << "Cannot preload an exclusively locked database.";
 
-  absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
+  std::optional<base::ScopedBlockingCall> scoped_blocking_call;
   InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
 
   // Maximum number of bytes that will be prefetched from the database.
@@ -794,7 +794,7 @@
 size_t Database::ComputeMmapSizeForOpen() {
   TRACE_EVENT0("sql", "Database::ComputeMmapSizeForOpen");
 
-  absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
+  std::optional<base::ScopedBlockingCall> scoped_blocking_call;
   InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
 
   // How much to map if no errors are found.  50MB encompasses the 99th
@@ -974,7 +974,7 @@
 bool Database::Raze() {
   TRACE_EVENT0("sql", "Database::Raze");
 
-  absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
+  std::optional<base::ScopedBlockingCall> scoped_blocking_call;
   InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
 
   if (!db_) {
@@ -1324,7 +1324,7 @@
     return SqliteResultCode::kError;
   }
 
-  absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
+  std::optional<base::ScopedBlockingCall> scoped_blocking_call;
   InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
 
   SqliteResultCode sqlite_result_code = SqliteResultCode::kOk;
@@ -1442,7 +1442,7 @@
     return false;
   }
 
-  absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
+  std::optional<base::ScopedBlockingCall> scoped_blocking_call;
   InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
 
   while (*sql_script) {
@@ -1525,7 +1525,7 @@
   if (!db_)
     return base::MakeRefCounted<StatementRef>(nullptr, nullptr, poisoned_);
 
-  absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
+  std::optional<base::ScopedBlockingCall> scoped_blocking_call;
   InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
 
 #if DCHECK_IS_ON()
@@ -1612,7 +1612,7 @@
 bool Database::IsSQLValid(const char* sql) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
+  std::optional<base::ScopedBlockingCall> scoped_blocking_call;
   InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
   if (!db_) {
     DCHECK(poisoned_) << "Illegal use of Database without a db";
@@ -1807,7 +1807,7 @@
     return false;
   }
 
-  absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
+  std::optional<base::ScopedBlockingCall> scoped_blocking_call;
   InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
 
   EnsureSqliteInitialized();
@@ -2293,7 +2293,7 @@
 
 bool Database::CheckpointDatabase() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
+  std::optional<base::ScopedBlockingCall> scoped_blocking_call;
   InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
 
   auto sqlite_result_code = ToSqliteResultCode(sqlite3_wal_checkpoint_v2(
diff --git a/sql/database.h b/sql/database.h
index 7917287..ac4a920 100644
--- a/sql/database.h
+++ b/sql/database.h
@@ -14,6 +14,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/containers/flat_map.h"
 #include "base/dcheck_is_on.h"
@@ -33,7 +34,6 @@
 #include "sql/sqlite_result_code.h"
 #include "sql/sqlite_result_code_values.h"
 #include "sql/statement_id.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // Forward declaration for SQLite structures. Headers in the public sql:: API
 // must NOT include sqlite3.h.
@@ -764,7 +764,7 @@
   // declare its blocking execution scope (see https://www.crbug/934302).
   void InitScopedBlockingCall(
       const base::Location& from_here,
-      absl::optional<base::ScopedBlockingCall>* scoped_blocking_call) const {
+      std::optional<base::ScopedBlockingCall>* scoped_blocking_call) const {
     if (!in_memory_)
       scoped_blocking_call->emplace(from_here, base::BlockingType::MAY_BLOCK);
   }
@@ -831,7 +831,7 @@
     // declare its blocking execution scope (see https://www.crbug/934302).
     void InitScopedBlockingCall(
         const base::Location& from_here,
-        absl::optional<base::ScopedBlockingCall>* scoped_blocking_call) const {
+        std::optional<base::ScopedBlockingCall>* scoped_blocking_call) const {
       if (database_)
         database_->InitScopedBlockingCall(from_here, scoped_blocking_call);
     }
diff --git a/sql/database_options_unittest.cc b/sql/database_options_unittest.cc
index f90e9c9..932c4693 100644
--- a/sql/database_options_unittest.cc
+++ b/sql/database_options_unittest.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <optional>
 #include "base/files/file_path.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/functional/callback_helpers.h"
@@ -12,7 +13,6 @@
 #include "sql/test/test_helpers.h"
 #include "sql/transaction.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/sqlite/sqlite3.h"
 
 namespace sql {
diff --git a/sql/recover_module/parsing.cc b/sql/recover_module/parsing.cc
index 5bc32a49..b1c7289 100644
--- a/sql/recover_module/parsing.cc
+++ b/sql/recover_module/parsing.cc
@@ -9,12 +9,12 @@
 #include <tuple>
 #include <utility>
 
+#include <optional>
 #include "base/check.h"
 #include "base/notreached.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_piece.h"
 #include "sql/recover_module/record.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sql {
 namespace recover {
@@ -63,7 +63,7 @@
 constexpr base::StringPiece kNonNullSql1("NOT");
 constexpr base::StringPiece kNonNullSql2("NULL");
 
-absl::optional<ModuleColumnType> ParseColumnType(
+std::optional<ModuleColumnType> ParseColumnType(
     base::StringPiece column_type_sql) {
   if (column_type_sql == kIntegerSql)
     return ModuleColumnType::kInteger;
@@ -80,7 +80,7 @@
   if (column_type_sql == kAnySql)
     return ModuleColumnType::kAny;
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 // Returns a view into a SQL string representing the column type.
@@ -151,7 +151,7 @@
 
   base::StringPiece column_type_sql;
   std::tie(column_type_sql, sql) = SplitToken(sql);
-  absl::optional<ModuleColumnType> column_type =
+  std::optional<ModuleColumnType> column_type =
       ParseColumnType(column_type_sql);
   if (!column_type.has_value()) {
     // Invalid column type.
diff --git a/sql/recover_module/table.cc b/sql/recover_module/table.cc
index fbd31a0..7e852bf2 100644
--- a/sql/recover_module/table.cc
+++ b/sql/recover_module/table.cc
@@ -4,6 +4,7 @@
 
 #include "sql/recover_module/table.h"
 
+#include <optional>
 #include "base/check_op.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_piece.h"
@@ -11,7 +12,6 @@
 #include "sql/recover_module/cursor.h"
 #include "sql/recover_module/integers.h"
 #include "sql/recover_module/pager.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace sql {
 namespace recover {
@@ -21,12 +21,12 @@
 // Returns a null optional if the operation fails in any way. The failure is
 // most likely due to an incorrect table spec (missing attachment or table).
 // Corrupted SQLite metadata can cause failures here.
-absl::optional<int> GetTableRootPageId(sqlite3* sqlite_db,
-                                       const TargetTableSpec& table) {
+std::optional<int> GetTableRootPageId(sqlite3* sqlite_db,
+                                      const TargetTableSpec& table) {
   if (table.table_name == "sqlite_schema") {
     // The sqlite_schema table is always rooted at the first page.
     // SQLite page IDs use 1-based indexing.
-    return absl::optional<int64_t>(1);
+    return std::optional<int64_t>(1);
   }
 
   std::string select_sql =
@@ -37,7 +37,7 @@
                          SQLITE_PREPARE_NO_VTAB, &sqlite_statement,
                          nullptr) != SQLITE_OK) {
     // The sqlite_schema table is missing or its schema is corrupted.
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (sqlite3_bind_text(sqlite_statement, 1, table.table_name.c_str(),
@@ -45,13 +45,13 @@
                         SQLITE_STATIC) != SQLITE_OK) {
     // Binding the table name failed. This shouldn't happen.
     sqlite3_finalize(sqlite_statement);
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (sqlite3_step(sqlite_statement) != SQLITE_ROW) {
     // The database attachment point or table does not exist.
     sqlite3_finalize(sqlite_statement);
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   int64_t root_page = sqlite3_column_int64(sqlite_statement, 0);
@@ -59,13 +59,13 @@
 
   if (!DatabasePageReader::IsValidPageId(root_page)) {
     // Database corruption.
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   static_assert(
       DatabasePageReader::kMaxPageId <= std::numeric_limits<int>::max(),
       "Converting the page ID to int may overflow");
-  return absl::make_optional(static_cast<int>(root_page));
+  return std::make_optional(static_cast<int>(root_page));
 }
 
 // Returns (SQLite status, a SQLite database's page size).
@@ -126,7 +126,7 @@
     std::vector<RecoveredColumnSpec> column_specs) {
   DCHECK(backing_table_spec.IsValid());
 
-  absl::optional<int64_t> backing_table_root_page_id =
+  std::optional<int64_t> backing_table_root_page_id =
       GetTableRootPageId(sqlite_db, backing_table_spec);
   if (!backing_table_root_page_id.has_value()) {
     // Either the backing table specification is incorrect, or the database
diff --git a/sql/sandboxed_vfs.cc b/sql/sandboxed_vfs.cc
index d1fea53a..a0f850c 100644
--- a/sql/sandboxed_vfs.cc
+++ b/sql/sandboxed_vfs.cc
@@ -195,7 +195,7 @@
 
 int SandboxedVfs::Access(const char* full_path, int flags, int& result) {
   DCHECK(full_path);
-  absl::optional<PathAccessInfo> access =
+  std::optional<PathAccessInfo> access =
       delegate_->GetPathAccess(base::FilePath::FromUTF8Unsafe(full_path));
   if (!access) {
     result = 0;
diff --git a/sql/sandboxed_vfs.h b/sql/sandboxed_vfs.h
index 93ae6098..b454fb2 100644
--- a/sql/sandboxed_vfs.h
+++ b/sql/sandboxed_vfs.h
@@ -8,12 +8,13 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/files/file.h"
 #include "base/files/file_path.h"
 #include "base/time/time.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/sqlite/sqlite3.h"
 
 namespace sql {
@@ -58,7 +59,7 @@
 
     // Queries path access information for `file_path`. Returns null if the
     // given path does not exist.
-    virtual absl::optional<PathAccessInfo> GetPathAccess(
+    virtual std::optional<PathAccessInfo> GetPathAccess(
         const base::FilePath& file_path) = 0;
 
     // Resizes a file.
diff --git a/sql/statement.cc b/sql/statement.cc
index 90c39b52..2dfb878e 100644
--- a/sql/statement.cc
+++ b/sql/statement.cc
@@ -72,7 +72,7 @@
   if (!CheckValid())
     return SqliteResultCode::kError;
 
-  absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
+  std::optional<base::ScopedBlockingCall> scoped_blocking_call;
   ref_->InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
 
   auto sqlite_result_code = ToSqliteResultCode(sqlite3_step(ref_->stmt()));
@@ -103,7 +103,7 @@
 void Statement::Reset(bool clear_bound_vars) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
+  std::optional<base::ScopedBlockingCall> scoped_blocking_call;
   ref_->InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
   if (is_valid()) {
     if (clear_bound_vars)
diff --git a/sql/test/test_helpers.cc b/sql/test/test_helpers.cc
index d8cddcb..7a1f781 100644
--- a/sql/test/test_helpers.cc
+++ b/sql/test/test_helpers.cc
@@ -12,6 +12,7 @@
 #include <string>
 #include <tuple>
 
+#include <optional>
 #include "base/big_endian.h"
 #include "base/check.h"
 #include "base/check_op.h"
@@ -24,7 +25,6 @@
 #include "sql/database.h"
 #include "sql/statement.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/sqlite/sqlite3.h"
 
 namespace sql::test {
@@ -43,17 +43,16 @@
 // Read the number of the root page of a B-tree (index/table).
 //
 // Returns a 0-indexed page number, not the raw SQLite page number.
-absl::optional<int> GetRootPage(sql::Database& db,
-                                base::StringPiece tree_name) {
+std::optional<int> GetRootPage(sql::Database& db, base::StringPiece tree_name) {
   sql::Statement select(
       db.GetUniqueStatement("SELECT rootpage FROM sqlite_schema WHERE name=?"));
   select.BindString(0, tree_name);
   if (!select.Step())
-    return absl::nullopt;
+    return std::nullopt;
 
   int sqlite_page_number = select.ColumnInt(0);
   if (!sqlite_page_number)
-    return absl::nullopt;
+    return std::nullopt;
 
   return sqlite_page_number - 1;
 }
@@ -117,15 +116,15 @@
 
 }  // namespace
 
-absl::optional<int> ReadDatabasePageSize(const base::FilePath& db_path) {
+std::optional<int> ReadDatabasePageSize(const base::FilePath& db_path) {
   // See https://www.sqlite.org/fileformat2.html#page_size
   constexpr size_t kPageSizeOffset = 16;
   uint8_t raw_page_size_bytes[2];
   base::File file(db_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
   if (!file.IsValid())
-    return absl::nullopt;
+    return std::nullopt;
   if (!file.ReadAndCheck(kPageSizeOffset, raw_page_size_bytes))
-    return absl::nullopt;
+    return std::nullopt;
 
   uint16_t raw_page_size;
   base::ReadBigEndian(raw_page_size_bytes, &raw_page_size);
@@ -142,7 +141,7 @@
   // Sanity-check that the page size is valid.
   constexpr uint16_t kMinPageSize = 512;
   if (page_size < kMinPageSize || (page_size & (page_size - 1)) != 0)
-    return absl::nullopt;
+    return std::nullopt;
 
   return page_size;
 }
@@ -209,7 +208,7 @@
 
 bool CorruptIndexRootPage(const base::FilePath& db_path,
                           base::StringPiece index_name) {
-  absl::optional<int> page_size = ReadDatabasePageSize(db_path);
+  std::optional<int> page_size = ReadDatabasePageSize(db_path);
   if (!page_size.has_value())
     return false;
 
@@ -217,7 +216,7 @@
   if (!db.Open(db_path))
     return false;
 
-  absl::optional<int> page_number = GetRootPage(db, index_name);
+  std::optional<int> page_number = GetRootPage(db, index_name);
   db.Close();
   if (!page_number.has_value())
     return false;
diff --git a/sql/test/test_helpers.h b/sql/test/test_helpers.h
index 459a9e2..32001967 100644
--- a/sql/test/test_helpers.h
+++ b/sql/test/test_helpers.h
@@ -7,11 +7,10 @@
 
 #include <stddef.h>
 #include <stdint.h>
-
+#include <optional>
 #include <string>
 
 #include "base/strings/string_piece.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // Collection of test-only convenience functions.
 
@@ -26,7 +25,7 @@
 namespace sql::test {
 
 // Read a database's page size. Returns nullopt in case of error.
-absl::optional<int> ReadDatabasePageSize(const base::FilePath& db_path);
+std::optional<int> ReadDatabasePageSize(const base::FilePath& db_path);
 
 // SQLite stores the database size in the header, and if the actual
 // OS-derived size is smaller, the database is considered corrupt.
diff --git a/storage/browser/blob/blob_impl.cc b/storage/browser/blob/blob_impl.cc
index ed96092..83dcaa50 100644
--- a/storage/browser/blob/blob_impl.cc
+++ b/storage/browser/blob/blob_impl.cc
@@ -146,7 +146,7 @@
          BlobStatus status) {
         if (status != BlobStatus::DONE) {
           DCHECK(BlobStatusIsError(status));
-          std::move(callback).Run(absl::nullopt);
+          std::move(callback).Run(std::nullopt);
           return;
         }
 
@@ -154,26 +154,26 @@
         // Currently side data is supported only for blobs with a single entry.
         const auto& items = snapshot->items();
         if (items.size() != 1) {
-          std::move(callback).Run(absl::nullopt);
+          std::move(callback).Run(std::nullopt);
           return;
         }
 
         const auto& item = items[0];
         if (item->type() != BlobDataItem::Type::kReadableDataHandle) {
-          std::move(callback).Run(absl::nullopt);
+          std::move(callback).Run(std::nullopt);
           return;
         }
 
         int32_t body_size = item->data_handle()->GetSideDataSize();
         if (body_size == 0) {
-          std::move(callback).Run(absl::nullopt);
+          std::move(callback).Run(std::nullopt);
           return;
         }
         item->data_handle()->ReadSideData(base::BindOnce(
             [](ReadSideDataCallback callback, int result,
                mojo_base::BigBuffer buffer) {
               if (result < 0) {
-                std::move(callback).Run(absl::nullopt);
+                std::move(callback).Run(std::nullopt);
                 return;
               }
               std::move(callback).Run(std::move(buffer));
@@ -197,7 +197,7 @@
 
         if (status != BlobStatus::DONE) {
           DCHECK(BlobStatusIsError(status));
-          std::move(callback).Run(0, absl::nullopt);
+          std::move(callback).Run(0, std::nullopt);
           return;
         }
 
@@ -206,13 +206,13 @@
         // time.
         const auto& items = snapshot->items();
         if (items.size() != 1) {
-          std::move(callback).Run(handle->size(), absl::nullopt);
+          std::move(callback).Run(handle->size(), std::nullopt);
           return;
         }
 
         const auto& item = items[0];
         if (item->type() != BlobDataItem::Type::kFile) {
-          std::move(callback).Run(handle->size(), absl::nullopt);
+          std::move(callback).Run(handle->size(), std::nullopt);
           return;
         }
 
@@ -225,7 +225,7 @@
 
         struct SizeAndTime {
           uint64_t size;
-          absl::optional<base::Time> time;
+          std::optional<base::Time> time;
         };
         base::ThreadPool::PostTaskAndReplyWithResult(
             FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE},
@@ -233,7 +233,7 @@
                 [](const base::FilePath& path) {
                   base::File::Info info;
                   if (!base::GetFileInfo(path, &info))
-                    return SizeAndTime{0, absl::nullopt};
+                    return SizeAndTime{0, std::nullopt};
                   return SizeAndTime{static_cast<uint64_t>(info.size),
                                      info.last_modified};
                 },
diff --git a/storage/browser/blob/blob_memory_controller.cc b/storage/browser/blob/blob_memory_controller.cc
index 714f8b5..c262aa06 100644
--- a/storage/browser/blob/blob_memory_controller.cc
+++ b/storage/browser/blob/blob_memory_controller.cc
@@ -75,7 +75,7 @@
 BlobStorageLimits CalculateBlobStorageLimitsImpl(
     const FilePath& storage_dir,
     bool disk_enabled,
-    absl::optional<uint64_t> optional_memory_size_for_testing) {
+    std::optional<uint64_t> optional_memory_size_for_testing) {
   int64_t disk_size = 0ull;
   uint64_t memory_size = optional_memory_size_for_testing
                              ? optional_memory_size_for_testing.value()
diff --git a/storage/browser/blob/blob_memory_controller.h b/storage/browser/blob/blob_memory_controller.h
index 3c15e0e..4f9ec4e 100644
--- a/storage/browser/blob/blob_memory_controller.h
+++ b/storage/browser/blob/blob_memory_controller.h
@@ -15,6 +15,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/containers/lru_cache.h"
 #include "base/feature_list.h"
@@ -28,7 +29,6 @@
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "storage/browser/blob/blob_storage_constants.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class TaskRunner;
@@ -281,7 +281,7 @@
   bool did_calculate_storage_limits_ = false;
   std::vector<base::OnceClosure> on_calculate_limits_callbacks_;
 
-  absl::optional<uint64_t> amount_of_memory_for_testing_;
+  std::optional<uint64_t> amount_of_memory_for_testing_;
 
   // Memory bookkeeping. These numbers are all disjoint.
   // This is the amount of memory we're using for blobs in RAM, including the
diff --git a/storage/browser/blob/blob_memory_controller_unittest.cc b/storage/browser/blob/blob_memory_controller_unittest.cc
index 061ea14..2d60482 100644
--- a/storage/browser/blob/blob_memory_controller_unittest.cc
+++ b/storage/browser/blob/blob_memory_controller_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "storage/browser/blob/blob_memory_controller.h"
 
+#include <optional>
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/functional/bind.h"
@@ -17,7 +18,6 @@
 #include "storage/browser/blob/blob_data_item.h"
 #include "storage/browser/blob/shareable_blob_data_item.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace storage {
 
@@ -163,7 +163,7 @@
 
   base::test::TaskEnvironment task_environment_;
 
-  absl::optional<base::ScopedDisallowBlocking> disallow_blocking_;
+  std::optional<base::ScopedDisallowBlocking> disallow_blocking_;
 };
 
 TEST_F(BlobMemoryControllerTest, Strategy) {
diff --git a/storage/browser/blob/blob_reader.cc b/storage/browser/blob/blob_reader.cc
index e9b8275..7bc8296 100644
--- a/storage/browser/blob/blob_reader.cc
+++ b/storage/browser/blob/blob_reader.cc
@@ -137,7 +137,7 @@
                      std::move(done), side_data_size));
 }
 
-absl::optional<mojo_base::BigBuffer> BlobReader::TakeSideData() {
+std::optional<mojo_base::BigBuffer> BlobReader::TakeSideData() {
   return std::move(side_data_);
 }
 
diff --git a/storage/browser/blob/blob_reader.h b/storage/browser/blob/blob_reader.h
index af034fea..1a396f3 100644
--- a/storage/browser/blob/blob_reader.h
+++ b/storage/browser/blob/blob_reader.h
@@ -12,6 +12,7 @@
 #include <memory>
 #include <vector>
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/functional/callback_forward.h"
 #include "base/functional/callback_helpers.h"
@@ -25,7 +26,6 @@
 #include "net/base/completion_once_callback.h"
 #include "services/network/public/cpp/data_pipe_to_source_stream.h"
 #include "storage/browser/blob/blob_storage_constants.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class GURL;
 
@@ -110,7 +110,7 @@
   void ReadSideData(StatusCallback done);
 
   // Passes the side data (if any) from ReadSideData() to the caller.
-  absl::optional<mojo_base::BigBuffer> TakeSideData();
+  std::optional<mojo_base::BigBuffer> TakeSideData();
 
   // Used to set the read position.
   // * This should be called after CalculateSize and before Read.
@@ -256,7 +256,7 @@
   std::unique_ptr<BlobDataSnapshot> blob_data_;
   std::unique_ptr<FileStreamReaderProvider> file_stream_provider_for_testing_;
   scoped_refptr<base::TaskRunner> file_task_runner_;
-  absl::optional<mojo_base::BigBuffer> side_data_;
+  std::optional<mojo_base::BigBuffer> side_data_;
 
   int net_error_;
   bool item_list_populated_ = false;
diff --git a/storage/browser/blob/blob_registry_impl.cc b/storage/browser/blob/blob_registry_impl.cc
index a372aed..9f5959d 100644
--- a/storage/browser/blob/blob_registry_impl.cc
+++ b/storage/browser/blob/blob_registry_impl.cc
@@ -283,7 +283,7 @@
     // requested asynchronously later again anyway.
     for (auto& entry : elements_) {
       if (entry.element->is_bytes())
-        entry.element->get_bytes()->embedded_data = absl::nullopt;
+        entry.element->get_bytes()->embedded_data = std::nullopt;
     }
   }
 
diff --git a/storage/browser/blob/blob_registry_impl_unittest.cc b/storage/browser/blob/blob_registry_impl_unittest.cc
index 00652e0..307e7ae 100644
--- a/storage/browser/blob/blob_registry_impl_unittest.cc
+++ b/storage/browser/blob/blob_registry_impl_unittest.cc
@@ -11,6 +11,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/feature_list.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/functional/bind.h"
@@ -43,7 +44,6 @@
 #include "storage/browser/test/mock_bytes_provider.h"
 #include "storage/browser/test/mock_special_storage_policy.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/mojom/blob/data_element.mojom.h"
 #include "third_party/blink/public/mojom/blob/serialized_blob.mojom.h"
 
@@ -194,7 +194,7 @@
  protected:
   base::ScopedTempDir data_dir_;
   base::test::TaskEnvironment task_environment_;
-  absl::optional<base::ScopedDisallowBlocking> disallow_blocking_;
+  std::optional<base::ScopedDisallowBlocking> disallow_blocking_;
   std::unique_ptr<BlobStorageContext> context_;
   BlobUrlRegistry url_registry_;
   std::unique_ptr<BlobRegistryImpl> registry_impl_;
@@ -307,7 +307,7 @@
   std::vector<blink::mojom::DataElementPtr> elements;
   elements.push_back(
       blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New(
-          0, absl::nullopt, CreateBytesProvider(""))));
+          0, std::nullopt, CreateBytesProvider(""))));
 
   mojo::Remote<blink::mojom::Blob> blob;
   EXPECT_TRUE(registry_->Register(blob.BindNewPipeAndPassReceiver(), kId,
@@ -587,7 +587,7 @@
   std::vector<blink::mojom::DataElementPtr> elements;
   elements.push_back(
       blink::mojom::DataElement::NewFile(blink::mojom::DataElementFile::New(
-          base::FilePath(FILE_PATH_LITERAL("foobar")), 0, 16, absl::nullopt)));
+          base::FilePath(FILE_PATH_LITERAL("foobar")), 0, 16, std::nullopt)));
 
   mojo::PendingRemote<blink::mojom::Blob> blob;
   EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId,
@@ -611,7 +611,7 @@
 
   std::vector<blink::mojom::DataElementPtr> elements;
   elements.push_back(blink::mojom::DataElement::NewFile(
-      blink::mojom::DataElementFile::New(path, 0, 16, absl::nullopt)));
+      blink::mojom::DataElementFile::New(path, 0, 16, std::nullopt)));
 
   mojo::PendingRemote<blink::mojom::Blob> blob;
   EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId,
@@ -667,10 +667,10 @@
   std::vector<blink::mojom::DataElementPtr> elements;
   elements.push_back(
       blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New(
-          8, absl::nullopt, CreateBytesProvider(""))));
+          8, std::nullopt, CreateBytesProvider(""))));
   elements.push_back(
       blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New(
-          std::numeric_limits<uint64_t>::max() - 4, absl::nullopt,
+          std::numeric_limits<uint64_t>::max() - 4, std::nullopt,
           CreateBytesProvider(""))));
 
   mojo::PendingRemote<blink::mojom::Blob> blob;
@@ -701,11 +701,11 @@
   std::vector<blink::mojom::DataElementPtr> elements;
   elements.push_back(
       blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New(
-          kTestBlobStorageMaxDiskSpace, absl::nullopt,
+          kTestBlobStorageMaxDiskSpace, std::nullopt,
           CreateBytesProvider(""))));
   elements.push_back(
       blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New(
-          kTestBlobStorageMaxDiskSpace, absl::nullopt,
+          kTestBlobStorageMaxDiskSpace, std::nullopt,
           CreateBytesProvider(""))));
 
   mojo::PendingRemote<blink::mojom::Blob> blob;
@@ -762,7 +762,7 @@
   std::vector<blink::mojom::DataElementPtr> elements;
   elements.push_back(
       blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New(
-          kData.size(), absl::nullopt, CreateBytesProvider(kData))));
+          kData.size(), std::nullopt, CreateBytesProvider(kData))));
 
   mojo::PendingRemote<blink::mojom::Blob> blob;
   EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId,
@@ -792,7 +792,7 @@
   std::vector<blink::mojom::DataElementPtr> elements;
   elements.push_back(
       blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New(
-          kData.size(), absl::nullopt, CreateBytesProvider(""))));
+          kData.size(), std::nullopt, CreateBytesProvider(""))));
 
   mojo::PendingRemote<blink::mojom::Blob> blob;
   EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId,
@@ -823,7 +823,7 @@
   std::vector<blink::mojom::DataElementPtr> elements;
   elements.push_back(
       blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New(
-          kData.size(), absl::nullopt, CreateBytesProvider(kData))));
+          kData.size(), std::nullopt, CreateBytesProvider(kData))));
 
   mojo::PendingRemote<blink::mojom::Blob> blob;
   EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId,
@@ -859,7 +859,7 @@
   std::vector<blink::mojom::DataElementPtr> elements;
   elements.push_back(
       blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New(
-          kData.size(), absl::nullopt, CreateBytesProvider(kData))));
+          kData.size(), std::nullopt, CreateBytesProvider(kData))));
 
   mojo::PendingRemote<blink::mojom::Blob> blob;
   EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId,
@@ -905,7 +905,7 @@
   std::vector<blink::mojom::DataElementPtr> elements;
   elements.push_back(
       blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New(
-          32, absl::nullopt, std::move(bytes_provider_remote))));
+          32, std::nullopt, std::move(bytes_provider_remote))));
 
   mojo::PendingRemote<blink::mojom::Blob> blob;
   EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId,
@@ -930,7 +930,7 @@
   std::vector<blink::mojom::DataElementPtr> elements;
   elements.push_back(
       blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New(
-          32, absl::nullopt, std::move(bytes_provider_remote))));
+          32, std::nullopt, std::move(bytes_provider_remote))));
 
   mojo::PendingRemote<blink::mojom::Blob> blob;
   EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId,
@@ -1009,7 +1009,7 @@
   std::vector<blink::mojom::DataElementPtr> elements;
   elements.push_back(
       blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New(
-          kData.size(), absl::nullopt, std::move(bytes_provider_remote))));
+          kData.size(), std::nullopt, std::move(bytes_provider_remote))));
 
   mojo::PendingRemote<blink::mojom::Blob> blob;
   EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId,
@@ -1045,7 +1045,7 @@
   std::vector<blink::mojom::DataElementPtr> elements;
   elements.push_back(
       blink::mojom::DataElement::NewBytes(blink::mojom::DataElementBytes::New(
-          kData.size(), absl::nullopt, std::move(bytes_provider_remote))));
+          kData.size(), std::nullopt, std::move(bytes_provider_remote))));
 
   mojo::PendingRemote<blink::mojom::Blob> blob;
   EXPECT_TRUE(registry_->Register(blob.InitWithNewPipeAndPassReceiver(), kId,
diff --git a/storage/browser/blob/blob_storage_context.cc b/storage/browser/blob/blob_storage_context.cc
index 2b781f2..140c04a 100644
--- a/storage/browser/blob/blob_storage_context.cc
+++ b/storage/browser/blob/blob_storage_context.cc
@@ -706,7 +706,7 @@
     mojo::PendingRemote<::blink::mojom::Blob> pending_blob,
     const base::FilePath& file_path,
     bool flush_on_write,
-    absl::optional<base::Time> last_modified,
+    std::optional<base::Time> last_modified,
     BlobStorageContext::WriteBlobToFileCallback callback) {
   DCHECK(!last_modified || !last_modified.value().is_null());
   if (profile_directory_.empty()) {
@@ -727,7 +727,7 @@
       base::BindOnce(
           [](base::WeakPtr<BlobStorageContext> blob_context,
              const base::FilePath& file_path, bool flush_on_write,
-             absl::optional<base::Time> last_modified,
+             std::optional<base::Time> last_modified,
              BlobStorageContext::WriteBlobToFileCallback callback,
              std::unique_ptr<BlobDataHandle> handle) {
             if (!handle || !blob_context) {
diff --git a/storage/browser/blob/blob_storage_context.h b/storage/browser/blob/blob_storage_context.h
index ae1d156..f6ce674 100644
--- a/storage/browser/blob/blob_storage_context.h
+++ b/storage/browser/blob/blob_storage_context.h
@@ -254,7 +254,7 @@
   void WriteBlobToFile(mojo::PendingRemote<::blink::mojom::Blob> blob,
                        const base::FilePath& path,
                        bool flush_on_write,
-                       absl::optional<base::Time> last_modified,
+                       std::optional<base::Time> last_modified,
                        WriteBlobToFileCallback callback) override;
   void Clone(mojo::PendingReceiver<mojom::BlobStorageContext> cloned) override;
 
diff --git a/storage/browser/blob/blob_storage_context_mojo_unittest.cc b/storage/browser/blob/blob_storage_context_mojo_unittest.cc
index df94acb..c24836fc 100644
--- a/storage/browser/blob/blob_storage_context_mojo_unittest.cc
+++ b/storage/browser/blob/blob_storage_context_mojo_unittest.cc
@@ -122,7 +122,7 @@
 
   void CreateFile(base::FilePath path,
                   std::string data,
-                  absl::optional<base::Time> modification_time) {
+                  std::optional<base::Time> modification_time) {
     base::ScopedAllowBlockingForTesting allow_blocking;
     EXPECT_TRUE(base::WriteFile(path, data));
     if (modification_time) {
@@ -136,7 +136,7 @@
       base::test::TaskEnvironment::MainThreadType::IO};
   scoped_refptr<base::SequencedTaskRunner> file_runner_;
   std::unique_ptr<BlobStorageContext> context_;
-  absl::optional<base::ScopedDisallowBlocking> disallow_blocking_;
+  std::optional<base::ScopedDisallowBlocking> disallow_blocking_;
 };
 
 TEST_F(BlobStorageContextMojoTest, BasicBlobCreation) {
@@ -214,7 +214,7 @@
   base::RunLoop loop;
   base::FilePath file_path = temp_dir_.GetPath().AppendASCII("TestFile.txt");
   context->WriteBlobToFile(
-      blob.Unbind(), file_path, true, absl::nullopt,
+      blob.Unbind(), file_path, true, std::nullopt,
       base::BindLambdaForTesting([&](mojom::WriteBlobToFileResult result) {
         EXPECT_EQ(result, mojom::WriteBlobToFileResult::kSuccess);
         loop.Quit();
@@ -494,7 +494,7 @@
   base::FilePath file_path =
       temp_dir_.GetPath().AppendASCII("DestinationFile.txt");
   context->WriteBlobToFile(
-      blob.Unbind(), file_path, true, absl::nullopt,
+      blob.Unbind(), file_path, true, std::nullopt,
       base::BindLambdaForTesting([&loop](mojom::WriteBlobToFileResult result) {
         EXPECT_EQ(result, mojom::WriteBlobToFileResult::kInvalidBlob);
         loop.Quit();
@@ -519,7 +519,7 @@
   base::RunLoop loop;
   base::FilePath file_path = temp_dir_.GetPath().AppendASCII("TestFile.txt");
   context->WriteBlobToFile(
-      blob.Unbind(), file_path, true, absl::nullopt,
+      blob.Unbind(), file_path, true, std::nullopt,
       base::BindLambdaForTesting([&](mojom::WriteBlobToFileResult result) {
         EXPECT_EQ(result, mojom::WriteBlobToFileResult::kBadPath);
         loop.Quit();
@@ -541,7 +541,7 @@
   base::FilePath file_path =
       temp_dir_.GetPath().AppendASCII("..").AppendASCII("UnaccessibleFile.txt");
   context->WriteBlobToFile(
-      blob.Unbind(), file_path, true, absl::nullopt,
+      blob.Unbind(), file_path, true, std::nullopt,
       base::BindLambdaForTesting([&](mojom::WriteBlobToFileResult result) {
         EXPECT_EQ(result, mojom::WriteBlobToFileResult::kBadPath);
         loop.Quit();
@@ -562,7 +562,7 @@
   base::RunLoop loop;
   base::FilePath file_path = base::FilePath::FromUTF8Unsafe("/etc/passwd");
   context->WriteBlobToFile(
-      blob.Unbind(), file_path, true, absl::nullopt,
+      blob.Unbind(), file_path, true, std::nullopt,
       base::BindLambdaForTesting([&](mojom::WriteBlobToFileResult result) {
         EXPECT_EQ(result, mojom::WriteBlobToFileResult::kBadPath);
         loop.Quit();
@@ -609,7 +609,7 @@
       temp_dir_.GetPath().AppendASCII("SourceFile.txt");
 
   // Create a file to copy from.
-  CreateFile(copy_from_file, kData, absl::nullopt);
+  CreateFile(copy_from_file, kData, std::nullopt);
 
   std::unique_ptr<BlobDataBuilder> builder =
       std::make_unique<BlobDataBuilder>("1234");
@@ -628,7 +628,7 @@
                                  .AppendASCII("NotCreatedDirectory")
                                  .AppendASCII("TestFile.txt");
   context->WriteBlobToFile(
-      std::move(blob), file_path, true, absl::nullopt,
+      std::move(blob), file_path, true, std::nullopt,
       base::BindLambdaForTesting([&](mojom::WriteBlobToFileResult result) {
         EXPECT_EQ(result, mojom::WriteBlobToFileResult::kIOError);
         loop.Quit();
@@ -648,7 +648,7 @@
       temp_dir_.GetPath().AppendASCII("SourceFile.txt");
 
   // Create a file to copy from.
-  CreateFile(copy_from_file, kData, absl::nullopt);
+  CreateFile(copy_from_file, kData, std::nullopt);
 
   std::unique_ptr<BlobDataBuilder> builder =
       std::make_unique<BlobDataBuilder>("1234");
@@ -666,7 +666,7 @@
   base::RunLoop loop;
   base::FilePath file_path = temp_dir_.GetPath().AppendASCII("TestFile.txt");
   context->WriteBlobToFile(
-      std::move(blob), file_path, true, absl::nullopt,
+      std::move(blob), file_path, true, std::nullopt,
       base::BindLambdaForTesting([&](mojom::WriteBlobToFileResult result) {
         EXPECT_EQ(result, mojom::WriteBlobToFileResult::kSuccess);
         loop.Quit();
diff --git a/storage/browser/blob/blob_storage_context_unittest.cc b/storage/browser/blob/blob_storage_context_unittest.cc
index 67bbcee..f7df78a 100644
--- a/storage/browser/blob/blob_storage_context_unittest.cc
+++ b/storage/browser/blob/blob_storage_context_unittest.cc
@@ -11,6 +11,7 @@
 #include <string>
 #include <utility>
 
+#include <optional>
 #include "base/files/file.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -34,7 +35,6 @@
 #include "storage/browser/test/fake_blob_data_handle.h"
 #include "storage/browser/test/test_file_system_context.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace storage {
 namespace {
@@ -140,7 +140,7 @@
 
   std::vector<FileCreationInfo> files_;
   base::ScopedTempDir temp_dir_;
-  absl::optional<base::ScopedDisallowBlocking> disallow_blocking_;
+  std::optional<base::ScopedDisallowBlocking> disallow_blocking_;
   scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner();
   scoped_refptr<FileSystemContext> file_system_context_;
 
diff --git a/storage/browser/blob/blob_transport_strategy.cc b/storage/browser/blob/blob_transport_strategy.cc
index 3353d7fc..34911703 100644
--- a/storage/browser/blob/blob_transport_strategy.cc
+++ b/storage/browser/blob/blob_transport_strategy.cc
@@ -323,7 +323,7 @@
  private:
   void OnReply(BlobDataBuilder::FutureFile future_file,
                scoped_refptr<ShareableFileReference> file_reference,
-               absl::optional<base::Time> time_file_modified) {
+               std::optional<base::Time> time_file_modified) {
     if (!time_file_modified) {
       // Writing to the file failed in the renderer.
       std::move(result_callback_).Run(BlobStatus::ERR_FILE_WRITE_FAILED);
diff --git a/storage/browser/blob/blob_transport_strategy_unittest.cc b/storage/browser/blob/blob_transport_strategy_unittest.cc
index 41867d8..7283cd93 100644
--- a/storage/browser/blob/blob_transport_strategy_unittest.cc
+++ b/storage/browser/blob/blob_transport_strategy_unittest.cc
@@ -10,6 +10,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/functional/bind.h"
@@ -27,7 +28,6 @@
 #include "storage/browser/blob/blob_data_builder.h"
 #include "storage/browser/test/mock_bytes_provider.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/mojom/blob/data_element.mojom.h"
 
 namespace storage {
@@ -89,7 +89,7 @@
 
   mojo::PendingRemote<blink::mojom::BytesProvider> CreateBytesProvider(
       const std::string& bytes,
-      absl::optional<base::Time> time) {
+      std::optional<base::Time> time) {
     mojo::PendingRemote<blink::mojom::BytesProvider> result;
     auto provider = std::make_unique<MockBytesProvider>(
         std::vector<uint8_t>(bytes.begin(), bytes.end()), &reply_request_count_,
@@ -107,7 +107,7 @@
   base::Time mock_time_;
   BlobStorageLimits limits_;
 
-  absl::optional<base::ScopedDisallowBlocking> disallow_blocking_;
+  std::optional<base::ScopedDisallowBlocking> disallow_blocking_;
 
   std::vector<std::string> bad_messages_;
 
@@ -182,7 +182,7 @@
   expected.AppendData(data);
 
   data = base::RandBytesAsString(10);
-  blink::mojom::DataElementBytes bytes3(data.size(), absl::nullopt,
+  blink::mojom::DataElementBytes bytes3(data.size(), std::nullopt,
                                         mojo::NullRemote());
   mojo::Remote<blink::mojom::BytesProvider> bytes_provider3(
       CreateBytesProvider(data, mock_time_));
@@ -243,7 +243,7 @@
       limits_);
 
   std::string data = base::RandBytesAsString(7);
-  blink::mojom::DataElementBytes bytes(data.size(), absl::nullopt,
+  blink::mojom::DataElementBytes bytes(data.size(), std::nullopt,
                                        mojo::NullRemote());
   mojo::Remote<blink::mojom::BytesProvider> bytes_provider(
       CreateBytesProvider(data.substr(0, 4), mock_time_));
@@ -273,7 +273,7 @@
       limits_);
 
   std::string data = base::RandBytesAsString(4);
-  blink::mojom::DataElementBytes bytes(data.size(), absl::nullopt,
+  blink::mojom::DataElementBytes bytes(data.size(), std::nullopt,
                                        mojo::NullRemote());
   mojo::Remote<blink::mojom::BytesProvider> bytes_provider(
       CreateBytesProvider(data + "foobar", mock_time_));
@@ -315,7 +315,7 @@
 
   std::string data =
       base::RandBytesAsString(kTestBlobStorageMaxSharedMemoryBytes * 3 + 13);
-  blink::mojom::DataElementBytes bytes(data.size(), absl::nullopt,
+  blink::mojom::DataElementBytes bytes(data.size(), std::nullopt,
                                        mojo::NullRemote());
   mojo::Remote<blink::mojom::BytesProvider> bytes_provider(
       CreateBytesProvider(data, mock_time_));
@@ -371,12 +371,12 @@
 
   base::RunLoop loop;
   std::string data = base::RandBytesAsString(kTestBlobStorageMaxFileSizeBytes);
-  blink::mojom::DataElementBytes bytes(data.size(), absl::nullopt,
+  blink::mojom::DataElementBytes bytes(data.size(), std::nullopt,
                                        mojo::NullRemote());
 
   // Must outlive `strategy`.
   mojo::Remote<blink::mojom::BytesProvider> bytes_provider(
-      CreateBytesProvider(data, absl::nullopt));
+      CreateBytesProvider(data, std::nullopt));
 
   BlobStatus status = BlobStatus::PENDING_TRANSPORT;
   auto strategy = BlobTransportStrategy::Create(
@@ -419,7 +419,7 @@
   base::RunLoop loop;
   std::string data =
       base::RandBytesAsString(kTestBlobStorageMaxBlobMemorySize + 42);
-  blink::mojom::DataElementBytes bytes(data.size(), absl::nullopt,
+  blink::mojom::DataElementBytes bytes(data.size(), std::nullopt,
                                        mojo::NullRemote());
 
   // Must outlive `strategy`.
@@ -480,19 +480,19 @@
       base::RandBytesAsString(kTestBlobStorageMaxBlobMemorySize / 3);
 
   // These must outlive `strategy`.
-  blink::mojom::DataElementBytes bytes1(data.size(), absl::nullopt,
+  blink::mojom::DataElementBytes bytes1(data.size(), std::nullopt,
                                         mojo::NullRemote());
   mojo::Remote<blink::mojom::BytesProvider> bytes_provider1(
       CreateBytesProvider(data, mock_time_));
-  blink::mojom::DataElementBytes bytes2(data.size(), absl::nullopt,
+  blink::mojom::DataElementBytes bytes2(data.size(), std::nullopt,
                                         mojo::NullRemote());
   mojo::Remote<blink::mojom::BytesProvider> bytes_provider2(
       CreateBytesProvider(data, mock_time_));
-  blink::mojom::DataElementBytes bytes3(data.size(), absl::nullopt,
+  blink::mojom::DataElementBytes bytes3(data.size(), std::nullopt,
                                         mojo::NullRemote());
   mojo::Remote<blink::mojom::BytesProvider> bytes_provider3(
       CreateBytesProvider(data, mock_time_));
-  blink::mojom::DataElementBytes bytes4(data.size(), absl::nullopt,
+  blink::mojom::DataElementBytes bytes4(data.size(), std::nullopt,
                                         mojo::NullRemote());
   mojo::Remote<blink::mojom::BytesProvider> bytes_provider4(
       CreateBytesProvider(data, mock_time_));
diff --git a/storage/browser/blob/blob_url_loader.cc b/storage/browser/blob/blob_url_loader.cc
index aef3a1b..f011ae6 100644
--- a/storage/browser/blob/blob_url_loader.cc
+++ b/storage/browser/blob/blob_url_loader.cc
@@ -171,7 +171,7 @@
     const std::vector<std::string>& removed_headers,
     const net::HttpRequestHeaders& modified_headers,
     const net::HttpRequestHeaders& modified_cors_exempt_headers,
-    const absl::optional<GURL>& new_url) {
+    const std::optional<GURL>& new_url) {
   NOTREACHED();
 }
 
@@ -192,11 +192,11 @@
     return REQUEST_SIDE_DATA;
   }
 
-  HeadersCompleted(status_code, content_size, absl::nullopt);
+  HeadersCompleted(status_code, content_size, std::nullopt);
   return DONT_REQUEST_SIDE_DATA;
 }
 
-void BlobURLLoader::DidReadSideData(absl::optional<mojo_base::BigBuffer> data) {
+void BlobURLLoader::DidReadSideData(std::optional<mojo_base::BigBuffer> data) {
   HeadersCompleted(net::HTTP_OK, total_size_, std::move(data));
 }
 
@@ -210,7 +210,7 @@
 void BlobURLLoader::HeadersCompleted(
     net::HttpStatusCode status_code,
     uint64_t content_size,
-    absl::optional<mojo_base::BigBuffer> metadata) {
+    std::optional<mojo_base::BigBuffer> metadata) {
   auto response = network::mojom::URLResponseHead::New();
   response->content_length = 0;
   if (status_code == net::HTTP_OK || status_code == net::HTTP_PARTIAL_CONTENT)
diff --git a/storage/browser/blob/blob_url_loader.h b/storage/browser/blob/blob_url_loader.h
index 7cea56f..1021157 100644
--- a/storage/browser/blob/blob_url_loader.h
+++ b/storage/browser/blob/blob_url_loader.h
@@ -67,7 +67,7 @@
       const std::vector<std::string>& removed_headers,
       const net::HttpRequestHeaders& modified_request_headers,
       const net::HttpRequestHeaders& modified_cors_exempt_request_headers,
-      const absl::optional<GURL>& new_url) override;
+      const std::optional<GURL>& new_url) override;
   void SetPriority(net::RequestPriority priority,
                    int32_t intra_priority_value) override {}
   void PauseReadingBodyFromNet() override {}
@@ -76,12 +76,12 @@
   // MojoBlobReader::Delegate implementation:
   RequestSideData DidCalculateSize(uint64_t total_size,
                                    uint64_t content_size) override;
-  void DidReadSideData(absl::optional<mojo_base::BigBuffer> data) override;
+  void DidReadSideData(std::optional<mojo_base::BigBuffer> data) override;
   void OnComplete(net::Error error_code, uint64_t total_written_bytes) override;
 
   void HeadersCompleted(net::HttpStatusCode status_code,
                         uint64_t content_size,
-                        absl::optional<mojo_base::BigBuffer> metadata);
+                        std::optional<mojo_base::BigBuffer> metadata);
 
   mojo::Receiver<network::mojom::URLLoader> receiver_;
   mojo::Remote<network::mojom::URLLoaderClient> client_;
diff --git a/storage/browser/blob/blob_url_registry.cc b/storage/browser/blob/blob_url_registry.cc
index 0891432..6b8fee3 100644
--- a/storage/browser/blob/blob_url_registry.cc
+++ b/storage/browser/blob/blob_url_registry.cc
@@ -58,7 +58,7 @@
     const blink::StorageKey& storage_key,
     // TODO(https://crbug.com/1224926): Remove these once experiment is over.
     const base::UnguessableToken& unsafe_agent_cluster_id,
-    const absl::optional<net::SchemefulSite>& unsafe_top_level_site) {
+    const std::optional<net::SchemefulSite>& unsafe_top_level_site) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(!BlobUrlUtils::UrlHasFragment(blob_url));
   if (IsUrlMapped(blob_url, storage_key)) {
@@ -113,7 +113,7 @@
 }
 
 // TODO(https://crbug.com/1224926): Remove this once experiment is over.
-absl::optional<base::UnguessableToken> BlobUrlRegistry::GetUnsafeAgentClusterID(
+std::optional<base::UnguessableToken> BlobUrlRegistry::GetUnsafeAgentClusterID(
     const GURL& blob_url) const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   auto it = url_to_unsafe_agent_cluster_id_.find(blob_url);
@@ -121,10 +121,10 @@
     return it->second;
   if (fallback_)
     return fallback_->GetUnsafeAgentClusterID(blob_url);
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<net::SchemefulSite> BlobUrlRegistry::GetUnsafeTopLevelSite(
+std::optional<net::SchemefulSite> BlobUrlRegistry::GetUnsafeTopLevelSite(
     const GURL& blob_url) const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   auto it = url_to_unsafe_top_level_site_.find(blob_url);
@@ -132,7 +132,7 @@
     return it->second;
   if (fallback_)
     return fallback_->GetUnsafeTopLevelSite(blob_url);
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 mojo::PendingRemote<blink::mojom::Blob> BlobUrlRegistry::GetBlobFromUrl(
diff --git a/storage/browser/blob/blob_url_registry.h b/storage/browser/blob/blob_url_registry.h
index 2c7d3fb..bfa492e 100644
--- a/storage/browser/blob/blob_url_registry.h
+++ b/storage/browser/blob/blob_url_registry.h
@@ -62,7 +62,7 @@
       const blink::StorageKey& storage_key,
       // TODO(https://crbug.com/1224926): Remove these once experiment is over.
       const base::UnguessableToken& unsafe_agent_cluster_id,
-      const absl::optional<net::SchemefulSite>& unsafe_top_level_site);
+      const std::optional<net::SchemefulSite>& unsafe_top_level_site);
 
   // Removes the given URL mapping associated with `storage_key` (unless the
   // kSupportPartitionedBlobUrl flag is disabled, in which case `storage_key` is
@@ -76,9 +76,9 @@
                    const blink::StorageKey& storage_key) const;
 
   // TODO(https://crbug.com/1224926): Remove this once experiment is over.
-  absl::optional<base::UnguessableToken> GetUnsafeAgentClusterID(
+  std::optional<base::UnguessableToken> GetUnsafeAgentClusterID(
       const GURL& blob_url) const;
-  absl::optional<net::SchemefulSite> GetUnsafeTopLevelSite(
+  std::optional<net::SchemefulSite> GetUnsafeTopLevelSite(
       const GURL& blob_url) const;
 
   // Returns the blob from the given url. Returns a null remote if the mapping
diff --git a/storage/browser/blob/blob_url_registry_unittest.cc b/storage/browser/blob/blob_url_registry_unittest.cc
index ec02da9..9480a32 100644
--- a/storage/browser/blob/blob_url_registry_unittest.cc
+++ b/storage/browser/blob/blob_url_registry_unittest.cc
@@ -142,8 +142,8 @@
   EXPECT_EQ(2u, registry.url_count());
   EXPECT_TRUE(registry.RemoveUrlMapping(kURL2, storageKey2));
   EXPECT_FALSE(registry.IsUrlMapped(kURL2, storageKey2));
-  EXPECT_EQ(absl::nullopt, registry.GetUnsafeAgentClusterID(kURL2));
-  EXPECT_EQ(absl::nullopt, registry.GetUnsafeTopLevelSite(kURL2));
+  EXPECT_EQ(std::nullopt, registry.GetUnsafeAgentClusterID(kURL2));
+  EXPECT_EQ(std::nullopt, registry.GetUnsafeTopLevelSite(kURL2));
 
   // Both urls point to the same blob.
   EXPECT_TRUE(registry.AddUrlMapping(kURL2, blob1.Clone(), storageKey2,
diff --git a/storage/browser/blob/blob_url_store_impl.cc b/storage/browser/blob/blob_url_store_impl.cc
index 8b318b4..6253250 100644
--- a/storage/browser/blob/blob_url_store_impl.cc
+++ b/storage/browser/blob/blob_url_store_impl.cc
@@ -89,7 +89,7 @@
     const GURL& url,
     // TODO(https://crbug.com/1224926): Remove these once experiment is over.
     const base::UnguessableToken& unsafe_agent_cluster_id,
-    const absl::optional<net::SchemefulSite>& unsafe_top_level_site,
+    const std::optional<net::SchemefulSite>& unsafe_top_level_site,
     RegisterCallback callback) {
   // TODO(https://crbug.com/1376126): Generate blob URLs here, rather than
   // validating the URLs the renderer process generated.
@@ -116,7 +116,7 @@
 
 void BlobURLStoreImpl::Resolve(const GURL& url, ResolveCallback callback) {
   if (!registry_) {
-    std::move(callback).Run(mojo::NullRemote(), absl::nullopt);
+    std::move(callback).Run(mojo::NullRemote(), std::nullopt);
     return;
   }
   mojo::PendingRemote<blink::mojom::Blob> blob = registry_->GetBlobFromUrl(url);
@@ -130,7 +130,7 @@
     ResolveAsURLLoaderFactoryCallback callback) {
   if (!registry_) {
     BlobURLLoaderFactory::Create(mojo::NullRemote(), url, std::move(receiver));
-    std::move(callback).Run(absl::nullopt, absl::nullopt);
+    std::move(callback).Run(std::nullopt, std::nullopt);
     return;
   }
 
@@ -145,12 +145,12 @@
     mojo::PendingReceiver<blink::mojom::BlobURLToken> token,
     ResolveForNavigationCallback callback) {
   if (!registry_) {
-    std::move(callback).Run(absl::nullopt);
+    std::move(callback).Run(std::nullopt);
     return;
   }
   mojo::PendingRemote<blink::mojom::Blob> blob = registry_->GetBlobFromUrl(url);
   if (!blob) {
-    std::move(callback).Run(absl::nullopt);
+    std::move(callback).Run(std::nullopt);
     return;
   }
   new BlobURLTokenImpl(registry_, url, std::move(blob), std::move(token));
diff --git a/storage/browser/blob/blob_url_store_impl.h b/storage/browser/blob/blob_url_store_impl.h
index 76ff04c..a4a5129 100644
--- a/storage/browser/blob/blob_url_store_impl.h
+++ b/storage/browser/blob/blob_url_store_impl.h
@@ -39,7 +39,7 @@
       const GURL& url,
       // TODO(https://crbug.com/1224926): Remove these once experiment is over.
       const base::UnguessableToken& unsafe_agent_cluster_id,
-      const absl::optional<net::SchemefulSite>& unsafe_top_level_site,
+      const std::optional<net::SchemefulSite>& unsafe_top_level_site,
       RegisterCallback callback) override;
   void Revoke(const GURL& url) override;
   void Resolve(const GURL& url, ResolveCallback callback) override;
diff --git a/storage/browser/blob/blob_url_store_impl_unittest.cc b/storage/browser/blob/blob_url_store_impl_unittest.cc
index f2c4688e..f915522 100644
--- a/storage/browser/blob/blob_url_store_impl_unittest.cc
+++ b/storage/browser/blob/blob_url_store_impl_unittest.cc
@@ -158,7 +158,7 @@
                           mojo::PendingRemote<blink::mojom::Blob>* blob_out,
                           const base::UnguessableToken& agent_registered,
                           mojo::PendingRemote<blink::mojom::Blob> blob,
-                          const absl::optional<base::UnguessableToken>&
+                          const std::optional<base::UnguessableToken>&
                               unsafe_agent_cluster_id) {
                          if (blob)
                            EXPECT_EQ(agent_registered, unsafe_agent_cluster_id);
@@ -373,9 +373,9 @@
       base::BindOnce(
           [](base::OnceClosure done,
              const base::UnguessableToken& agent_registered,
-             const absl::optional<base::UnguessableToken>&
+             const std::optional<base::UnguessableToken>&
                  unsafe_agent_cluster_id,
-             const absl::optional<net::SchemefulSite>& unsafe_top_level_site) {
+             const std::optional<net::SchemefulSite>& unsafe_top_level_site) {
             EXPECT_EQ(agent_registered, unsafe_agent_cluster_id);
             std::move(done).Run();
           },
@@ -411,7 +411,7 @@
       base::BindOnce(
           [](base::OnceClosure done,
              const base::UnguessableToken& agent_registered,
-             const absl::optional<base::UnguessableToken>&
+             const std::optional<base::UnguessableToken>&
                  unsafe_agent_cluster_id) {
             EXPECT_EQ(agent_registered, unsafe_agent_cluster_id);
             std::move(done).Run();
diff --git a/storage/browser/blob/mojo_blob_reader.h b/storage/browser/blob/mojo_blob_reader.h
index f64ca6b7..3dc68b1 100644
--- a/storage/browser/blob/mojo_blob_reader.h
+++ b/storage/browser/blob/mojo_blob_reader.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/sequence_checker.h"
@@ -15,7 +16,6 @@
 #include "net/base/net_errors.h"
 #include "net/http/http_byte_range.h"
 #include "storage/browser/blob/blob_reader.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace network {
 class NetToMojoPendingBuffer;
@@ -53,7 +53,7 @@
 
     // Called if DidCalculateSize returned |REQUEST_SIDE_DATA|, with the side
     // data associated with the blob being read, if any.
-    virtual void DidReadSideData(absl::optional<mojo_base::BigBuffer> data) {}
+    virtual void DidReadSideData(std::optional<mojo_base::BigBuffer> data) {}
 
     // Called whenever some amount of data is read from the blob and about to be
     // written to the data pipe.
diff --git a/storage/browser/blob/write_blob_to_file.cc b/storage/browser/blob/write_blob_to_file.cc
index 2d02d6d..9e9ff28 100644
--- a/storage/browser/blob/write_blob_to_file.cc
+++ b/storage/browser/blob/write_blob_to_file.cc
@@ -144,8 +144,8 @@
     base::Time expected_last_modified_copy_from,
     const base::FilePath& copy_to,
     int64_t offset,
-    absl::optional<int64_t> size,
-    absl::optional<base::Time> last_modified,
+    std::optional<int64_t> size,
+    std::optional<base::Time> last_modified,
     bool flush_on_close,
     file_access::ScopedFileAccess) {
   // Do a full file copy if the sizes match and there is no offset.
@@ -207,7 +207,7 @@
 
 mojom::WriteBlobToFileResult CreateEmptyFileAndMaybeSetModifiedTime(
     base::FilePath file_path,
-    absl::optional<base::Time> last_modified,
+    std::optional<base::Time> last_modified,
     bool flush_on_write) {
   base::File file(file_path,
                   base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
@@ -230,7 +230,7 @@
 
 void HandleModifiedTimeOnBlobFileWriteComplete(
     base::FilePath file_path,
-    absl::optional<base::Time> last_modified,
+    std::optional<base::Time> last_modified,
     bool flush_on_write,
     mojom::BlobStorageContext::WriteBlobToFileCallback callback,
     base::File::Error rv,
@@ -258,7 +258,7 @@
         FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE},
         base::BindOnce(
             [](int64_t bytes_written, base::FilePath file_path,
-               absl::optional<base::Time> last_modified) {
+               std::optional<base::Time> last_modified) {
               if (!base::TouchFile(file_path, last_modified.value(),
                                    last_modified.value())) {
                 // If the file modification time isn't set correctly, then
@@ -293,7 +293,7 @@
     std::unique_ptr<BlobDataHandle> blob_handle,
     const base::FilePath& file_path,
     bool flush_on_write,
-    absl::optional<base::Time> last_modified,
+    std::optional<base::Time> last_modified,
     mojom::BlobStorageContext::WriteBlobToFileCallback callback,
     BlobStatus status) {
   DCHECK(!last_modified || !last_modified.value().is_null());
@@ -311,11 +311,11 @@
     const BlobDataItem& item = *items[0];
     if (item.type() == BlobDataItem::Type::kFile) {
       // The File API cannot handle uint64_t.
-      absl::optional<int64_t> optional_size = item.length();
+      std::optional<int64_t> optional_size = item.length();
       if (item.length() == blink::BlobUtils::kUnknownSize) {
         // The blob system uses a special value (max uint64_t) to denote an
         // unknown file size. This means the whole file should be copied.
-        optional_size = absl::nullopt;
+        optional_size = std::nullopt;
       } else if (item.length() > std::numeric_limits<int64_t>::max()) {
         std::move(callback).Run(mojom::WriteBlobToFileResult::kError);
         return;
@@ -373,7 +373,7 @@
     std::unique_ptr<BlobDataHandle> blob_handle,
     const base::FilePath& file_path,
     bool flush_on_write,
-    absl::optional<base::Time> last_modified,
+    std::optional<base::Time> last_modified,
     mojom::BlobStorageContext::WriteBlobToFileCallback callback) {
   auto* blob_handle_ptr = blob_handle.get();
   blob_handle_ptr->RunOnConstructionComplete(base::BindOnce(
diff --git a/storage/browser/blob/write_blob_to_file.h b/storage/browser/blob/write_blob_to_file.h
index b787552..e643c0c 100644
--- a/storage/browser/blob/write_blob_to_file.h
+++ b/storage/browser/blob/write_blob_to_file.h
@@ -5,13 +5,13 @@
 #ifndef STORAGE_BROWSER_BLOB_WRITE_BLOB_TO_FILE_H_
 #define STORAGE_BROWSER_BLOB_WRITE_BLOB_TO_FILE_H_
 
+#include <optional>
 #include "base/files/file_path.h"
 #include "base/time/time.h"
 #include "components/services/storage/public/mojom/blob_storage_context.mojom.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "storage/browser/blob/blob_data_handle.h"
 #include "storage/browser/blob/blob_entry.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace storage {
 
@@ -26,7 +26,7 @@
     std::unique_ptr<BlobDataHandle> blob_handle,
     const base::FilePath& file_path,
     bool flush_on_write,
-    absl::optional<base::Time> last_modified,
+    std::optional<base::Time> last_modified,
     mojom::BlobStorageContext::WriteBlobToFileCallback callback);
 
 }  // namespace storage
diff --git a/storage/browser/database/database_tracker_unittest.cc b/storage/browser/database/database_tracker_unittest.cc
index 5b44ef6..2255d13 100644
--- a/storage/browser/database/database_tracker_unittest.cc
+++ b/storage/browser/database/database_tracker_unittest.cc
@@ -122,7 +122,7 @@
   void NotifyBucketModified(
       QuotaClientType client_id,
       const BucketLocator& bucket,
-      absl::optional<int64_t> delta,
+      std::optional<int64_t> delta,
       base::Time modification_time,
       scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
       base::OnceClosure callback) override {
diff --git a/storage/browser/file_system/file_system_context.cc b/storage/browser/file_system/file_system_context.cc
index 863d9f4..0ed3d82 100644
--- a/storage/browser/file_system/file_system_context.cc
+++ b/storage/browser/file_system/file_system_context.cc
@@ -424,7 +424,7 @@
 
 void FileSystemContext::OpenFileSystem(
     const blink::StorageKey& storage_key,
-    const absl::optional<storage::BucketLocator>& bucket,
+    const std::optional<storage::BucketLocator>& bucket,
     FileSystemType type,
     OpenFileSystemMode mode,
     OpenFileSystemCallback callback) {
@@ -485,7 +485,7 @@
 
 void FileSystemContext::ResolveURLOnOpenFileSystem(
     const blink::StorageKey& storage_key,
-    const absl::optional<storage::BucketLocator>& bucket,
+    const std::optional<storage::BucketLocator>& bucket,
     FileSystemType type,
     OpenFileSystemMode mode,
     OpenFileSystemCallback callback) {
diff --git a/storage/browser/file_system/file_system_context.h b/storage/browser/file_system/file_system_context.h
index f3cd9e48..4ea496b0 100644
--- a/storage/browser/file_system/file_system_context.h
+++ b/storage/browser/file_system/file_system_context.h
@@ -240,7 +240,7 @@
   // Provide a non-null BucketLocator to override the default storage bucket
   // for the root URL (which will be propagated to child URLs).
   void OpenFileSystem(const blink::StorageKey& storage_key,
-                      const absl::optional<storage::BucketLocator>& bucket,
+                      const std::optional<storage::BucketLocator>& bucket,
                       FileSystemType type,
                       OpenFileSystemMode mode,
                       OpenFileSystemCallback callback);
@@ -339,7 +339,7 @@
 
   void ResolveURLOnOpenFileSystemForTesting(
       const blink::StorageKey& storage_key,
-      const absl::optional<storage::BucketLocator>& bucket,
+      const std::optional<storage::BucketLocator>& bucket,
       FileSystemType type,
       OpenFileSystemMode mode,
       OpenFileSystemCallback callback) {
@@ -416,7 +416,7 @@
   // `bucket` will be populated if the non-default storage bucket was used.
   void ResolveURLOnOpenFileSystem(
       const blink::StorageKey& storage_key,
-      const absl::optional<storage::BucketLocator>& bucket,
+      const std::optional<storage::BucketLocator>& bucket,
       FileSystemType type,
       OpenFileSystemMode mode,
       OpenFileSystemCallback callback);
diff --git a/storage/browser/file_system/file_system_context_unittest.cc b/storage/browser/file_system/file_system_context_unittest.cc
index 140d1941..016eb6b 100644
--- a/storage/browser/file_system/file_system_context_unittest.cc
+++ b/storage/browser/file_system/file_system_context_unittest.cc
@@ -103,8 +103,7 @@
     EXPECT_EQ(expect_filesystem_id, url.filesystem_id());
   }
 
-  inline static absl::optional<FileSystemURL> last_resolved_url_ =
-      absl::nullopt;
+  inline static std::optional<FileSystemURL> last_resolved_url_ = std::nullopt;
 
  private:
   base::ScopedTempDir data_dir_;
diff --git a/storage/browser/file_system/file_system_url.h b/storage/browser/file_system/file_system_url.h
index df45f49..d7bef429 100644
--- a/storage/browser/file_system/file_system_url.h
+++ b/storage/browser/file_system/file_system_url.h
@@ -8,12 +8,12 @@
 #include <set>
 #include <string>
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/files/file_path.h"
 #include "components/services/storage/public/cpp/buckets/bucket_locator.h"
 #include "storage/common/file_system/file_system_mount_option.h"
 #include "storage/common/file_system/file_system_types.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/storage_key/storage_key.h"
 #include "url/gurl.h"
 
@@ -241,7 +241,7 @@
   // Returns the `BucketLocator` for this URL's partitioned file location. In
   // the majority of cases, this will not be populated and the default storage
   // bucket will be used.
-  const absl::optional<BucketLocator>& bucket() const { return bucket_; }
+  const std::optional<BucketLocator>& bucket() const { return bucket_; }
   void SetBucket(const BucketLocator& bucket) { bucket_ = bucket; }
 
   // Returns either `bucket_` or a `BucketLocator` corresponding to the default
@@ -308,7 +308,7 @@
   FileSystemMountOption mount_option_;
 
   // Fields that must be explicitly set separately.
-  absl::optional<BucketLocator> bucket_;
+  std::optional<BucketLocator> bucket_;
 };
 
 using FileSystemURLSet = std::set<FileSystemURL, FileSystemURL::Comparator>;
diff --git a/storage/browser/file_system/file_system_url_unittest.cc b/storage/browser/file_system/file_system_url_unittest.cc
index b6132de..09ce663 100644
--- a/storage/browser/file_system/file_system_url_unittest.cc
+++ b/storage/browser/file_system/file_system_url_unittest.cc
@@ -216,7 +216,7 @@
       no_bucket.CreateSibling(*base::SafeBaseName::Create(FPL("without")));
 
   EXPECT_EQ(with.bucket(), bucket);
-  EXPECT_EQ(without.bucket(), absl::nullopt);
+  EXPECT_EQ(without.bucket(), std::nullopt);
 }
 
 TEST(FileSystemURLTest, EnsureFilePathIsRelative) {
diff --git a/storage/browser/file_system/obfuscated_file_util.cc b/storage/browser/file_system/obfuscated_file_util.cc
index 1e84d35..ffae7d4 100644
--- a/storage/browser/file_system/obfuscated_file_util.cc
+++ b/storage/browser/file_system/obfuscated_file_util.cc
@@ -125,7 +125,7 @@
 DatabaseKey& DatabaseKey::operator=(DatabaseKey&& other) = default;
 
 DatabaseKey::DatabaseKey(const blink::StorageKey& storage_key,
-                         const absl::optional<BucketLocator>& bucket,
+                         const std::optional<BucketLocator>& bucket,
                          const std::string& type) {
   storage_key_ = storage_key;
   bucket_ = bucket;
@@ -272,11 +272,11 @@
 
   // Returns the next StorageKey. Returns empty if there are no more
   // StorageKeys.
-  absl::optional<blink::StorageKey> Next() override {
+  std::optional<blink::StorageKey> Next() override {
     OriginRecord record;
     if (origin_records_.empty()) {
       current_ = record;
-      return absl::nullopt;
+      return std::nullopt;
     }
     record = origin_records_.back();
     origin_records_.pop_back();
@@ -924,7 +924,7 @@
 base::FileErrorOr<base::FilePath>
 ObfuscatedFileUtil::GetDirectoryForBucketAndType(
     const BucketLocator& bucket,
-    const absl::optional<FileSystemType>& type,
+    const std::optional<FileSystemType>& type,
     bool create) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   // A default bucket in a first-party context uses
@@ -954,7 +954,7 @@
 base::FileErrorOr<base::FilePath>
 ObfuscatedFileUtil::GetDirectoryForStorageKeyAndType(
     const blink::StorageKey& storage_key,
-    const absl::optional<FileSystemType>& type,
+    const std::optional<FileSystemType>& type,
     bool create) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   ASSIGN_OR_RETURN(base::FilePath path,
@@ -974,13 +974,13 @@
 
 bool ObfuscatedFileUtil::DeleteDirectoryForBucketAndType(
     const BucketLocator& bucket_locator,
-    const absl::optional<FileSystemType>& type) {
+    const std::optional<FileSystemType>& type) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DestroyDirectoryDatabaseForBucket(bucket_locator, type);
 
   // Get the base path for the bucket without the type string appended.
   base::FileErrorOr<base::FilePath> path_without_type =
-      GetDirectoryForBucketAndType(bucket_locator, /*type=*/absl::nullopt,
+      GetDirectoryForBucketAndType(bucket_locator, /*type=*/std::nullopt,
                                    /*create=*/false);
   if (!path_without_type.has_value() || path_without_type->empty()) {
     return true;
@@ -1048,30 +1048,30 @@
 
 void ObfuscatedFileUtil::DestroyDirectoryDatabaseForBucket(
     const BucketLocator& bucket_locator,
-    const absl::optional<FileSystemType>& type) {
+    const std::optional<FileSystemType>& type) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   DatabaseKey key_prefix;
   const std::string type_string =
       type ? SandboxFileSystemBackendDelegate::GetTypeString(type.value())
            : std::string();
-  // `key.bucket()` is absl::nullopt for all non-kTemporary types.
+  // `key.bucket()` is std::nullopt for all non-kTemporary types.
   if (type && (FileSystemTypeToQuotaStorageType(type.value()) ==
                ::blink::mojom::StorageType::kTemporary)) {
     key_prefix =
         DatabaseKey(bucket_locator.storage_key, bucket_locator, type_string);
   } else {  // All other storage types.
     key_prefix =
-        DatabaseKey(bucket_locator.storage_key, absl::nullopt, type_string);
+        DatabaseKey(bucket_locator.storage_key, std::nullopt, type_string);
   }
 
   // If `type` is empty, delete all filesystem types under `storage_key`.
   for (auto iter = directories_.lower_bound(key_prefix);
        iter != directories_.end();) {
-    // If the key matches exactly or `type` is absl::nullopt and just the
+    // If the key matches exactly or `type` is std::nullopt and just the
     // StorageKey and BucketLocator match exactly, delete the database.
     if (iter->first == key_prefix ||
-        (type == absl::nullopt &&
+        (type == std::nullopt &&
          iter->first.storage_key() == key_prefix.storage_key() &&
          iter->first.bucket() == key_prefix.bucket())) {
       std::unique_ptr<SandboxDirectoryDatabase> database =
@@ -1307,7 +1307,7 @@
   DatabaseKey key;
   const std::string type_string =
       SandboxFileSystemBackendDelegate::GetTypeString(url.type());
-  // `key.bucket()` is absl::nullopt for all non-kTemporary types.
+  // `key.bucket()` is std::nullopt for all non-kTemporary types.
   if (FileSystemTypeToQuotaStorageType(url.type()) ==
       ::blink::mojom::StorageType::kTemporary) {
     if (url.bucket().has_value()) {
@@ -1322,7 +1322,7 @@
                         type_string);
     }
   } else {  // All other storage types.
-    key = DatabaseKey(url.storage_key(), absl::nullopt, type_string);
+    key = DatabaseKey(url.storage_key(), std::nullopt, type_string);
   }
 
   auto iter = directories_.find(key);
diff --git a/storage/browser/file_system/obfuscated_file_util.h b/storage/browser/file_system/obfuscated_file_util.h
index e51b9813..eeaee161 100644
--- a/storage/browser/file_system/obfuscated_file_util.h
+++ b/storage/browser/file_system/obfuscated_file_util.h
@@ -45,7 +45,7 @@
 // Class representing the key for directories_. NOTE: The `bucket` value is
 // optional due to usage of ObfuscatedFileUtil where the type is not kTemporary
 // (i.e. kPersistent or kSyncable). For all non-temporary types, expect the
-// bucket member value to be absl::nullopt. The class is implemented as such to
+// bucket member value to be std::nullopt. The class is implemented as such to
 // avoid mapping the same StorageKey to potentially different bucket values,
 // which would cause directories_ lookup errors. NOTE: The `type_string` value
 // is empty when designating a "top-level directory" or a directory that
@@ -66,11 +66,11 @@
   DatabaseKey& operator=(DatabaseKey&& other);
 
   DatabaseKey(const blink::StorageKey& storage_key,
-              const absl::optional<BucketLocator>& bucket,
+              const std::optional<BucketLocator>& bucket,
               const std::string& type_string);
 
   const blink::StorageKey& storage_key() const { return storage_key_; }
-  const absl::optional<BucketLocator>& bucket() const { return bucket_; }
+  const std::optional<BucketLocator>& bucket() const { return bucket_; }
   const std::string& type() const { return type_; }
 
   bool operator==(const DatabaseKey& other) const;
@@ -79,7 +79,7 @@
 
  private:
   blink::StorageKey storage_key_;
-  absl::optional<BucketLocator> bucket_;
+  std::optional<BucketLocator> bucket_;
   std::string type_;
 };
 
@@ -127,9 +127,9 @@
    public:
     virtual ~AbstractStorageKeyEnumerator() = default;
 
-    // Returns the next StorageKey. Returns absl::nullopt if there are no more
+    // Returns the next StorageKey. Returns std::nullopt if there are no more
     // StorageKeys.
-    virtual absl::optional<blink::StorageKey> Next() = 0;
+    virtual std::optional<blink::StorageKey> Next() = 0;
 
     // Returns the current StorageKey's information.
     // `type_string` must be ascii string.
@@ -218,7 +218,7 @@
   // Returns a base::FileError if the directory is undefined.
   base::FileErrorOr<base::FilePath> GetDirectoryForBucketAndType(
       const BucketLocator& bucket_locator,
-      const absl::optional<FileSystemType>& type,
+      const std::optional<FileSystemType>& type,
       bool create);
 
   // Gets the topmost directory specific to this StorageKey and type.  This will
@@ -231,15 +231,15 @@
   // `create` is false).
   base::FileErrorOr<base::FilePath> GetDirectoryForStorageKeyAndType(
       const blink::StorageKey& storage_key,
-      const absl::optional<FileSystemType>& type,
+      const std::optional<FileSystemType>& type,
       bool create);
 
   // Deletes the topmost directory specific to this BucketLocator and type. This
   // will delete its directory database. Deletes the topmost bucket
-  // directory if `type` is absl::nullopt.
+  // directory if `type` is std::nullopt.
   bool DeleteDirectoryForBucketAndType(
       const BucketLocator& bucket_locator,
-      const absl::optional<FileSystemType>& type);
+      const std::optional<FileSystemType>& type);
 
   // This method and all methods of its returned class must be called only on
   // the FILE thread.  The caller is responsible for deleting the returned
@@ -250,7 +250,7 @@
   // database on the disk corresponding to the provided bucket locator and type.
   void DestroyDirectoryDatabaseForBucket(
       const BucketLocator& bucket_locator,
-      const absl::optional<FileSystemType>& type);
+      const std::optional<FileSystemType>& type);
 
   // Computes a cost for storing a given file in the obfuscated FSFU.
   // As the cost of a file is independent of the cost of its parent directories,
diff --git a/storage/browser/file_system/obfuscated_file_util_memory_delegate.cc b/storage/browser/file_system/obfuscated_file_util_memory_delegate.cc
index 5d54bc9a..cb7da7c 100644
--- a/storage/browser/file_system/obfuscated_file_util_memory_delegate.cc
+++ b/storage/browser/file_system/obfuscated_file_util_memory_delegate.cc
@@ -101,7 +101,7 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 }
 
-absl::optional<ObfuscatedFileUtilMemoryDelegate::DecomposedPath>
+std::optional<ObfuscatedFileUtilMemoryDelegate::DecomposedPath>
 ObfuscatedFileUtilMemoryDelegate::ParsePath(const base::FilePath& path) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DecomposedPath dp;
@@ -109,11 +109,11 @@
 
   // Ensure |path| is under |root_|.
   if (dp.components.size() < root_path_components_.size())
-    return absl::nullopt;
+    return std::nullopt;
 
   for (size_t i = 0; i < root_path_components_.size(); i++)
     if (dp.components[i] != root_path_components_[i])
-      return absl::nullopt;
+      return std::nullopt;
 
   dp.components.erase(dp.components.begin(),
                       dp.components.begin() + root_path_components_.size());
@@ -126,7 +126,7 @@
     } else if (dp.components[i] == base::FilePath::kParentDirectory) {
       // Beyond |root|?
       if (!i)
-        return absl::nullopt;
+        return std::nullopt;
       dp.components.erase(dp.components.begin() + i - 1,
                           dp.components.begin() + i + 1);
       i -= 2;
@@ -159,7 +159,7 @@
 bool ObfuscatedFileUtilMemoryDelegate::DirectoryExists(
     const base::FilePath& path) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  absl::optional<DecomposedPath> dp = ParsePath(path);
+  std::optional<DecomposedPath> dp = ParsePath(path);
   return dp && dp->entry && dp->entry->type == Entry::kDirectory;
 }
 
@@ -168,7 +168,7 @@
     bool exclusive,
     bool recursive) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  absl::optional<DecomposedPath> dp = ParsePath(path);
+  std::optional<DecomposedPath> dp = ParsePath(path);
   if (!dp)
     return base::File::FILE_ERROR_NOT_FOUND;
 
@@ -212,7 +212,7 @@
     const base::FilePath& path,
     bool recursive) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  absl::optional<DecomposedPath> dp = ParsePath(path);
+  std::optional<DecomposedPath> dp = ParsePath(path);
   if (!dp)
     return false;
 
@@ -235,7 +235,7 @@
 
 bool ObfuscatedFileUtilMemoryDelegate::PathExists(const base::FilePath& path) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  absl::optional<DecomposedPath> dp = ParsePath(path);
+  std::optional<DecomposedPath> dp = ParsePath(path);
   return dp && dp->entry;
 }
 
@@ -269,7 +269,7 @@
 base::File::Error ObfuscatedFileUtilMemoryDelegate::DeleteFile(
     const base::FilePath& path) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  absl::optional<DecomposedPath> dp = ParsePath(path);
+  std::optional<DecomposedPath> dp = ParsePath(path);
   if (!dp || !dp->entry)
     return base::File::FILE_ERROR_NOT_FOUND;
 
@@ -284,7 +284,7 @@
     const base::FilePath& path,
     bool* created) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  absl::optional<DecomposedPath> dp = ParsePath(path);
+  std::optional<DecomposedPath> dp = ParsePath(path);
   *created = false;
   if (!dp || !dp->parent)
     return base::File::FILE_ERROR_NOT_FOUND;
@@ -303,7 +303,7 @@
     const base::FilePath& path,
     base::File::Info* file_info) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  absl::optional<DecomposedPath> dp = ParsePath(path);
+  std::optional<DecomposedPath> dp = ParsePath(path);
   if (!dp || !dp->entry)
     return base::File::FILE_ERROR_NOT_FOUND;
 
@@ -323,7 +323,7 @@
     const base::Time& last_access_time,
     const base::Time& last_modified_time) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  absl::optional<DecomposedPath> dp = ParsePath(path);
+  std::optional<DecomposedPath> dp = ParsePath(path);
   if (!dp || !dp->entry)
     return base::File::FILE_ERROR_FAILED;
 
@@ -337,7 +337,7 @@
     const base::FilePath& path,
     int64_t length) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  absl::optional<DecomposedPath> dp = ParsePath(path);
+  std::optional<DecomposedPath> dp = ParsePath(path);
   if (!dp || !dp->entry || dp->entry->type != Entry::kFile)
     return base::File::FILE_ERROR_NOT_FOUND;
 
@@ -367,8 +367,8 @@
     FileSystemOperation::CopyOrMoveOptionSet options,
     NativeFileUtil::CopyOrMoveMode mode) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  absl::optional<DecomposedPath> src_dp = ParsePath(src_path);
-  absl::optional<DecomposedPath> dest_dp = ParsePath(dest_path);
+  std::optional<DecomposedPath> src_dp = ParsePath(src_path);
+  std::optional<DecomposedPath> dest_dp = ParsePath(dest_path);
 
   if (!src_dp || !src_dp->entry || !dest_dp || !dest_dp->parent)
     return base::File::FILE_ERROR_NOT_FOUND;
@@ -477,7 +477,7 @@
 size_t ObfuscatedFileUtilMemoryDelegate::ComputeDirectorySize(
     const base::FilePath& path) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  absl::optional<DecomposedPath> dp = ParsePath(path);
+  std::optional<DecomposedPath> dp = ParsePath(path);
   if (!dp || !dp->entry || dp->entry->type != Entry::kDirectory)
     return 0;
 
@@ -503,7 +503,7 @@
                                                scoped_refptr<net::IOBuffer> buf,
                                                int buf_len) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  absl::optional<DecomposedPath> dp = ParsePath(path);
+  std::optional<DecomposedPath> dp = ParsePath(path);
   if (!dp || dp->entry->type != Entry::kFile)
     return net::ERR_FILE_NOT_FOUND;
 
@@ -532,7 +532,7 @@
     scoped_refptr<net::IOBuffer> buf,
     int buf_len) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  absl::optional<DecomposedPath> dp = ParsePath(path);
+  std::optional<DecomposedPath> dp = ParsePath(path);
 
   if (!dp || !dp->entry || dp->entry->type != Entry::kFile)
     return net::ERR_FILE_NOT_FOUND;
@@ -595,7 +595,7 @@
   if (result != base::File::FILE_OK)
     return result;
 
-  absl::optional<DecomposedPath> dp = ParsePath(path);
+  std::optional<DecomposedPath> dp = ParsePath(path);
   DCHECK(dp && dp->entry->type == Entry::kFile);
 
   dp->entry->file_content =
@@ -610,7 +610,7 @@
     FileSystemOperation::CopyOrMoveOptionSet /* options */,
     NativeFileUtil::CopyOrMoveMode /* mode */) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  absl::optional<DecomposedPath> dest_dp = ParsePath(dest_path);
+  std::optional<DecomposedPath> dest_dp = ParsePath(dest_path);
 
   if (!dest_dp || !dest_dp->parent)
     return base::File::FILE_ERROR_NOT_FOUND;
diff --git a/storage/browser/file_system/obfuscated_file_util_memory_delegate.h b/storage/browser/file_system/obfuscated_file_util_memory_delegate.h
index 0c6c5e8..e2bd64e8 100644
--- a/storage/browser/file_system/obfuscated_file_util_memory_delegate.h
+++ b/storage/browser/file_system/obfuscated_file_util_memory_delegate.h
@@ -118,7 +118,7 @@
 
   // Parses the given path into a decomposed path and performs validity checks
   // and normalization. Returns an empty value if checks fail.
-  absl::optional<DecomposedPath> ParsePath(const base::FilePath& path);
+  std::optional<DecomposedPath> ParsePath(const base::FilePath& path);
 
   // Creates or opens a file specified in |dp|.
   void CreateOrOpenInternal(const DecomposedPath& dp, uint32_t file_flags);
diff --git a/storage/browser/file_system/obfuscated_file_util_unittest.cc b/storage/browser/file_system/obfuscated_file_util_unittest.cc
index 0c153b4..428978b 100644
--- a/storage/browser/file_system/obfuscated_file_util_unittest.cc
+++ b/storage/browser/file_system/obfuscated_file_util_unittest.cc
@@ -1735,7 +1735,7 @@
   // populates the enumerator being tested. So in a test environment, this
   // enumerator should not have any additional StorageKeys to access via Next().
   if (is_third_party_context() || is_non_default_bucket()) {
-    EXPECT_EQ(absl::nullopt, enumerator->Next());
+    EXPECT_EQ(std::nullopt, enumerator->Next());
     return;
   }
   EXPECT_EQ(storage_key(), enumerator->Next());
@@ -1785,7 +1785,7 @@
   enumerator = ofu()->CreateStorageKeyEnumerator();
   EXPECT_TRUE(enumerator.get());
   std::set<blink::StorageKey> storage_keys_found;
-  absl::optional<blink::StorageKey> enumerator_storage_key;
+  std::optional<blink::StorageKey> enumerator_storage_key;
   while ((enumerator_storage_key = enumerator->Next()).has_value()) {
     storage_keys_found.insert(enumerator_storage_key.value());
     SCOPED_TRACE(testing::Message()
@@ -2667,7 +2667,7 @@
                   .has_value());
 
   // Delete all directories for default_bucket_.
-  ofu()->DeleteDirectoryForBucketAndType(default_bucket_, absl::nullopt);
+  ofu()->DeleteDirectoryForBucketAndType(default_bucket_, std::nullopt);
 
   // The directories for default_bucket_ should be removed.
   ASSERT_THAT(ofu()->GetDirectoryForBucketAndType(default_bucket_,
diff --git a/storage/browser/file_system/quota/quota_backend_impl_unittest.cc b/storage/browser/file_system/quota/quota_backend_impl_unittest.cc
index 10f7f6c..3d0de9a7 100644
--- a/storage/browser/file_system/quota/quota_backend_impl_unittest.cc
+++ b/storage/browser/file_system/quota/quota_backend_impl_unittest.cc
@@ -62,7 +62,7 @@
   void NotifyBucketModified(
       QuotaClientType client_id,
       const BucketLocator& bucket,
-      absl::optional<int64_t> delta,
+      std::optional<int64_t> delta,
       base::Time modification_time,
       scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
       base::OnceClosure callback) override {
diff --git a/storage/browser/file_system/sandbox_file_stream_reader_unittest.cc b/storage/browser/file_system/sandbox_file_stream_reader_unittest.cc
index 1211c75..be5b4a9 100644
--- a/storage/browser/file_system/sandbox_file_stream_reader_unittest.cc
+++ b/storage/browser/file_system/sandbox_file_stream_reader_unittest.cc
@@ -62,7 +62,7 @@
 
     file_system_context_->OpenFileSystem(
         blink::StorageKey::CreateFromStringForTesting(kURLOrigin),
-        /*bucket=*/absl::nullopt, kFileSystemTypeTemporary,
+        /*bucket=*/std::nullopt, kFileSystemTypeTemporary,
         OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
         base::BindOnce([](const FileSystemURL& root_url,
                           const std::string& name, base::File::Error result) {
diff --git a/storage/browser/file_system/sandbox_file_stream_writer_unittest.cc b/storage/browser/file_system/sandbox_file_stream_writer_unittest.cc
index ac8af87..4378ea7 100644
--- a/storage/browser/file_system/sandbox_file_stream_writer_unittest.cc
+++ b/storage/browser/file_system/sandbox_file_stream_writer_unittest.cc
@@ -65,7 +65,7 @@
 
     file_system_context_->OpenFileSystem(
         blink::StorageKey::CreateFromStringForTesting(kURLOrigin),
-        /*bucket=*/absl::nullopt, kFileSystemTypeTemporary,
+        /*bucket=*/std::nullopt, kFileSystemTypeTemporary,
         OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
         base::BindOnce([](const FileSystemURL& root_url,
                           const std::string& name, base::File::Error result) {
diff --git a/storage/browser/file_system/sandbox_file_system_backend_delegate.cc b/storage/browser/file_system/sandbox_file_system_backend_delegate.cc
index 09a4290..7a832de 100644
--- a/storage/browser/file_system/sandbox_file_system_backend_delegate.cc
+++ b/storage/browser/file_system/sandbox_file_system_backend_delegate.cc
@@ -83,7 +83,7 @@
   }
   ~SandboxObfuscatedStorageKeyEnumerator() override = default;
 
-  absl::optional<blink::StorageKey> Next() override { return enum_->Next(); }
+  std::optional<blink::StorageKey> Next() override { return enum_->Next(); }
 
   bool HasFileSystemType(FileSystemType type) const override {
     return enum_->HasTypeDirectory(
@@ -355,7 +355,7 @@
   std::unique_ptr<StorageKeyEnumerator> enumerator(
       CreateStorageKeyEnumerator());
   std::vector<blink::StorageKey> storage_keys;
-  absl::optional<blink::StorageKey> storage_key;
+  std::optional<blink::StorageKey> storage_key;
   while ((storage_key = enumerator->Next()).has_value()) {
     if (enumerator->HasFileSystemType(type))
       storage_keys.push_back(std::move(storage_key).value());
@@ -369,7 +369,7 @@
     FileSystemType type) {
   DCHECK(file_task_runner_->RunsTasksInCurrentSequence());
   return GetUsageOnFileTaskRunner(file_system_context, storage_key,
-                                  /*bucket_locator=*/absl::nullopt, type);
+                                  /*bucket_locator=*/std::nullopt, type);
 }
 
 int64_t SandboxFileSystemBackendDelegate::GetBucketUsageOnFileTaskRunner(
@@ -384,7 +384,7 @@
 int64_t SandboxFileSystemBackendDelegate::GetUsageOnFileTaskRunner(
     FileSystemContext* file_system_context,
     const blink::StorageKey& storage_key,
-    const absl::optional<BucketLocator>& bucket_locator,
+    const std::optional<BucketLocator>& bucket_locator,
     FileSystemType type) {
   DCHECK(file_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(!bucket_locator.has_value() ||
@@ -623,7 +623,7 @@
 int64_t SandboxFileSystemBackendDelegate::RecalculateUsage(
     FileSystemContext* context,
     const blink::StorageKey& storage_key,
-    const absl::optional<BucketLocator>& bucket_locator,
+    const std::optional<BucketLocator>& bucket_locator,
     FileSystemType type) {
   FileSystemOperationContext operation_context(context);
   FileSystemURL url =
diff --git a/storage/browser/file_system/sandbox_file_system_backend_delegate.h b/storage/browser/file_system/sandbox_file_system_backend_delegate.h
index 90ca94f..2bf20a5 100644
--- a/storage/browser/file_system/sandbox_file_system_backend_delegate.h
+++ b/storage/browser/file_system/sandbox_file_system_backend_delegate.h
@@ -14,6 +14,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/files/file_error_or.h"
 #include "base/files/file_path.h"
@@ -26,7 +27,6 @@
 #include "storage/browser/file_system/file_system_quota_util.h"
 #include "storage/browser/file_system/task_runner_bound_observer_list.h"
 #include "storage/browser/quota/quota_manager_proxy.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class SequencedTaskRunner;
@@ -81,9 +81,9 @@
     StorageKeyEnumerator& operator=(const StorageKeyEnumerator&) = delete;
     virtual ~StorageKeyEnumerator() = default;
 
-    // Returns the next StorageKey.  Returns absl::nullopt if there are no more
+    // Returns the next StorageKey.  Returns std::nullopt if there are no more
     // StorageKey.
-    virtual absl::optional<blink::StorageKey> Next() = 0;
+    virtual std::optional<blink::StorageKey> Next() = 0;
 
     // Returns the current StorageKey's information.
     virtual bool HasFileSystemType(FileSystemType type) const = 0;
@@ -273,14 +273,14 @@
   int64_t GetUsageOnFileTaskRunner(
       FileSystemContext* context,
       const blink::StorageKey& storage_key,
-      const absl::optional<BucketLocator>& bucket_locator,
+      const std::optional<BucketLocator>& bucket_locator,
       FileSystemType type);
 
   // If no bucket value is provided, usage will be recalculated for the default
   // bucket for the provided StorageKey value.
   int64_t RecalculateUsage(FileSystemContext* context,
                            const blink::StorageKey& storage_key,
-                           const absl::optional<BucketLocator>& bucket_locator,
+                           const std::optional<BucketLocator>& bucket_locator,
                            FileSystemType type);
 
   ObfuscatedFileUtil* obfuscated_file_util();
diff --git a/storage/browser/file_system/sandbox_file_system_backend_unittest.cc b/storage/browser/file_system/sandbox_file_system_backend_unittest.cc
index 48da87ad..8eb9eeb 100644
--- a/storage/browser/file_system/sandbox_file_system_backend_unittest.cc
+++ b/storage/browser/file_system/sandbox_file_system_backend_unittest.cc
@@ -266,7 +266,7 @@
   size_t temporary_actual_size = 0;
   size_t persistent_actual_size = 0;
 
-  absl::optional<blink::StorageKey> current;
+  std::optional<blink::StorageKey> current;
   while ((current = enumerator->Next()).has_value()) {
     SCOPED_TRACE(testing::Message()
                  << "EnumerateOrigin " << current->origin().Serialize());
diff --git a/storage/browser/quota/client_usage_tracker.cc b/storage/browser/quota/client_usage_tracker.cc
index d2fc7d7..aee894b3 100644
--- a/storage/browser/quota/client_usage_tracker.cc
+++ b/storage/browser/quota/client_usage_tracker.cc
@@ -97,7 +97,7 @@
 }
 
 void ClientUsageTracker::UpdateBucketUsageCache(const BucketLocator& bucket,
-                                                absl::optional<int64_t> delta) {
+                                                std::optional<int64_t> delta) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (!IsUsageCacheEnabledForStorageKey(bucket.storage_key)) {
     return;
diff --git a/storage/browser/quota/client_usage_tracker.h b/storage/browser/quota/client_usage_tracker.h
index 5b60bcd..20ce524e 100644
--- a/storage/browser/quota/client_usage_tracker.h
+++ b/storage/browser/quota/client_usage_tracker.h
@@ -75,7 +75,7 @@
   // reduction in quota usage. Negative `delta` values are clamped to ensure the
   // total cached usage never goes below zero (crbug.com/463729).
   void UpdateBucketUsageCache(const BucketLocator& bucket,
-                              absl::optional<int64_t> delta);
+                              std::optional<int64_t> delta);
 
   // Deletes `bucket` from the cache if it exists. Called either for bucket
   // deletion or disabling cache for `bucket`'s Storage Key.
diff --git a/storage/browser/quota/quota_callbacks.h b/storage/browser/quota/quota_callbacks.h
index cebb7e1..aa60c0dc 100644
--- a/storage/browser/quota/quota_callbacks.h
+++ b/storage/browser/quota/quota_callbacks.h
@@ -13,10 +13,10 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/containers/contains.h"
 #include "base/functional/callback.h"
 #include "components/services/storage/public/cpp/buckets/bucket_locator.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/mojom/quota/quota_types.mojom-forward.h"
 
 namespace blink {
@@ -44,7 +44,7 @@
     base::OnceCallback<void(const std::set<blink::StorageKey>& storage_keys)>;
 using GetUsageInfoCallback = base::OnceCallback<void(UsageInfoEntries)>;
 using GetBucketCallback =
-    base::OnceCallback<void(const absl::optional<BucketLocator>& bucket_info)>;
+    base::OnceCallback<void(const std::optional<BucketLocator>& bucket_info)>;
 
 // Simple template wrapper for a callback queue.
 template <typename CallbackType, typename... Args>
diff --git a/storage/browser/quota/quota_database.cc b/storage/browser/quota/quota_database.cc
index 815b7b0..7c86bfd 100644
--- a/storage/browser/quota/quota_database.cc
+++ b/storage/browser/quota/quota_database.cc
@@ -135,7 +135,7 @@
                                                   : QuotaError::kDatabaseError);
   }
 
-  absl::optional<StorageKey> storage_key =
+  std::optional<StorageKey> storage_key =
       StorageKey::Deserialize(statement.ColumnString(1));
   if (!storage_key.has_value()) {
     return base::unexpected(QuotaError::kStorageKeyError);
@@ -582,7 +582,7 @@
                                                   : QuotaError::kDatabaseError);
   }
 
-  absl::optional<StorageKey> storage_key =
+  std::optional<StorageKey> storage_key =
       StorageKey::Deserialize(statement.ColumnString(1));
   if (!storage_key.has_value()) {
     return base::unexpected(QuotaError::kStorageKeyError);
@@ -668,7 +668,7 @@
   int64_t total_usage = 0;
 
   while (statement.Step()) {
-    absl::optional<StorageKey> read_storage_key =
+    std::optional<StorageKey> read_storage_key =
         StorageKey::Deserialize(statement.ColumnString(1));
     if (!read_storage_key.has_value()) {
       // TODO(estade): this row needs to be deleted.
@@ -721,7 +721,7 @@
 
   std::set<StorageKey> storage_keys;
   while (statement.Step()) {
-    absl::optional<StorageKey> read_storage_key =
+    std::optional<StorageKey> read_storage_key =
         StorageKey::Deserialize(statement.ColumnString(0));
     if (!read_storage_key.has_value()) {
       continue;
@@ -757,7 +757,7 @@
 
   std::set<BucketLocator> buckets;
   while (statement.Step()) {
-    absl::optional<StorageKey> read_storage_key =
+    std::optional<StorageKey> read_storage_key =
         StorageKey::Deserialize(statement.ColumnString(1));
     if (!read_storage_key.has_value()) {
       continue;
@@ -1190,7 +1190,7 @@
   sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
 
   while (statement.Step()) {
-    absl::optional<StorageKey> storage_key =
+    std::optional<StorageKey> storage_key =
         StorageKey::Deserialize(statement.ColumnString(1));
     if (!storage_key.has_value()) {
       continue;
diff --git a/storage/browser/quota/quota_database.h b/storage/browser/quota/quota_database.h
index 1a460253..cc0fd37 100644
--- a/storage/browser/quota/quota_database.h
+++ b/storage/browser/quota/quota_database.h
@@ -12,6 +12,7 @@
 #include <set>
 #include <string>
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/files/file_path.h"
 #include "base/functional/callback.h"
@@ -28,7 +29,6 @@
 #include "components/services/storage/public/cpp/quota_error_or.h"
 #include "storage/browser/quota/quota_internals.mojom-forward.h"
 #include "storage/browser/quota/storage_directory.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/storage_key/storage_key.h"
 #include "third_party/blink/public/mojom/quota/quota_types.mojom-shared.h"
 
@@ -319,7 +319,7 @@
   static const size_t kIndexCount;
 
   // A descriptor of the last SQL statement that was executed, used for metrics.
-  absl::optional<std::string> last_operation_;
+  std::optional<std::string> last_operation_;
 
   base::RepeatingCallback<void(int)> db_error_callback_;
 };
diff --git a/storage/browser/quota/quota_database_migrations.cc b/storage/browser/quota/quota_database_migrations.cc
index 05715f4..ff85a1e 100644
--- a/storage/browser/quota/quota_database_migrations.cc
+++ b/storage/browser/quota/quota_database_migrations.cc
@@ -184,7 +184,7 @@
     std::string storage_key_string = select_statement.ColumnString(1);
     insert_statement.BindString(1, storage_key_string);
 
-    absl::optional<blink::StorageKey> storage_key =
+    std::optional<blink::StorageKey> storage_key =
         blink::StorageKey::Deserialize(storage_key_string);
     const std::string& host = storage_key.has_value()
                                   ? storage_key.value().origin().host()
diff --git a/storage/browser/quota/quota_database_unittest.cc b/storage/browser/quota/quota_database_unittest.cc
index 84a3473..9aee0ef 100644
--- a/storage/browser/quota/quota_database_unittest.cc
+++ b/storage/browser/quota/quota_database_unittest.cc
@@ -151,7 +151,7 @@
           quota_database->db_->GetCachedStatement(SQL_FROM_HERE, kSql));
       ASSERT_TRUE(statement.is_valid());
 
-      absl::optional<StorageKey> storage_key =
+      std::optional<StorageKey> storage_key =
           StorageKey::Deserialize(entry->storage_key);
       ASSERT_TRUE(storage_key.has_value());
 
diff --git a/storage/browser/quota/quota_manager_impl.cc b/storage/browser/quota/quota_manager_impl.cc
index f1f1e979..bd426a1 100644
--- a/storage/browser/quota/quota_manager_impl.cc
+++ b/storage/browser/quota/quota_manager_impl.cc
@@ -241,7 +241,7 @@
     weak_factory_.InvalidateWeakPtrs();
 
     int64_t quota = desired_storage_key_quota_;
-    absl::optional<int64_t> quota_override_size =
+    std::optional<int64_t> quota_override_size =
         manager()->GetQuotaOverrideForStorageKey(storage_key_);
     if (quota_override_size) {
       quota = *quota_override_size;
@@ -346,7 +346,7 @@
   const StorageKey storage_key_;
   // Non-null iff usage info is to be gathered for an individual bucket. If
   // null, usage is gathered for all buckets in the given host/StorageKey.
-  absl::optional<BucketInfo> bucket_info_;
+  std::optional<BucketInfo> bucket_info_;
   QuotaManagerImpl::UsageAndQuotaForDevtoolsCallback callback_;
   const StorageType type_;
   const bool is_unlimited_;
@@ -2020,7 +2020,7 @@
 
 void QuotaManagerImpl::NotifyBucketModified(QuotaClientType client_id,
                                             const BucketLocator& bucket,
-                                            absl::optional<int64_t> delta,
+                                            std::optional<int64_t> delta,
                                             base::Time modification_time,
                                             base::OnceClosure callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -2104,7 +2104,7 @@
       continue;
     }
 
-    absl::optional<StorageKey> storage_key =
+    std::optional<StorageKey> storage_key =
         StorageKey::Deserialize(entry->storage_key);
     // If the serialization format changes keys may not deserialize.
     if (!storage_key) {
@@ -2144,7 +2144,7 @@
   // Start the storage eviction routine on a full disk error.
   if (static_cast<sql::SqliteErrorCode>(error_code) ==
       sql::SqliteErrorCode::kFullDisk) {
-    OnFullDiskError(absl::nullopt);
+    OnFullDiskError(std::nullopt);
     return;
   }
 
@@ -2183,7 +2183,7 @@
                      weak_factory_.GetWeakPtr()));
 }
 
-void QuotaManagerImpl::OnFullDiskError(absl::optional<StorageKey> storage_key) {
+void QuotaManagerImpl::OnFullDiskError(std::optional<StorageKey> storage_key) {
   if ((base::TimeTicks::Now() - last_full_disk_eviction_time_) >
       base::Minutes(15)) {
     last_full_disk_eviction_time_ = base::TimeTicks::Now();
@@ -2417,7 +2417,7 @@
   if (storage_key_for_pending_storage_pressure_callback_.has_value()) {
     storage_pressure_callback_.Run(
         std::move(storage_key_for_pending_storage_pressure_callback_.value()));
-    storage_key_for_pending_storage_pressure_callback_ = absl::nullopt;
+    storage_key_for_pending_storage_pressure_callback_ = std::nullopt;
   }
 }
 
@@ -2429,7 +2429,7 @@
 void QuotaManagerImpl::OverrideQuotaForStorageKey(
     int handle_id,
     const StorageKey& storage_key,
-    absl::optional<int64_t> quota_size) {
+    std::optional<int64_t> quota_size) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK_GE(quota_size.value_or(0), 0)
       << "negative quota override: " << quota_size.value_or(0);
@@ -2465,11 +2465,11 @@
   }
 }
 
-absl::optional<int64_t> QuotaManagerImpl::GetQuotaOverrideForStorageKey(
+std::optional<int64_t> QuotaManagerImpl::GetQuotaOverrideForStorageKey(
     const StorageKey& storage_key) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (!base::Contains(devtools_overrides_, storage_key)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return devtools_overrides_[storage_key].quota_size;
 }
@@ -2555,7 +2555,7 @@
       continue;
     }
 
-    absl::optional<StorageKey> storage_key =
+    std::optional<StorageKey> storage_key =
         StorageKey::Deserialize(info->storage_key);
     if (!storage_key.has_value()) {
       continue;
@@ -2778,7 +2778,7 @@
                                             weak_factory_.GetWeakPtr()))));
 }
 
-void QuotaManagerImpl::DidGetSettings(absl::optional<QuotaSettings> settings) {
+void QuotaManagerImpl::DidGetSettings(std::optional<QuotaSettings> settings) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (!settings) {
diff --git a/storage/browser/quota/quota_manager_impl.h b/storage/browser/quota/quota_manager_impl.h
index 82476fc..7b0a55a 100644
--- a/storage/browser/quota/quota_manager_impl.h
+++ b/storage/browser/quota/quota_manager_impl.h
@@ -15,6 +15,7 @@
 #include <utility>
 #include <vector>
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/files/file_path.h"
 #include "base/functional/callback.h"
@@ -45,7 +46,6 @@
 #include "storage/browser/quota/quota_settings.h"
 #include "storage/browser/quota/quota_task.h"
 #include "storage/browser/quota/special_storage_policy.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/storage_key/storage_key.h"
 #include "third_party/blink/public/mojom/quota/quota_types.mojom-forward.h"
 #include "third_party/blink/public/mojom/quota/quota_types.mojom-shared.h"
@@ -320,7 +320,7 @@
   // cache to instead be discarded, after which it will be lazily recalculated.
   void NotifyBucketModified(QuotaClientType client_id,
                             const BucketLocator& bucket,
-                            absl::optional<int64_t> delta,
+                            std::optional<int64_t> delta,
                             base::Time modification_time,
                             base::OnceClosure callback);
 
@@ -452,7 +452,7 @@
   int GetOverrideHandleId();
   void OverrideQuotaForStorageKey(int handle_id,
                                   const blink::StorageKey& storage_key,
-                                  absl::optional<int64_t> quota_size);
+                                  std::optional<int64_t> quota_size);
   // Called when a DevTools client releases all overrides, however, overrides
   // will not be disabled for any storage keys for which there are other
   // DevTools clients/QuotaOverrideHandle with an active override.
@@ -653,7 +653,7 @@
 
   // Called when the quota database or a quota client run into low disk space
   // errors.
-  void OnFullDiskError(absl::optional<blink::StorageKey> storage_key);
+  void OnFullDiskError(std::optional<blink::StorageKey> storage_key);
 
   // Notifies the embedder that space is too low. This ends up showing a
   // user-facing dialog in Chrome.
@@ -698,7 +698,7 @@
       GetBucketsCallback callback,
       QuotaErrorOr<std::set<BucketLocator>> result);
   void GetQuotaSettings(QuotaSettingsCallback callback);
-  void DidGetSettings(absl::optional<QuotaSettings> settings);
+  void DidGetSettings(std::optional<QuotaSettings> settings);
   void GetStorageCapacity(StorageCapacityCallback callback);
   void ContinueIncognitoGetStorageCapacity(const QuotaSettings& settings);
   void DidGetStorageCapacity(const QuotaAvailability& total_and_available);
@@ -748,7 +748,7 @@
   // to use DetermineStoragePressure().
   void DetermineStoragePressure(int64_t free_space, int64_t total_space);
 
-  absl::optional<int64_t> GetQuotaOverrideForStorageKey(
+  std::optional<int64_t> GetQuotaOverrideForStorageKey(
       const blink::StorageKey&);
 
   template <typename ValueType>
@@ -779,7 +779,7 @@
   bool eviction_disabled_ = false;
   bool bootstrap_disabled_for_testing_ = false;
 
-  absl::optional<blink::StorageKey>
+  std::optional<blink::StorageKey>
       storage_key_for_pending_storage_pressure_callback_;
   scoped_refptr<base::SingleThreadTaskRunner> io_thread_;
   scoped_refptr<base::SequencedTaskRunner> db_runner_;
@@ -810,7 +810,7 @@
   // The storage key for the last time a bucket was opened. This is used as an
   // imperfect estimate of which site may have encountered the last quota
   // database full disk error.
-  absl::optional<blink::StorageKey> last_opened_bucket_site_;
+  std::optional<blink::StorageKey> last_opened_bucket_site_;
 
   // The last time that an eviction round was started due to a full disk error.
   base::TimeTicks last_full_disk_eviction_time_;
diff --git a/storage/browser/quota/quota_manager_proxy.cc b/storage/browser/quota/quota_manager_proxy.cc
index 9024264..6b3f46d 100644
--- a/storage/browser/quota/quota_manager_proxy.cc
+++ b/storage/browser/quota/quota_manager_proxy.cc
@@ -440,7 +440,7 @@
 void QuotaManagerProxy::NotifyBucketModified(
     QuotaClientType client_id,
     const BucketLocator& bucket,
-    absl::optional<int64_t> delta,
+    std::optional<int64_t> delta,
     base::Time modification_time,
     scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
     base::OnceClosure callback) {
@@ -650,7 +650,7 @@
 void QuotaManagerProxy::OverrideQuotaForStorageKey(
     int handle_id,
     const StorageKey& storage_key,
-    absl::optional<int64_t> quota_size,
+    std::optional<int64_t> quota_size,
     scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
     base::OnceClosure callback) {
   DCHECK(callback_task_runner);
diff --git a/storage/browser/quota/quota_manager_proxy.h b/storage/browser/quota/quota_manager_proxy.h
index f15517c..7446b10 100644
--- a/storage/browser/quota/quota_manager_proxy.h
+++ b/storage/browser/quota/quota_manager_proxy.h
@@ -10,6 +10,7 @@
 #include <memory>
 #include <vector>
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
@@ -26,7 +27,6 @@
 #include "storage/browser/quota/quota_callbacks.h"
 #include "storage/browser/quota/quota_client_type.h"
 #include "storage/browser/quota/quota_manager_impl.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/mojom/quota/quota_types.mojom.h"
 
 namespace blink {
@@ -195,7 +195,7 @@
   virtual void NotifyBucketModified(
       QuotaClientType client_id,
       const BucketLocator& bucket,
-      absl::optional<int64_t> delta,
+      std::optional<int64_t> delta,
       base::Time modification_time,
       scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
       base::OnceClosure callback);
@@ -248,7 +248,7 @@
   void OverrideQuotaForStorageKey(
       int handle_id,
       const blink::StorageKey& storage_key,
-      absl::optional<int64_t> quota_size,
+      std::optional<int64_t> quota_size,
       scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
       base::OnceClosure callback);
   void WithdrawOverridesForHandle(int handle_id);
diff --git a/storage/browser/quota/quota_manager_unittest.cc b/storage/browser/quota/quota_manager_unittest.cc
index c027aeb..7909d2f 100644
--- a/storage/browser/quota/quota_manager_unittest.cc
+++ b/storage/browser/quota/quota_manager_unittest.cc
@@ -596,7 +596,7 @@
   int64_t quota() const { return quota_; }
   int64_t total_space() const { return total_space_; }
   int64_t available_space() const { return available_space_; }
-  const absl::optional<BucketLocator>& eviction_bucket() const {
+  const std::optional<BucketLocator>& eviction_bucket() const {
     return eviction_bucket_;
   }
   const QuotaSettings& settings() const { return settings_; }
@@ -623,8 +623,8 @@
     explicit ObserverNotification(BucketLocator locator)
         : type(ObserverNotifyType::kDelete), bucket_locator(locator) {}
     ObserverNotifyType type;
-    absl::optional<BucketInfo> bucket_info;
-    absl::optional<BucketLocator> bucket_locator;
+    std::optional<BucketInfo> bucket_info;
+    std::optional<BucketLocator> bucket_locator;
   };
 
   base::test::ScopedFeatureList scoped_feature_list_;
@@ -681,7 +681,7 @@
   int64_t quota_;
   int64_t total_space_;
   int64_t available_space_;
-  absl::optional<BucketLocator> eviction_bucket_;
+  std::optional<BucketLocator> eviction_bucket_;
   QuotaSettings settings_;
   std::unique_ptr<QuotaManagerObserverTest> quota_manager_observer_test_;
   std::unique_ptr<base::RunLoop> quota_manager_observer_run_loop_;
@@ -869,7 +869,7 @@
   // Dirty the cache by passing a null delta.
   quota_manager_impl()->NotifyBucketModified(
       QuotaClientType::kFileSystem, first_bucket_locator,
-      /*delta=*/absl::nullopt, base::Time::Now(), base::DoNothing());
+      /*delta=*/std::nullopt, base::Time::Now(), base::DoNothing());
 
   {
     base::test::TestFuture<UsageInfoEntries> future;
@@ -2515,7 +2515,7 @@
       continue;
     }
 
-    absl::optional<StorageKey> storage_key =
+    std::optional<StorageKey> storage_key =
         StorageKey::Deserialize(entry->storage_key);
     ASSERT_TRUE(storage_key.has_value());
 
@@ -2612,7 +2612,7 @@
       continue;
     }
 
-    absl::optional<StorageKey> storage_key =
+    std::optional<StorageKey> storage_key =
         StorageKey::Deserialize(entry->storage_key);
     ASSERT_TRUE(storage_key.has_value());
 
@@ -3442,7 +3442,7 @@
 
   base::RunLoop run_loop3;
   handle2->OverrideQuotaForStorageKey(
-      storage_key, absl::nullopt,
+      storage_key, std::nullopt,
       base::BindLambdaForTesting([&]() { run_loop3.Quit(); }));
   run_loop3.Run();
 
diff --git a/storage/browser/quota/quota_override_handle.cc b/storage/browser/quota/quota_override_handle.cc
index 85cb288..e9d90bd 100644
--- a/storage/browser/quota/quota_override_handle.cc
+++ b/storage/browser/quota/quota_override_handle.cc
@@ -31,7 +31,7 @@
 
 void QuotaOverrideHandle::OverrideQuotaForStorageKey(
     const blink::StorageKey& storage_key,
-    absl::optional<int64_t> quota_size,
+    std::optional<int64_t> quota_size,
     base::OnceClosure callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (!id_.has_value()) {
@@ -51,7 +51,7 @@
 void QuotaOverrideHandle::DidGetOverrideHandleId(int id) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(!id_.has_value());
-  id_ = absl::make_optional(id);
+  id_ = std::make_optional(id);
 
   for (auto& callback : override_callback_queue_) {
     std::move(callback).Run();
diff --git a/storage/browser/quota/quota_override_handle.h b/storage/browser/quota/quota_override_handle.h
index 834eeeee..d9cbf8a5 100644
--- a/storage/browser/quota/quota_override_handle.h
+++ b/storage/browser/quota/quota_override_handle.h
@@ -31,7 +31,7 @@
   QuotaOverrideHandle(const QuotaOverrideHandle&) = delete;
 
   void OverrideQuotaForStorageKey(const blink::StorageKey& storage_key,
-                                  absl::optional<int64_t> quota_size,
+                                  std::optional<int64_t> quota_size,
                                   base::OnceClosure callback);
 
  private:
@@ -43,7 +43,7 @@
 
   const scoped_refptr<QuotaManagerProxy> quota_manager_proxy_
       GUARDED_BY_CONTEXT(sequence_checker_);
-  absl::optional<int> id_ GUARDED_BY_CONTEXT(sequence_checker_);
+  std::optional<int> id_ GUARDED_BY_CONTEXT(sequence_checker_);
   std::vector<base::OnceClosure> override_callback_queue_
       GUARDED_BY_CONTEXT(sequence_checker_);
 
diff --git a/storage/browser/quota/quota_settings.cc b/storage/browser/quota/quota_settings.cc
index b90b655..e530531 100644
--- a/storage/browser/quota/quota_settings.cc
+++ b/storage/browser/quota/quota_settings.cc
@@ -53,7 +53,7 @@
   return settings;
 }
 
-absl::optional<QuotaSettings> CalculateNominalDynamicSettings(
+std::optional<QuotaSettings> CalculateNominalDynamicSettings(
     const base::FilePath& partition_path,
     bool is_incognito,
     QuotaDeviceInfoHelper* device_info_helper) {
@@ -124,7 +124,7 @@
   int64_t total = device_info_helper->AmountOfTotalDiskSpace(partition_path);
   if (total == -1) {
     LOG(ERROR) << "Unable to compute QuotaSettings.";
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Pool size calculated by ratio.
diff --git a/storage/browser/quota/quota_settings.h b/storage/browser/quota/quota_settings.h
index 41b41a07..9fd8a98 100644
--- a/storage/browser/quota/quota_settings.h
+++ b/storage/browser/quota/quota_settings.h
@@ -7,12 +7,12 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/files/file_path.h"
 #include "base/functional/callback.h"
 #include "base/time/time.h"
 #include "storage/browser/quota/quota_device_info_helper.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace storage {
 
@@ -60,9 +60,9 @@
 
 // Function type used to return the settings in response to a
 // GetQuotaSettingsFunc invocation. If the embedder cannot
-// produce a settings values, absl::nullopt can be returned.
+// produce a settings values, std::nullopt can be returned.
 using OptionalQuotaSettingsCallback =
-    base::OnceCallback<void(absl::optional<QuotaSettings>)>;
+    base::OnceCallback<void(std::optional<QuotaSettings>)>;
 
 // Function type used to query the embedder about the quota manager settings.
 // This function is invoked on the UI thread.
diff --git a/storage/browser/quota/quota_settings_unittest.cc b/storage/browser/quota/quota_settings_unittest.cc
index 97e6088..55764e8 100644
--- a/storage/browser/quota/quota_settings_unittest.cc
+++ b/storage/browser/quota/quota_settings_unittest.cc
@@ -5,6 +5,7 @@
 #include <memory>
 #include <utility>
 
+#include <optional>
 #include "base/files/scoped_temp_dir.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
@@ -17,7 +18,6 @@
 #include "storage/browser/quota/quota_features.h"
 #include "storage/browser/quota/quota_settings.h"
 #include "testing/gmock/include/gmock/gmock.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using ::testing::_;
 
@@ -43,14 +43,14 @@
   void SetUp() override { ASSERT_TRUE(data_dir_.CreateUniqueTempDir()); }
 
   // Synchronous proxy to GetNominalDynamicSettings().
-  absl::optional<QuotaSettings> GetSettings(
+  std::optional<QuotaSettings> GetSettings(
       bool is_incognito,
       QuotaDeviceInfoHelper* device_info_helper) {
-    absl::optional<QuotaSettings> quota_settings;
+    std::optional<QuotaSettings> quota_settings;
     base::RunLoop run_loop;
     GetNominalDynamicSettings(
         profile_path(), is_incognito, device_info_helper,
-        base::BindLambdaForTesting([&](absl::optional<QuotaSettings> settings) {
+        base::BindLambdaForTesting([&](std::optional<QuotaSettings> settings) {
           quota_settings = std::move(settings);
           run_loop.Quit();
         }));
@@ -80,7 +80,7 @@
   }
 
   void GetAndTestSettings(const uint64_t physical_memory_amount) {
-    absl::optional<QuotaSettings> settings =
+    std::optional<QuotaSettings> settings =
         GetSettings(true, &device_info_helper_);
     ASSERT_TRUE(settings.has_value());
     const uint64_t pool_size =
@@ -102,7 +102,7 @@
   ON_CALL(device_info_helper, AmountOfTotalDiskSpace(_))
       .WillByDefault(::testing::Return(2000));
 
-  absl::optional<QuotaSettings> settings =
+  std::optional<QuotaSettings> settings =
       GetSettings(false, &device_info_helper);
   ASSERT_TRUE(settings.has_value());
   // 1600 = 2000 * default PoolSizeRatio (0.8)
@@ -124,7 +124,7 @@
   ON_CALL(device_info_helper, AmountOfTotalDiskSpace(_))
       .WillByDefault(::testing::Return(2000));
 
-  absl::optional<QuotaSettings> settings =
+  std::optional<QuotaSettings> settings =
       GetSettings(false, &device_info_helper);
   ASSERT_TRUE(settings.has_value());
 
@@ -146,7 +146,7 @@
   ON_CALL(device_info_helper, AmountOfTotalDiskSpace(_))
       .WillByDefault(::testing::Return(2000));
 
-  absl::optional<QuotaSettings> settings =
+  std::optional<QuotaSettings> settings =
       GetSettings(false, &device_info_helper);
   ASSERT_TRUE(settings.has_value());
 
@@ -165,7 +165,7 @@
   ON_CALL(device_info_helper, AmountOfTotalDiskSpace(_))
       .WillByDefault(::testing::Return(2000));
 
-  absl::optional<QuotaSettings> settings =
+  std::optional<QuotaSettings> settings =
       GetSettings(false, &device_info_helper);
   ASSERT_TRUE(settings.has_value());
 
diff --git a/storage/browser/quota/quota_temporary_storage_evictor.h b/storage/browser/quota/quota_temporary_storage_evictor.h
index 4e3d4e4..c700540 100644
--- a/storage/browser/quota/quota_temporary_storage_evictor.h
+++ b/storage/browser/quota/quota_temporary_storage_evictor.h
@@ -11,6 +11,7 @@
 #include <set>
 #include <string>
 
+#include <optional>
 #include "base/component_export.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
@@ -18,7 +19,6 @@
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "components/services/storage/public/cpp/buckets/bucket_locator.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/mojom/quota/quota_types.mojom.h"
 
 namespace storage {
diff --git a/storage/browser/quota/quota_temporary_storage_evictor_unittest.cc b/storage/browser/quota/quota_temporary_storage_evictor_unittest.cc
index 8f4b15c..43e059be 100644
--- a/storage/browser/quota/quota_temporary_storage_evictor_unittest.cc
+++ b/storage/browser/quota/quota_temporary_storage_evictor_unittest.cc
@@ -177,9 +177,9 @@
   }
 
   void TaskForRepeatedEvictionTest(
-      const std::pair<absl::optional<BucketLocator>, int64_t>&
+      const std::pair<std::optional<BucketLocator>, int64_t>&
           bucket_to_be_added,
-      const absl::optional<BucketLocator> bucket_to_be_accessed,
+      const std::optional<BucketLocator> bucket_to_be_accessed,
       int expected_usage_after_first,
       int expected_usage_after_second) {
     EXPECT_GE(4, num_get_usage_and_quota_for_eviction_);
@@ -370,7 +370,7 @@
           weak_factory_.GetWeakPtr(),
           std::make_pair(CreateBucket("http://www.e.com", /*is_default=*/false),
                          e_size),
-          absl::nullopt,
+          std::nullopt,
           // First round evicts d.
           initial_total_size - d_size,
           // Second round evicts c and b.
@@ -409,8 +409,8 @@
   quota_eviction_handler()->set_task_for_get_usage_and_quota(
       base::BindRepeating(
           &QuotaTemporaryStorageEvictorTest::TaskForRepeatedEvictionTest,
-          weak_factory_.GetWeakPtr(), std::make_pair(absl::nullopt, 0),
-          absl::nullopt, initial_total_size - d_size,
+          weak_factory_.GetWeakPtr(), std::make_pair(std::nullopt, 0),
+          std::nullopt, initial_total_size - d_size,
           initial_total_size - d_size));
   EXPECT_EQ(initial_total_size, quota_eviction_handler()->GetUsage());
   temporary_storage_evictor()->Start();
@@ -453,7 +453,7 @@
           weak_factory_.GetWeakPtr(),
           std::make_pair(CreateBucket("http://www.e.com", /*is_default=*/false),
                          e_size),
-          absl::nullopt, initial_total_size - d_size,
+          std::nullopt, initial_total_size - d_size,
           initial_total_size - d_size + e_size - c_size));
   EXPECT_EQ(initial_total_size, quota_eviction_handler()->GetUsage());
   temporary_storage_evictor()->Start();
@@ -494,8 +494,8 @@
   quota_eviction_handler()->set_task_for_get_usage_and_quota(
       base::BindRepeating(
           &QuotaTemporaryStorageEvictorTest::TaskForRepeatedEvictionTest,
-          weak_factory_.GetWeakPtr(), std::make_pair(absl::nullopt, 0),
-          absl::nullopt, initial_total_size - d_size,
+          weak_factory_.GetWeakPtr(), std::make_pair(std::nullopt, 0),
+          std::nullopt, initial_total_size - d_size,
           initial_total_size - d_size));
   EXPECT_EQ(initial_total_size, quota_eviction_handler()->GetUsage());
   // disable_timer_for_testing();
diff --git a/storage/browser/quota/usage_tracker.cc b/storage/browser/quota/usage_tracker.cc
index b8e4dd06..5f02aab7 100644
--- a/storage/browser/quota/usage_tracker.cc
+++ b/storage/browser/quota/usage_tracker.cc
@@ -107,7 +107,7 @@
 
 void UsageTracker::UpdateBucketUsageCache(QuotaClientType client_type,
                                           const BucketLocator& bucket,
-                                          absl::optional<int64_t> delta) {
+                                          std::optional<int64_t> delta) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   GetClient(client_type).UpdateBucketUsageCache(bucket, delta);
diff --git a/storage/browser/quota/usage_tracker.h b/storage/browser/quota/usage_tracker.h
index 96e2619..5769780 100644
--- a/storage/browser/quota/usage_tracker.h
+++ b/storage/browser/quota/usage_tracker.h
@@ -78,7 +78,7 @@
   // Updates usage for `bucket` in the ClientUsageTracker for `client_type`.
   void UpdateBucketUsageCache(QuotaClientType client_type,
                               const BucketLocator& bucket,
-                              absl::optional<int64_t> delta);
+                              std::optional<int64_t> delta);
 
   // Deletes `bucket` from the cache for `client_type` if it exists.
   // Called by QuotaManagerImpl::BucketDataDeleter.
diff --git a/storage/browser/test/mock_bytes_provider.cc b/storage/browser/test/mock_bytes_provider.cc
index 8441556..f2c2c7d 100644
--- a/storage/browser/test/mock_bytes_provider.cc
+++ b/storage/browser/test/mock_bytes_provider.cc
@@ -15,7 +15,7 @@
     size_t* reply_request_count,
     size_t* stream_request_count,
     size_t* file_request_count,
-    absl::optional<base::Time> file_modification_time)
+    std::optional<base::Time> file_modification_time)
     : data_(std::move(data)),
       reply_request_count_(reply_request_count),
       stream_request_count_(stream_request_count),
diff --git a/storage/browser/test/mock_bytes_provider.h b/storage/browser/test/mock_bytes_provider.h
index 98d30db..ae27962 100644
--- a/storage/browser/test/mock_bytes_provider.h
+++ b/storage/browser/test/mock_bytes_provider.h
@@ -22,7 +22,7 @@
       size_t* reply_request_count = nullptr,
       size_t* stream_request_count = nullptr,
       size_t* file_request_count = nullptr,
-      absl::optional<base::Time> file_modification_time = base::Time());
+      std::optional<base::Time> file_modification_time = base::Time());
   ~MockBytesProvider() override;
 
   // BytesProvider implementation:
@@ -39,7 +39,7 @@
   raw_ptr<size_t> reply_request_count_;
   raw_ptr<size_t> stream_request_count_;
   raw_ptr<size_t> file_request_count_;
-  absl::optional<base::Time> file_modification_time_;
+  std::optional<base::Time> file_modification_time_;
 };
 
 }  // namespace storage
diff --git a/storage/browser/test/mock_quota_manager.cc b/storage/browser/test/mock_quota_manager.cc
index c6718ca..ae95b90 100644
--- a/storage/browser/test/mock_quota_manager.cc
+++ b/storage/browser/test/mock_quota_manager.cc
@@ -391,7 +391,7 @@
 }
 
 void MockQuotaManager::UpdateUsage(const BucketLocator& bucket,
-                                   absl::optional<int64_t> delta) {
+                                   std::optional<int64_t> delta) {
   if (delta) {
     usage_map_[bucket].usage += *delta;
   } else {
diff --git a/storage/browser/test/mock_quota_manager.h b/storage/browser/test/mock_quota_manager.h
index 87be449..fcf8608e 100644
--- a/storage/browser/test/mock_quota_manager.h
+++ b/storage/browser/test/mock_quota_manager.h
@@ -228,7 +228,7 @@
       blink::mojom::StorageType type);
 
   // This must be called via MockQuotaManagerProxy.
-  void UpdateUsage(const BucketLocator& bucket, absl::optional<int64_t> delta);
+  void UpdateUsage(const BucketLocator& bucket, std::optional<int64_t> delta);
 
   void DidGetBucket(base::OnceCallback<void(QuotaErrorOr<BucketInfo>)> callback,
                     QuotaErrorOr<BucketInfo> result);
diff --git a/storage/browser/test/mock_quota_manager_proxy.cc b/storage/browser/test/mock_quota_manager_proxy.cc
index dd6bffd..2295ebd8 100644
--- a/storage/browser/test/mock_quota_manager_proxy.cc
+++ b/storage/browser/test/mock_quota_manager_proxy.cc
@@ -109,7 +109,7 @@
 void MockQuotaManagerProxy::NotifyBucketModified(
     QuotaClientType client_id,
     const BucketLocator& bucket,
-    absl::optional<int64_t> delta,
+    std::optional<int64_t> delta,
     base::Time modification_time,
     scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
     base::OnceClosure callback) {
diff --git a/storage/browser/test/mock_quota_manager_proxy.h b/storage/browser/test/mock_quota_manager_proxy.h
index b0728fd..7dcf57f 100644
--- a/storage/browser/test/mock_quota_manager_proxy.h
+++ b/storage/browser/test/mock_quota_manager_proxy.h
@@ -95,7 +95,7 @@
   void NotifyBucketModified(
       QuotaClientType client_id,
       const BucketLocator& bucket,
-      absl::optional<int64_t> delta,
+      std::optional<int64_t> delta,
       base::Time modification_time,
       scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
       base::OnceClosure callback) override;
@@ -117,7 +117,7 @@
   int notify_bucket_accessed_count() const { return bucket_accessed_count_; }
   int notify_bucket_modified_count() const { return bucket_modified_count_; }
   BucketId last_notified_bucket_id() const { return last_notified_bucket_id_; }
-  absl::optional<int64_t> last_notified_bucket_delta() const {
+  std::optional<int64_t> last_notified_bucket_delta() const {
     return last_notified_bucket_delta_;
   }
 
@@ -135,7 +135,7 @@
   int bucket_accessed_count_ = 0;
   int bucket_modified_count_ = 0;
   BucketId last_notified_bucket_id_ = BucketId::FromUnsafeValue(-1);
-  absl::optional<int64_t> last_notified_bucket_delta_;
+  std::optional<int64_t> last_notified_bucket_delta_;
 };
 
 }  // namespace storage
diff --git a/storage/browser/test/sandbox_file_system_test_helper.h b/storage/browser/test/sandbox_file_system_test_helper.h
index e12b66b..9ec8d3b 100644
--- a/storage/browser/test/sandbox_file_system_test_helper.h
+++ b/storage/browser/test/sandbox_file_system_test_helper.h
@@ -109,7 +109,7 @@
   void SetUpFileSystem();
 
   scoped_refptr<FileSystemContext> file_system_context_;
-  absl::optional<BucketLocator> bucket_locator_;
+  std::optional<BucketLocator> bucket_locator_;
 
   blink::StorageKey storage_key_;
   const FileSystemType type_;
diff --git a/testing/perf/luci_test_result.h b/testing/perf/luci_test_result.h
index 9e0496c..172c4df9 100644
--- a/testing/perf/luci_test_result.h
+++ b/testing/perf/luci_test_result.h
@@ -8,10 +8,10 @@
 #include <string>
 #include <vector>
 
+#include <optional>
 #include "base/containers/flat_map.h"
 #include "base/files/file_path.h"
 #include "base/time/time.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace perf_test {
 
@@ -47,9 +47,9 @@
 
     // Use only one of the two fields below.
     // Absolute path on the same machine running the test.
-    absl::optional<base::FilePath> file_path;
+    std::optional<base::FilePath> file_path;
     // The data of the artifact.
-    absl::optional<std::string> contents;
+    std::optional<std::string> contents;
 
     std::string content_type;
   };
diff --git a/testing/perf/luci_test_result_unittest.cc b/testing/perf/luci_test_result_unittest.cc
index cff07b9..f0068182 100644
--- a/testing/perf/luci_test_result_unittest.cc
+++ b/testing/perf/luci_test_result_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "testing/perf/luci_test_result.h"
 
+#include <optional>
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
@@ -11,7 +12,6 @@
 #include "base/strings/stringprintf.h"
 #include "base/time/time.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace perf_test {
 
@@ -43,10 +43,10 @@
 
     std::string json;
     ASSERT_TRUE(ReadFileToString(GetResultFilePath(), &json));
-    absl::optional<base::Value> value = base::JSONReader::Read(json);
+    std::optional<base::Value> value = base::JSONReader::Read(json);
     ASSERT_TRUE(value.has_value());
 
-    absl::optional<base::Value> expected_value =
+    std::optional<base::Value> expected_value =
         base::JSONReader::Read(expected_json);
     ASSERT_TRUE(expected_value.has_value());
 
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_delegate.cc b/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_delegate.cc
index ca95bbb..4b61f2b 100644
--- a/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_delegate.cc
+++ b/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_delegate.cc
@@ -55,7 +55,7 @@
       StringFromFullPath(file_path), sync_dir);
 }
 
-absl::optional<sql::SandboxedVfs::PathAccessInfo>
+std::optional<sql::SandboxedVfs::PathAccessInfo>
 SandboxedVfsDelegate::GetPathAccess(const base::FilePath& file_path) {
   int32_t attributes = WebDatabaseHost::GetInstance().GetFileAttributes(
       StringFromFullPath(file_path));
@@ -71,7 +71,7 @@
 #endif  // BUILDFLAG(IS_WIN)
 
   if (!file_exists)
-    return absl::nullopt;
+    return std::nullopt;
 
   sql::SandboxedVfs::PathAccessInfo access;
 #if BUILDFLAG(IS_WIN)
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_delegate.h b/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_delegate.h
index 150941ff..06101e1 100644
--- a/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_delegate.h
+++ b/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_delegate.h
@@ -18,7 +18,7 @@
   base::File OpenFile(const base::FilePath& file_path,
                       int sqlite_requested_flags) override;
   int DeleteFile(const base::FilePath& file_path, bool sync_dir) override;
-  absl::optional<sql::SandboxedVfs::PathAccessInfo> GetPathAccess(
+  std::optional<sql::SandboxedVfs::PathAccessInfo> GetPathAccess(
       const base::FilePath& file_path) override;
   bool SetFileLength(const base::FilePath& file_path,
                      base::File& file,
diff --git a/tools/win/chromeexts/commands/view_command.cc b/tools/win/chromeexts/commands/view_command.cc
index b1ebd33..b1b3f0a 100644
--- a/tools/win/chromeexts/commands/view_command.cc
+++ b/tools/win/chromeexts/commands/view_command.cc
@@ -157,7 +157,7 @@
     return buffer;
   }
 
-  absl::optional<intptr_t> GetAddress() override {
+  std::optional<intptr_t> GetAddress() override {
     return view_block_.address();
   }
 
diff --git a/ui/gfx/mac/color_space_util.mm b/ui/gfx/mac/color_space_util.mm
index c31cb93a..2e396bb 100644
--- a/ui/gfx/mac/color_space_util.mm
+++ b/ui/gfx/mac/color_space_util.mm
@@ -6,6 +6,7 @@
 
 #include <CoreMedia/CoreMedia.h>
 #include <CoreVideo/CoreVideo.h>
+#include <optional>
 
 #include "base/apple/foundation_util.h"
 #include "base/apple/scoped_cftyperef.h"