diff --git a/Cargo.lock b/Cargo.lock
index b66579b839..4eb2777bff 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4027,6 +4027,10 @@ dependencies = [
  "wasm-bindgen-futures",
  "web-sys",
  "wgpu-core",
+ "wgpu-core-if-arch-wasm",
+ "wgpu-core-if-target-apple",
+ "wgpu-core-if-target-unix-non-apple",
+ "wgpu-core-if-target-windows",
  "wgpu-hal",
  "wgpu-types",
 ]
@@ -4074,6 +4078,34 @@ dependencies = [
  "wgpu-types",
 ]
 
+[[package]]
+name = "wgpu-core-if-arch-wasm"
+version = "24.0.0"
+dependencies = [
+ "wgpu-core",
+]
+
+[[package]]
+name = "wgpu-core-if-target-apple"
+version = "24.0.0"
+dependencies = [
+ "wgpu-core",
+]
+
+[[package]]
+name = "wgpu-core-if-target-unix-non-apple"
+version = "24.0.0"
+dependencies = [
+ "wgpu-core",
+]
+
+[[package]]
+name = "wgpu-core-if-target-windows"
+version = "24.0.0"
+dependencies = [
+ "wgpu-core",
+]
+
 [[package]]
 name = "wgpu-example-01-hello-compute"
 version = "0.0.0"
diff --git a/Cargo.toml b/Cargo.toml
index 5e5efd0513..bb4f90e3cf 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,6 +21,10 @@ members = [
     "wgpu-macros",
     "wgpu-types",
     "wgpu",
+    "wgpu-core-conditional/arch-wasm",
+    "wgpu-core-conditional/target-unix-non-apple",
+    "wgpu-core-conditional/target-apple",
+    "wgpu-core-conditional/target-windows",
 ]
 exclude = []
 default-members = [
@@ -40,6 +44,10 @@ default-members = [
     "wgpu-macros",
     "wgpu-types",
     "wgpu",
+    "wgpu-core-conditional/arch-wasm",
+    "wgpu-core-conditional/target-unix-non-apple",
+    "wgpu-core-conditional/target-apple",
+    "wgpu-core-conditional/target-windows",
 ]
 
 [workspace.lints.clippy]
@@ -61,11 +69,19 @@ naga = { version = "24.0.0", path = "./naga" }
 wgpu = { version = "24.0.0", path = "./wgpu", default-features = false, features = [
     "serde",
     "wgsl",
+    "static-dxc",
+
+    # Enabled all native non-indirect (not going through additional layers like Angle) backends for testing.
     "dx12",
     "metal",
-    "static-dxc",
+    "vulkan",
+    "gles",
 ] }
 wgpu-core = { version = "24.0.0", path = "./wgpu-core" }
+wgpu-core-if-arch-wasm = { version = "24.0.0", path = "./wgpu-core-conditional/arch-wasm" }
+wgpu-core-if-target-unix-non-apple = { version = "24.0.0", path = "./wgpu-core-conditional/target-unix-non-apple" }
+wgpu-core-if-target-apple = { version = "24.0.0", path = "./wgpu-core-conditional/target-apple" }
+wgpu-core-if-target-windows = { version = "24.0.0", path = "./wgpu-core-conditional/target-windows" }
 wgpu-hal = { version = "24.0.0", path = "./wgpu-hal" }
 wgpu-macros = { version = "24.0.0", path = "./wgpu-macros" }
 wgpu-test = { version = "24.0.0", path = "./tests" }
@@ -167,7 +183,7 @@ glutin_wgl_sys = "0.6"
 # DX12 and GLES dependencies
 windows = { version = "0.58", default-features = false }
 
-# wasm32 dependencies
+# wasm dependencies
 console_error_panic_hook = "0.1.7"
 console_log = "1"
 js-sys = { version = "0.3.70", default-features = false }
diff --git a/wgpu-core-conditional/arch-wasm/Cargo.toml b/wgpu-core-conditional/arch-wasm/Cargo.toml
new file mode 100644
index 0000000000..9dfc39d794
--- /dev/null
+++ b/wgpu-core-conditional/arch-wasm/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+name = "wgpu-core-if-arch-wasm"
+version.workspace = true
+authors.workspace = true
+edition.workspace = true
+description = "Workaround crate for enabling in wgpu-core when targeting wasm"
+homepage.workspace = true
+repository.workspace = true
+keywords.workspace = true
+license.workspace = true
+
+[lib]
+
+[features]
+gles = ["wgpu-core/gles"]
+
+[target.'cfg(target_arch = "wasm32")'.dependencies]
+wgpu-core.workspace = true
diff --git a/wgpu-core-conditional/arch-wasm/src/lib.rs b/wgpu-core-conditional/arch-wasm/src/lib.rs
new file mode 100644
index 0000000000..c0eb59f8c9
--- /dev/null
+++ b/wgpu-core-conditional/arch-wasm/src/lib.rs
@@ -0,0 +1,4 @@
+//! No code. See README.md for details.
+
+#[cfg(target_arch = "wasm32")]
+pub use wgpu_core::*;
diff --git a/wgpu-core-conditional/target-apple/Cargo.toml b/wgpu-core-conditional/target-apple/Cargo.toml
new file mode 100644
index 0000000000..3d9f2cd3fc
--- /dev/null
+++ b/wgpu-core-conditional/target-apple/Cargo.toml
@@ -0,0 +1,22 @@
+[package]
+name = "wgpu-core-if-target-apple"
+version.workspace = true
+authors.workspace = true
+edition.workspace = true
+description = "Workaround crate for enabling wgpu-core when targeting macOS/iOS/tvOS/VisionOS"
+homepage.workspace = true
+repository.workspace = true
+keywords.workspace = true
+license.workspace = true
+
+[lib]
+
+[features]
+gles = ["wgpu-core/gles"]
+metal = ["wgpu-core/metal"]
+vulkan = ["wgpu-core/vulkan"]
+
+raw-window-handle = ["wgpu-core/raw-window-handle"]
+
+[target.'cfg(target_vendor = "apple")'.dependencies]
+wgpu-core.workspace = true
diff --git a/wgpu-core-conditional/target-apple/src/lib.rs b/wgpu-core-conditional/target-apple/src/lib.rs
new file mode 100644
index 0000000000..a3037e84f7
--- /dev/null
+++ b/wgpu-core-conditional/target-apple/src/lib.rs
@@ -0,0 +1,4 @@
+//! No code. See README.md for details.
+
+#[cfg(target_vendor = "apple")]
+pub use wgpu_core;
diff --git a/wgpu-core-conditional/target-unix-non-apple/Cargo.toml b/wgpu-core-conditional/target-unix-non-apple/Cargo.toml
new file mode 100644
index 0000000000..f374092b3c
--- /dev/null
+++ b/wgpu-core-conditional/target-unix-non-apple/Cargo.toml
@@ -0,0 +1,20 @@
+[package]
+name = "wgpu-core-if-target-unix-non-apple"
+version.workspace = true
+authors.workspace = true
+edition.workspace = true
+description = "Workaround crate for enabling in wgpu-core when targeting native non-apple native unix platforms"
+homepage.workspace = true
+repository.workspace = true
+keywords.workspace = true
+license.workspace = true
+
+[lib]
+
+[features]
+gles = ["wgpu-core/gles"]
+renderdoc = ["wgpu-core/renderdoc"]
+vulkan = ["wgpu-core/vulkan"]
+
+[target.'cfg(all(unix, not(target_os = "emscripten"), not(target_vendor = "apple")))'.dependencies]
+wgpu-core.workspace = true
diff --git a/wgpu-core-conditional/target-unix-non-apple/src/lib.rs b/wgpu-core-conditional/target-unix-non-apple/src/lib.rs
new file mode 100644
index 0000000000..8d2204d915
--- /dev/null
+++ b/wgpu-core-conditional/target-unix-non-apple/src/lib.rs
@@ -0,0 +1,4 @@
+//! No code. See README.md for details.
+
+#[cfg(all(unix, not(target_os = "emscripten"), not(target_vendor = "apple")))]
+pub use wgpu_core::*;
diff --git a/wgpu-core-conditional/target-windows/Cargo.toml b/wgpu-core-conditional/target-windows/Cargo.toml
new file mode 100644
index 0000000000..f19033adf7
--- /dev/null
+++ b/wgpu-core-conditional/target-windows/Cargo.toml
@@ -0,0 +1,20 @@
+[package]
+name = "wgpu-core-if-target-windows"
+version.workspace = true
+authors.workspace = true
+edition.workspace = true
+description = "Workaround crate for enabling wgpu-core when targeting windows"
+homepage.workspace = true
+repository.workspace = true
+keywords.workspace = true
+license.workspace = true
+
+[lib]
+
+[features]
+dx12 = ["wgpu-core/dx12"]
+gles = ["wgpu-core/gles"]
+vulkan = ["wgpu-core/vulkan"]
+
+[target.'cfg(windows)'.dependencies]
+wgpu-core.workspace = true
diff --git a/wgpu-core-conditional/target-windows/src/lib.rs b/wgpu-core-conditional/target-windows/src/lib.rs
new file mode 100644
index 0000000000..858db106f1
--- /dev/null
+++ b/wgpu-core-conditional/target-windows/src/lib.rs
@@ -0,0 +1,4 @@
+//! No code. See README.md for details.
+
+#[cfg(windows)]
+pub use wgpu_core::*;
diff --git a/wgpu-core/src/lib.rs b/wgpu-core/src/lib.rs
index 47aaa87a51..0d0957c7df 100644
--- a/wgpu-core/src/lib.rs
+++ b/wgpu-core/src/lib.rs
@@ -56,8 +56,8 @@
 // (the only reason to use wgpu-core on the web in the first place) that have atomics enabled.
 #![cfg_attr(not(send_sync), allow(clippy::arc_with_non_send_sync))]
 
-extern crate wgpu_hal as hal;
-extern crate wgpu_types as wgt;
+pub extern crate wgpu_hal as hal;
+pub extern crate wgpu_types as wgt;
 
 pub mod binding_model;
 pub mod command;
diff --git a/wgpu-types/Cargo.toml b/wgpu-types/Cargo.toml
index 653f988b7b..e10288c92e 100644
--- a/wgpu-types/Cargo.toml
+++ b/wgpu-types/Cargo.toml
@@ -40,12 +40,12 @@ default = ["std"]
 std = ["js-sys/std", "web-sys/std"]
 strict_asserts = []
 fragile-send-sync-non-atomic-wasm = []
-serde = ["dep:serde"]
+serde = ["dep:serde", "bitflags/serde"]
 # Enables some internal instrumentation for debugging purposes.
 counters = []
 
 [dependencies]
-bitflags = { workspace = true, features = ["serde"] }
+bitflags.workspace = true
 log.workspace = true
 serde = { workspace = true, default-features = false, features = [
     "alloc",
diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml
index 5f70401579..d9bd9198cf 100644
--- a/wgpu/Cargo.toml
+++ b/wgpu/Cargo.toml
@@ -28,33 +28,48 @@ ignored = ["cfg_aliases"]
 [lib]
 
 [features]
-default = ["wgsl", "dx12", "metal", "webgpu"]
+default = ["wgsl", "dx12", "metal", "vulkan", "gles", "webgpu"]
 
 #! ### Backends
 # --------------------------------------------------------------------
-#! ⚠️ WIP: Not all backends can be manually configured today.
-#! On Windows, Linux & Android the Vulkan & GLES backends are always enabled.
-#! See [#3514](https://github.com/gfx-rs/wgpu/issues/3514) for more details.
 
 ## Enables the DX12 backend on Windows.
-dx12 = ["wgpu-core?/dx12"]
+# Note that while wgpu-hal ignores dx12 for non-windows targets, we still need to use a proxy crate,
+# since for non-windows targets we don't want to include wgpu-core in the first place via this feature.
+dx12 = ["wgpu-core-if-target-windows/dx12"]
 
 ## Enables the Metal backend on macOS & iOS.
-metal = ["wgpu-core?/metal"]
+# Note that while wgpu-hal ignores metal for non-apple targets, we still need to use a proxy crate,
+# since for non-apple targets we don't want to include wgpu-core in the first place via this feature.
+metal = ["wgpu-core-if-target-apple/metal"]
 
-## Enables the WebGPU backend on Wasm. Disabled when targeting `emscripten`.
-webgpu = ["naga?/wgsl-out"]
-
-## Enables the GLES backend via [ANGLE](https://github.com/google/angle) on macOS using.
-angle = ["wgpu-core?/gles"]
+## Enables the Vulkan backend on Windows, Linux, and Android.
+##
+## For enabling Vulkan on macOS & iOS, use the `vulkan-portability` feature.
+vulkan = [
+    "wgpu-core-if-target-unix-non-apple/vulkan",
+    "wgpu-core-if-target-windows/vulkan",
+]
 
 ## Enables the Vulkan backend on macOS & iOS.
-vulkan-portability = ["wgpu-core?/vulkan"]
+vulkan-portability = ["wgpu-core-if-target-apple/vulkan"]
 
-## Enables the GLES backend on Wasm
+## Enables the OpenGL/GLES backend on Windows, Linux, and Android.
 ##
-## * ⚠️ WIP: Currently will also enable GLES dependencies on any other targets.
-webgl = ["dep:wgpu-hal", "wgpu-core/gles"]
+## For enabling WebGL use the `webgl` feature, for enabling OpenGL via ANGLE on macOS use the `angle` feature.
+gles = [
+    "wgpu-core-if-target-unix-non-apple/gles",
+    "wgpu-core-if-target-windows/gles",
+]
+
+## Enables the GLES backend via [ANGLE](https://github.com/google/angle) on macOS using.
+angle = ["wgpu-core-if-target-apple/gles"]
+
+## Enables GLES backend (WebGL) on Wasm
+webgl = ["wgpu-core-if-arch-wasm/gles"]
+
+## Enables the WebGPU backend on Wasm. Disabled when targeting `emscripten`.
+webgpu = ["naga?/wgsl-out"]
 
 #! **Note:** In the documentation, if you see that an item depends on a backend,
 #! it means that the item is only available when that backend is enabled _and_ the backend
@@ -84,7 +99,7 @@ naga-ir = ["dep:naga"]
 strict_asserts = ["wgpu-core?/strict_asserts", "wgpu-types/strict_asserts"]
 
 ## Enables serialization via `serde` on common wgpu types.
-serde = ["dep:serde", "wgpu-core/serde"]
+serde = ["dep:serde", "wgpu-core?/serde", "wgpu-types/serde"]
 
 # Uncomment once we get to https://github.com/gfx-rs/wgpu/issues/5974
 # ## Allow writing of trace capture files. See [`Adapter::request_device`].
@@ -92,7 +107,7 @@ serde = ["dep:serde", "wgpu-core/serde"]
 
 ## Allow deserializing of trace capture files that were written with the `trace` feature.
 ## To replay a trace file use the [wgpu player](https://github.com/gfx-rs/wgpu/tree/trunk/player).
-replay = ["serde", "wgpu-core/replay"]
+replay = ["serde", "wgpu-core?/replay"]
 
 #! ### Other
 # --------------------------------------------------------------------
@@ -100,7 +115,7 @@ replay = ["serde", "wgpu-core/replay"]
 ## Internally count resources and events for debugging purposes. If the counters
 ## feature is disabled, the counting infrastructure is removed from the build and
 ## the exposed counters always return 0.
-counters = ["wgpu-core/counters"]
+counters = ["wgpu-core?/counters"]
 
 ## Implement `Send` and `Sync` on Wasm, but only if atomics are not enabled.
 ##
@@ -111,8 +126,8 @@ counters = ["wgpu-core/counters"]
 ## but on a wasm binary compiled without atomics we know we are definitely
 ## not in a multithreaded environment.
 fragile-send-sync-non-atomic-wasm = [
-    "wgpu-hal/fragile-send-sync-non-atomic-wasm",
-    "wgpu-core/fragile-send-sync-non-atomic-wasm",
+    "wgpu-hal?/fragile-send-sync-non-atomic-wasm",
+    "wgpu-core?/fragile-send-sync-non-atomic-wasm",
     "wgpu-types/fragile-send-sync-non-atomic-wasm",
 ]
 
@@ -134,8 +149,11 @@ static-dxc = ["wgpu-hal/static-dxc"]
 
 [dependencies]
 naga = { workspace = true, optional = true }
-wgpu-core = { workspace = true, optional = true }
-wgpu-types = { workspace = true, features = ["serde"] }
+wgpu-core = { workspace = true, optional = true, features = [
+    "raw-window-handle",
+] }
+wgpu-types = { workspace = true }
+wgpu-hal = { workspace = true, optional = true, features = ["renderdoc"] }
 
 arrayvec.workspace = true
 bitflags.workspace = true
@@ -148,40 +166,17 @@ serde = { workspace = true, features = ["default", "derive"], optional = true }
 smallvec.workspace = true
 static_assertions.workspace = true
 
+wgpu-core-if-arch-wasm = { workspace = true, optional = true }
+wgpu-core-if-target-unix-non-apple = { workspace = true, optional = true }
+wgpu-core-if-target-apple = { workspace = true, optional = true }
+wgpu-core-if-target-windows = { workspace = true, optional = true }
+
+
 ########################################
 # Target Specific Feature Dependencies #
 ########################################
-
-# Windows
-[target.'cfg(windows)'.dependencies]
-wgpu-core = { workspace = true, features = [
-    "raw-window-handle",
-    "vulkan",
-    "gles",
-] }
-wgpu-hal = { workspace = true, features = ["renderdoc"] }
-
-# Apple Platforms
-[target.'cfg(target_vendor = "apple")'.dependencies]
-wgpu-core = { workspace = true, features = ["raw-window-handle"] }
-wgpu-hal = { workspace = true, features = [] }
-
-# Linux + Android
-[target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies]
-wgpu-core = { workspace = true, features = [
-    "raw-window-handle",
-    "vulkan",
-    "gles",
-] }
-wgpu-hal = { workspace = true, features = ["renderdoc"] }
-
 # Webassembly
 [target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies]
-wgpu-core = { workspace = true, optional = true, features = [
-    "raw-window-handle",
-] }
-wgpu-hal = { workspace = true, optional = true }
-
 js-sys = { workspace = true, features = ["default"] }
 parking_lot.workspace = true
 wasm-bindgen-futures.workspace = true
diff --git a/wgpu/build.rs b/wgpu/build.rs
index d853281dfa..5dcbe22674 100644
--- a/wgpu/build.rs
+++ b/wgpu/build.rs
@@ -1,16 +1,31 @@
 fn main() {
     cfg_aliases::cfg_aliases! {
         native: { not(target_arch = "wasm32") },
-        webgl: { all(target_arch = "wasm32", not(target_os = "emscripten"), feature = "webgl") },
-        webgpu: { all(target_arch = "wasm32", not(target_os = "emscripten"), feature = "webgpu") },
+
+        unix_non_apple: { all(native, not(target_vendor = "apple"), unix) },
         Emscripten: { all(target_arch = "wasm32", target_os = "emscripten") },
-        wgpu_core: { any(native, webgl, Emscripten) },
         send_sync: { any(
             not(target_arch = "wasm32"),
             all(feature = "fragile-send-sync-non-atomic-wasm", not(target_feature = "atomics"))
         ) },
+
+        webgl: { all(target_arch = "wasm32", not(target_os = "emscripten"), feature = "webgl") },
+        webgpu: { all(target_arch = "wasm32", not(target_os = "emscripten"), feature = "webgpu") },
         dx12: { all(target_os = "windows", feature = "dx12") },
         metal: { all(target_vendor = "apple", feature = "metal") },
+        vulkan: {
+            any(all(feature = "vulkan-portability", target_vendor = "apple"),
+                all(feature = "vulkan", unix_non_apple)
+            )},
+        gles: {
+            any(
+                all(feature = "angle", target_vendor = "apple"),
+                all(feature = "gles", unix_non_apple)
+            )
+        },
+
+        wgpu_core: { any(webgl, dx12, metal, vulkan, gles) },
+
         // This alias is _only_ if _we_ need naga in the wrapper. wgpu-core provides
         // its own re-export of naga, which can be used in other situations
         naga: { any(feature = "naga-ir", feature = "spirv", feature = "glsl") },
diff --git a/wgpu/src/api/instance.rs b/wgpu/src/api/instance.rs
index a8daf37fdc..3b54ec4658 100644
--- a/wgpu/src/api/instance.rs
+++ b/wgpu/src/api/instance.rs
@@ -60,45 +60,23 @@ impl Instance {
     ///
     /// `InstanceDescriptor::backends` does not need to be a subset of this,
     /// but any backend that is not in this set, will not be picked.
-    ///
-    /// TODO: Right now it's otherwise not possible yet to opt-out of all features on some platforms.
-    /// See <https://github.com/gfx-rs/wgpu/issues/3514>
-    /// * Windows/Linux/Android: always enables Vulkan and GLES with no way to opt out
     pub const fn enabled_backend_features() -> Backends {
         let mut backends = Backends::empty();
-
-        if cfg!(native) {
-            if cfg!(metal) {
-                backends = backends.union(Backends::METAL);
-            }
-            if cfg!(dx12) {
-                backends = backends.union(Backends::DX12);
-            }
-
-            // Windows, Android, Linux currently always enable Vulkan and OpenGL.
-            // See <https://github.com/gfx-rs/wgpu/issues/3514>
-            if cfg!(target_os = "windows") || cfg!(unix) {
-                backends = backends.union(Backends::VULKAN).union(Backends::GL);
-            }
-
-            // Vulkan on Mac/iOS is only available through vulkan-portability.
-            if cfg!(target_vendor = "apple") && cfg!(feature = "vulkan-portability") {
-                backends = backends.union(Backends::VULKAN);
-            }
-
-            // GL on Mac is only available through angle.
-            if cfg!(target_os = "macos") && cfg!(feature = "angle") {
-                backends = backends.union(Backends::GL);
-            }
-        } else {
-            if cfg!(webgpu) {
-                backends = backends.union(Backends::BROWSER_WEBGPU);
-            }
-            if cfg!(webgl) {
-                backends = backends.union(Backends::GL);
-            }
+        if cfg!(metal) {
+            backends = backends.union(Backends::METAL);
+        }
+        if cfg!(dx12) {
+            backends = backends.union(Backends::DX12);
+        }
+        if cfg!(vulkan) {
+            backends = backends.union(Backends::VULKAN);
+        }
+        if cfg!(gles) {
+            backends = backends.union(Backends::GL);
+        }
+        if cfg!(webgpu) {
+            backends = backends.union(Backends::BROWSER_WEBGPU);
         }
-
         backends
     }
 
@@ -221,7 +199,7 @@ impl Instance {
     /// # Arguments
     ///
     /// - `backends` - Backends from which to enumerate adapters.
-    #[cfg(native)]
+    #[cfg(all(native, wgpu_core))]
     pub fn enumerate_adapters(&self, backends: Backends) -> Vec<Adapter> {
         let Some(core_instance) = self.inner.as_core_opt() else {
             return Vec::new();
diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs
index 36438abfdc..42d6d158fa 100644
--- a/wgpu/src/backend/wgpu_core.rs
+++ b/wgpu/src/backend/wgpu_core.rs
@@ -61,7 +61,7 @@ impl ContextWgpuCore {
 
     pub unsafe fn create_adapter_from_hal<A: wgc::hal_api::HalApi>(
         &self,
-        hal_adapter: hal::ExposedAdapter<A>,
+        hal_adapter: crate::hal::ExposedAdapter<A>,
     ) -> wgc::id::AdapterId {
         unsafe { self.0.create_adapter_from_hal(hal_adapter.into(), None) }
     }
@@ -95,7 +95,7 @@ impl ContextWgpuCore {
     pub unsafe fn create_device_from_hal<A: wgc::hal_api::HalApi>(
         &self,
         adapter: &CoreAdapter,
-        hal_device: hal::OpenDevice<A>,
+        hal_device: crate::hal::OpenDevice<A>,
         desc: &crate::DeviceDescriptor<'_>,
         trace_dir: Option<&std::path::Path>,
     ) -> Result<(CoreDevice, CoreQueue), crate::RequestDeviceError> {
diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs
index 29cf6fe163..e78bfecaeb 100644
--- a/wgpu/src/lib.rs
+++ b/wgpu/src/lib.rs
@@ -25,10 +25,18 @@
 #![allow(clippy::arc_with_non_send_sync)]
 #![cfg_attr(not(any(wgpu_core, webgpu)), allow(unused))]
 
+#[cfg(all(wgpu_core, not(native)))]
+pub extern crate wgpu_core_if_arch_wasm as wgc;
+#[cfg(all(wgpu_core, target_vendor = "apple"))]
+pub extern crate wgpu_core_if_target_apple as wgc;
+#[cfg(all(wgpu_core, windows))]
+pub extern crate wgpu_core_if_target_windows as wgc;
+#[cfg(all(wgpu_core, unix_non_apple))]
+pub extern crate wgpu_core_if_unix_non_apple as wgc;
+
 #[cfg(wgpu_core)]
-pub extern crate wgpu_core as wgc;
-#[cfg(wgpu_core)]
-pub extern crate wgpu_hal as hal;
+pub use wgc::hal;
+
 pub extern crate wgpu_types as wgt;
 
 //
@@ -89,18 +97,18 @@ pub use wgt::ImageCopyExternalImage;
 #[cfg(any(webgpu, webgl))]
 pub use wgt::{CopyExternalImageSourceInfo, ExternalImageSource};
 
-/// Re-export of our `naga` dependency.
-///
-#[cfg(wgpu_core)]
-#[cfg_attr(docsrs, doc(cfg(any(wgpu_core, naga))))]
-// We re-export wgpu-core's re-export of naga, as we may not have direct access to it.
-pub use ::wgc::naga;
 /// Re-export of our `naga` dependency.
 ///
 #[cfg(all(not(wgpu_core), naga))]
 #[cfg_attr(docsrs, doc(cfg(any(wgpu_core, naga))))]
 // If that's not available, we re-export our own.
 pub use naga;
+/// Re-export of our `naga` dependency.
+///
+#[cfg(wgpu_core)]
+#[cfg_attr(docsrs, doc(cfg(any(wgpu_core, naga))))]
+// We re-export wgpu-core's re-export of naga, as we may not have direct access to it.
+pub use wgc::naga;
 
 /// Re-export of our `raw-window-handle` dependency.
 ///
diff --git a/wgpu/src/util/init.rs b/wgpu/src/util/init.rs
index 54de26da65..d48047eb03 100644
--- a/wgpu/src/util/init.rs
+++ b/wgpu/src/util/init.rs
@@ -4,7 +4,7 @@ use crate::{Adapter, Instance, RequestAdapterOptions, Surface};
 use crate::Backends;
 
 /// Initialize the adapter obeying the WGPU_ADAPTER_NAME environment variable.
-#[cfg(native)]
+#[cfg(all(native, wgpu_core))]
 pub fn initialize_adapter_from_env(
     instance: &Instance,
     compatible_surface: Option<&Surface<'_>>,
@@ -36,7 +36,7 @@ pub fn initialize_adapter_from_env(
 }
 
 /// Initialize the adapter obeying the WGPU_ADAPTER_NAME environment variable.
-#[cfg(not(native))]
+#[cfg(not(all(native, wgpu_core)))]
 pub fn initialize_adapter_from_env(
     _instance: &Instance,
     _compatible_surface: Option<&Surface<'_>>,