diff --git a/Examples/Embedded/Package.swift b/Examples/Embedded/Package.swift
index 5ae19adc..aae08002 100644
--- a/Examples/Embedded/Package.swift
+++ b/Examples/Embedded/Package.swift
@@ -1,11 +1,11 @@
-// swift-tools-version:6.0
+// swift-tools-version:6.1
 
 import PackageDescription
 
 let package = Package(
     name: "Embedded",
     dependencies: [
-        .package(name: "JavaScriptKit", path: "../../"),
+        .package(name: "JavaScriptKit", path: "../../", traits: ["Embedded"]),
         .package(url: "https://github.com/swiftwasm/swift-dlmalloc", branch: "0.1.0"),
     ],
     targets: [
diff --git a/Examples/Embedded/build.sh b/Examples/Embedded/build.sh
index f807cdbf..81840e76 100755
--- a/Examples/Embedded/build.sh
+++ b/Examples/Embedded/build.sh
@@ -1,5 +1,4 @@
 #!/bin/bash
 package_dir="$(cd "$(dirname "$0")" && pwd)"
-JAVASCRIPTKIT_EXPERIMENTAL_EMBEDDED_WASM=true \
-  swift package --package-path "$package_dir" \
+swift package --package-path "$package_dir" \
   -c release --triple wasm32-unknown-none-wasm js
diff --git a/Package.swift b/Package.swift
index 85a9a616..5a3a1ca5 100644
--- a/Package.swift
+++ b/Package.swift
@@ -1,9 +1,8 @@
-// swift-tools-version:6.0
+// swift-tools-version:6.1
 
 import PackageDescription
 
 // NOTE: needed for embedded customizations, ideally this will not be necessary at all in the future, or can be replaced with traits
-let shouldBuildForEmbedded = Context.environment["JAVASCRIPTKIT_EXPERIMENTAL_EMBEDDED_WASM"].flatMap(Bool.init) ?? false
 let useLegacyResourceBundling =
     Context.environment["JAVASCRIPTKIT_USE_LEGACY_RESOURCE_BUNDLING"].flatMap(Bool.init) ?? false
 
@@ -16,22 +15,23 @@ let package = Package(
         .library(name: "JavaScriptEventLoopTestSupport", targets: ["JavaScriptEventLoopTestSupport"]),
         .plugin(name: "PackageToJS", targets: ["PackageToJS"]),
     ],
+    traits: [
+        "Embedded"
+    ],
     targets: [
         .target(
             name: "JavaScriptKit",
             dependencies: ["_CJavaScriptKit"],
             exclude: useLegacyResourceBundling ? [] : ["Runtime"],
             resources: useLegacyResourceBundling ? [.copy("Runtime")] : [],
-            cSettings: shouldBuildForEmbedded
-                ? [
-                    .unsafeFlags(["-fdeclspec"])
-                ] : nil,
-            swiftSettings: shouldBuildForEmbedded
-                ? [
-                    .enableExperimentalFeature("Embedded"),
-                    .enableExperimentalFeature("Extern"),
-                    .unsafeFlags(["-Xfrontend", "-emit-empty-object-file"]),
-                ] : nil
+            cSettings: [
+                .unsafeFlags(["-fdeclspec"], .when(traits: ["Embedded"]))
+            ],
+            swiftSettings: [
+                .enableExperimentalFeature("Embedded", .when(traits: ["Embedded"])),
+                .enableExperimentalFeature("Extern", .when(traits: ["Embedded"])),
+                .unsafeFlags(["-Xfrontend", "-emit-empty-object-file"], .when(traits: ["Embedded"])),
+            ]
         ),
         .target(name: "_CJavaScriptKit"),
         .testTarget(
diff --git a/Package@swift-6.0.swift b/Package@swift-6.0.swift
new file mode 100644
index 00000000..85a9a616
--- /dev/null
+++ b/Package@swift-6.0.swift
@@ -0,0 +1,94 @@
+// swift-tools-version:6.0
+
+import PackageDescription
+
+// NOTE: needed for embedded customizations, ideally this will not be necessary at all in the future, or can be replaced with traits
+let shouldBuildForEmbedded = Context.environment["JAVASCRIPTKIT_EXPERIMENTAL_EMBEDDED_WASM"].flatMap(Bool.init) ?? false
+let useLegacyResourceBundling =
+    Context.environment["JAVASCRIPTKIT_USE_LEGACY_RESOURCE_BUNDLING"].flatMap(Bool.init) ?? false
+
+let package = Package(
+    name: "JavaScriptKit",
+    products: [
+        .library(name: "JavaScriptKit", targets: ["JavaScriptKit"]),
+        .library(name: "JavaScriptEventLoop", targets: ["JavaScriptEventLoop"]),
+        .library(name: "JavaScriptBigIntSupport", targets: ["JavaScriptBigIntSupport"]),
+        .library(name: "JavaScriptEventLoopTestSupport", targets: ["JavaScriptEventLoopTestSupport"]),
+        .plugin(name: "PackageToJS", targets: ["PackageToJS"]),
+    ],
+    targets: [
+        .target(
+            name: "JavaScriptKit",
+            dependencies: ["_CJavaScriptKit"],
+            exclude: useLegacyResourceBundling ? [] : ["Runtime"],
+            resources: useLegacyResourceBundling ? [.copy("Runtime")] : [],
+            cSettings: shouldBuildForEmbedded
+                ? [
+                    .unsafeFlags(["-fdeclspec"])
+                ] : nil,
+            swiftSettings: shouldBuildForEmbedded
+                ? [
+                    .enableExperimentalFeature("Embedded"),
+                    .enableExperimentalFeature("Extern"),
+                    .unsafeFlags(["-Xfrontend", "-emit-empty-object-file"]),
+                ] : nil
+        ),
+        .target(name: "_CJavaScriptKit"),
+        .testTarget(
+            name: "JavaScriptKitTests",
+            dependencies: ["JavaScriptKit"],
+            swiftSettings: [
+                .enableExperimentalFeature("Extern")
+            ]
+        ),
+
+        .target(
+            name: "JavaScriptBigIntSupport",
+            dependencies: ["_CJavaScriptBigIntSupport", "JavaScriptKit"]
+        ),
+        .target(name: "_CJavaScriptBigIntSupport", dependencies: ["_CJavaScriptKit"]),
+        .testTarget(
+            name: "JavaScriptBigIntSupportTests",
+            dependencies: ["JavaScriptBigIntSupport", "JavaScriptKit"]
+        ),
+
+        .target(
+            name: "JavaScriptEventLoop",
+            dependencies: ["JavaScriptKit", "_CJavaScriptEventLoop"]
+        ),
+        .target(name: "_CJavaScriptEventLoop"),
+        .testTarget(
+            name: "JavaScriptEventLoopTests",
+            dependencies: [
+                "JavaScriptEventLoop",
+                "JavaScriptKit",
+                "JavaScriptEventLoopTestSupport",
+            ],
+            swiftSettings: [
+                .enableExperimentalFeature("Extern")
+            ]
+        ),
+        .target(
+            name: "JavaScriptEventLoopTestSupport",
+            dependencies: [
+                "_CJavaScriptEventLoopTestSupport",
+                "JavaScriptEventLoop",
+            ]
+        ),
+        .target(name: "_CJavaScriptEventLoopTestSupport"),
+        .testTarget(
+            name: "JavaScriptEventLoopTestSupportTests",
+            dependencies: [
+                "JavaScriptKit",
+                "JavaScriptEventLoopTestSupport",
+            ]
+        ),
+        .plugin(
+            name: "PackageToJS",
+            capability: .command(
+                intent: .custom(verb: "js", description: "Convert a Swift package to a JavaScript package")
+            ),
+            sources: ["Sources"]
+        ),
+    ]
+)
diff --git a/Plugins/PackageToJS/Sources/PackageToJSPlugin.swift b/Plugins/PackageToJS/Sources/PackageToJSPlugin.swift
index 9d0b2c19..559022c2 100644
--- a/Plugins/PackageToJS/Sources/PackageToJSPlugin.swift
+++ b/Plugins/PackageToJS/Sources/PackageToJSPlugin.swift
@@ -161,9 +161,11 @@ struct PackageToJSPlugin: CommandPlugin {
         }
 
         // Build products
+        let selfPackage = try findSelfPackage(in: context.package)
         let productName = try buildOptions.product ?? deriveDefaultProduct(package: context.package)
         let build = try buildWasm(
             productName: productName,
+            selfPackage: selfPackage,
             context: context,
             options: buildOptions.packageOptions
         )
@@ -178,14 +180,6 @@ struct PackageToJSPlugin: CommandPlugin {
             } else {
                 context.pluginWorkDirectoryURL.appending(path: "Package")
             }
-        guard
-            let selfPackage = findPackageInDependencies(
-                package: context.package,
-                id: Self.JAVASCRIPTKIT_PACKAGE_ID
-            )
-        else {
-            throw PackageToJSError("Failed to find JavaScriptKit in dependencies!?")
-        }
         var make = MiniMake(
             explain: buildOptions.packageOptions.explain,
             printProgress: self.printProgress
@@ -226,9 +220,11 @@ struct PackageToJSPlugin: CommandPlugin {
             exit(1)
         }
 
+        let selfPackage = try findSelfPackage(in: context.package)
         let productName = "\(context.package.displayName)PackageTests"
         let build = try buildWasm(
             productName: productName,
+            selfPackage: selfPackage,
             context: context,
             options: testOptions.packageOptions
         )
@@ -264,14 +260,6 @@ struct PackageToJSPlugin: CommandPlugin {
             } else {
                 context.pluginWorkDirectoryURL.appending(path: "PackageTests")
             }
-        guard
-            let selfPackage = findPackageInDependencies(
-                package: context.package,
-                id: Self.JAVASCRIPTKIT_PACKAGE_ID
-            )
-        else {
-            throw PackageToJSError("Failed to find JavaScriptKit in dependencies!?")
-        }
         var make = MiniMake(
             explain: testOptions.packageOptions.explain,
             printProgress: self.printProgress
@@ -311,6 +299,7 @@ struct PackageToJSPlugin: CommandPlugin {
 
     private func buildWasm(
         productName: String,
+        selfPackage: Package,
         context: PluginContext,
         options: PackageToJS.PackageOptions
     ) throws
@@ -331,11 +320,7 @@ struct PackageToJSPlugin: CommandPlugin {
         )
         parameters.echoLogs = true
         parameters.otherSwiftcFlags = ["-color-diagnostics"]
-        let buildingForEmbedded =
-            ProcessInfo.processInfo.environment["JAVASCRIPTKIT_EXPERIMENTAL_EMBEDDED_WASM"].flatMap(
-                Bool.init
-            ) ?? false
-        if !buildingForEmbedded {
+        if !isBuildingForEmbedded(selfPackage: selfPackage) {
             // NOTE: We only support static linking for now, and the new SwiftDriver
             // does not infer `-static-stdlib` for WebAssembly targets intentionally
             // for future dynamic linking support.
@@ -355,6 +340,31 @@ struct PackageToJSPlugin: CommandPlugin {
         return try self.packageManager.build(.product(productName), parameters: parameters)
     }
 
+    /// Check if the build is for embedded WebAssembly
+    private func isBuildingForEmbedded(selfPackage: Package) -> Bool {
+        let coreTarget = selfPackage.targets.first { $0.name == "JavaScriptKit" }
+        guard let swiftTarget = coreTarget as? SwiftSourceModuleTarget else {
+            return false
+        }
+        // SwiftPM defines "Embedded" compilation condition when `Embedded` experimental
+        // feature is enabled.
+        // TODO: This should be replaced with a proper trait-based solution in the future.
+        return swiftTarget.compilationConditions.contains("Embedded")
+    }
+
+    /// Find JavaScriptKit package in the dependencies of the given package recursively
+    private func findSelfPackage(in package: Package) throws -> Package {
+        guard
+            let selfPackage = findPackageInDependencies(
+                package: package,
+                id: Self.JAVASCRIPTKIT_PACKAGE_ID
+            )
+        else {
+            throw PackageToJSError("Failed to find JavaScriptKit in dependencies!?")
+        }
+        return selfPackage
+    }
+
     /// Clean if the build graph of the packaging process has changed
     ///
     /// This is especially important to detect user changes debug/release