diff --git a/cli/args/flags.rs b/cli/args/flags.rs
index 44bb0dde170505..7712a291e51643 100644
--- a/cli/args/flags.rs
+++ b/cli/args/flags.rs
@@ -756,12 +756,12 @@ impl Flags {
           .ok()
       }
       Task(_) | Check(_) | Coverage(_) | Cache(_) | Info(_) | Eval(_)
-      | Test(_) | Bench(_) | Repl(_) | Compile(_) => {
+      | Test(_) | Bench(_) | Repl(_) | Compile(_) | Publish(_) => {
         std::env::current_dir().ok()
       }
       Bundle(_) | Completions(_) | Doc(_) | Fmt(_) | Init(_) | Install(_)
       | Uninstall(_) | Jupyter(_) | Lsp | Lint(_) | Types | Upgrade(_)
-      | Vendor(_) | Publish(_) => None,
+      | Vendor(_) => None,
     }
   }
 
diff --git a/cli/tools/registry/mod.rs b/cli/tools/registry/mod.rs
index aea5dc6340a1a9..ab02bc8d5e5546 100644
--- a/cli/tools/registry/mod.rs
+++ b/cli/tools/registry/mod.rs
@@ -34,6 +34,7 @@ use crate::cache::ParsedSourceCache;
 use crate::factory::CliFactory;
 use crate::graph_util::ModuleGraphCreator;
 use crate::http_util::HttpClient;
+use crate::resolver::MappedSpecifierResolver;
 use crate::tools::check::CheckOptions;
 use crate::tools::lint::no_slow_types;
 use crate::tools::registry::diagnostics::PublishDiagnostic;
@@ -85,7 +86,7 @@ async fn prepare_publish(
   deno_json: &ConfigFile,
   source_cache: Arc<ParsedSourceCache>,
   graph: Arc<deno_graph::ModuleGraph>,
-  import_map: Arc<ImportMap>,
+  mapped_resolver: Arc<MappedSpecifierResolver>,
   diagnostics_collector: &PublishDiagnosticsCollector,
 ) -> Result<Rc<PreparedPublishPackage>, AnyError> {
   let config_path = deno_json.specifier.to_file_path().unwrap();
@@ -131,7 +132,7 @@ async fn prepare_publish(
 
   let diagnostics_collector = diagnostics_collector.clone();
   let tarball = deno_core::unsync::spawn_blocking(move || {
-    let unfurler = ImportMapUnfurler::new(&import_map);
+    let unfurler = ImportMapUnfurler::new(&mapped_resolver);
     tar::create_gzipped_tarball(
       &dir_path,
       LazyGraphSourceParser::new(&source_cache, &graph),
@@ -654,7 +655,7 @@ async fn prepare_packages_for_publishing(
   allow_slow_types: bool,
   diagnostics_collector: &PublishDiagnosticsCollector,
   deno_json: ConfigFile,
-  import_map: Arc<ImportMap>,
+  mapped_resolver: Arc<MappedSpecifierResolver>,
 ) -> Result<PreparePackagesData, AnyError> {
   let members = deno_json.to_workspace_members()?;
   let module_graph_creator = cli_factory.module_graph_creator().await?.as_ref();
@@ -684,7 +685,7 @@ async fn prepare_packages_for_publishing(
   let results = members
     .into_iter()
     .map(|member| {
-      let import_map = import_map.clone();
+      let mapped_resolver = mapped_resolver.clone();
       let graph = graph.clone();
       async move {
         let package = prepare_publish(
@@ -692,7 +693,7 @@ async fn prepare_packages_for_publishing(
           &member.config_file,
           source_cache.clone(),
           graph,
-          import_map,
+          mapped_resolver,
           diagnostics_collector,
         )
         .await
@@ -806,6 +807,11 @@ pub async fn publish(
       Arc::new(ImportMap::new(Url::parse("file:///dev/null").unwrap()))
     });
 
+  let mapped_resolver = Arc::new(MappedSpecifierResolver::new(
+    Some(import_map),
+    cli_factory.package_json_deps_provider().clone(),
+  ));
+
   let directory_path = cli_factory.cli_options().initial_cwd();
 
   let cli_options = cli_factory.cli_options();
@@ -823,7 +829,7 @@ pub async fn publish(
     publish_flags.allow_slow_types,
     &diagnostics_collector,
     config_file.clone(),
-    import_map,
+    mapped_resolver,
   )
   .await?;
 
diff --git a/cli/util/import_map.rs b/cli/util/import_map.rs
index 50a74b2852f247..9adc41af07e5c0 100644
--- a/cli/util/import_map.rs
+++ b/cli/util/import_map.rs
@@ -14,7 +14,8 @@ use deno_graph::TypeScriptReference;
 use deno_semver::jsr::JsrDepPackageReq;
 use deno_semver::jsr::JsrPackageReqReference;
 use deno_semver::npm::NpmPackageReqReference;
-use import_map::ImportMap;
+
+use crate::resolver::MappedSpecifierResolver;
 
 pub fn import_map_deps(value: &serde_json::Value) -> HashSet<JsrDepPackageReq> {
   let Some(obj) = value.as_object() else {
@@ -95,11 +96,11 @@ impl ImportMapUnfurlDiagnostic {
 }
 
 pub struct ImportMapUnfurler<'a> {
-  import_map: &'a ImportMap,
+  import_map: &'a MappedSpecifierResolver,
 }
 
 impl<'a> ImportMapUnfurler<'a> {
-  pub fn new(import_map: &'a ImportMap) -> Self {
+  pub fn new(import_map: &'a MappedSpecifierResolver) -> Self {
     Self { import_map }
   }
 
@@ -117,10 +118,12 @@ impl<'a> ImportMapUnfurler<'a> {
        text_changes: &mut Vec<deno_ast::TextChange>| {
         let resolved = self.import_map.resolve(specifier, url);
         if let Ok(resolved) = resolved {
-          text_changes.push(deno_ast::TextChange {
-            range: to_range(parsed_source, range),
-            new_text: make_relative_to(url, &resolved),
-          });
+          if let Some(resolved) = resolved.into_specifier() {
+            text_changes.push(deno_ast::TextChange {
+              range: to_range(parsed_source, range),
+              new_text: make_relative_to(url, &resolved),
+            });
+          }
         }
       };
     for dep in &module_info.dependencies {
@@ -206,7 +209,7 @@ fn make_relative_to(from: &ModuleSpecifier, to: &ModuleSpecifier) -> String {
 /// Attempts to unfurl the dynamic dependency returning `true` on success
 /// or `false` when the import was not analyzable.
 fn try_unfurl_dynamic_dep(
-  import_map: &ImportMap,
+  mapped_resolver: &MappedSpecifierResolver,
   module_url: &lsp_types::Url,
   parsed_source: &ParsedSource,
   dep: &deno_graph::DynamicDependencyDescriptor,
@@ -220,10 +223,13 @@ fn try_unfurl_dynamic_dep(
       let Some(relative_index) = maybe_relative_index else {
         return false;
       };
-      let resolved = import_map.resolve(value, module_url);
+      let resolved = mapped_resolver.resolve(value, module_url);
       let Ok(resolved) = resolved else {
         return false;
       };
+      let Some(resolved) = resolved.into_specifier() else {
+        return false;
+      };
       let start = range.start + relative_index;
       text_changes.push(deno_ast::TextChange {
         range: start..start + value.len(),
@@ -241,7 +247,10 @@ fn try_unfurl_dynamic_dep(
         if !value.ends_with('/') {
           return false;
         }
-        let Ok(resolved) = import_map.resolve(value, module_url) else {
+        let Ok(resolved) = mapped_resolver.resolve(value, module_url) else {
+          return false;
+        };
+        let Some(resolved) = resolved.into_specifier() else {
           return false;
         };
         let range = to_range(parsed_source, &dep.argument_range);
@@ -289,6 +298,10 @@ fn to_range(
 
 #[cfg(test)]
 mod tests {
+  use std::sync::Arc;
+
+  use crate::args::PackageJsonDepsProvider;
+
   use super::*;
   use deno_ast::MediaType;
   use deno_ast::ModuleSpecifier;
@@ -323,7 +336,11 @@ mod tests {
     });
     let ImportMapWithDiagnostics { import_map, .. } =
       import_map::parse_from_value(&deno_json_url, value).unwrap();
-    let unfurler = ImportMapUnfurler::new(&import_map);
+    let mapped_resolved = MappedSpecifierResolver::new(
+      Some(Arc::new(import_map)),
+      Arc::new(PackageJsonDepsProvider::new(None)),
+    );
+    let unfurler = ImportMapUnfurler::new(&mapped_resolved);
 
     // Unfurling TS file should apply changes.
     {
diff --git a/test_util/std b/test_util/std
new file mode 160000
index 00000000000000..e0ef24091e87f8
--- /dev/null
+++ b/test_util/std
@@ -0,0 +1 @@
+Subproject commit e0ef24091e87f84d44d495d432d611625b281249
diff --git a/test_util/wpt b/test_util/wpt
new file mode 160000
index 00000000000000..00f2d3447e634b
--- /dev/null
+++ b/test_util/wpt
@@ -0,0 +1 @@
+Subproject commit 00f2d3447e634be6beb0261e59e2a3264fa383d6
diff --git a/tests/integration/publish_tests.rs b/tests/integration/publish_tests.rs
index 71bc838a85d413..e8eda5010a1d43 100644
--- a/tests/integration/publish_tests.rs
+++ b/tests/integration/publish_tests.rs
@@ -3,6 +3,7 @@
 use deno_core::serde_json::json;
 use test_util::assert_contains;
 use test_util::assert_not_contains;
+use test_util::env_vars_for_jsr_npm_tests;
 use test_util::env_vars_for_jsr_tests;
 use test_util::env_vars_for_npm_tests;
 use test_util::itest;
@@ -147,6 +148,14 @@ itest!(javascript_decl_file {
   exit_code: 0,
 });
 
+itest!(package_json {
+  args: "publish --token 'sadfasdf'",
+  output: "publish/package_json.out",
+  cwd: Some("publish/package_json"),
+  envs: env_vars_for_jsr_npm_tests(),
+  http_server: true,
+});
+
 itest!(successful {
   args: "publish --token 'sadfasdf'",
   output: "publish/successful.out",
diff --git a/tests/testdata/publish/package_json.out b/tests/testdata/publish/package_json.out
new file mode 100644
index 00000000000000..7b54ce8dac289c
--- /dev/null
+++ b/tests/testdata/publish/package_json.out
@@ -0,0 +1,8 @@
+Download http://localhost:4545/npm/registry/picocolors
+Download http://localhost:4545/npm/registry/picocolors/picocolors-1.0.0.tgz
+Check file:///[WILDCARD]/publish/package_json/mod.ts
+Checking for slow types in the public API...
+Check file:///[WILDCARD]/publish/package_json/mod.ts
+Publishing @foo/bar@1.0.0 ...
+Successfully published @foo/bar@1.0.0
+Visit http://127.0.0.1:4250/@foo/bar@1.0.0 for details
diff --git a/tests/testdata/publish/package_json/deno.json b/tests/testdata/publish/package_json/deno.json
new file mode 100644
index 00000000000000..6e2826ef5eb3da
--- /dev/null
+++ b/tests/testdata/publish/package_json/deno.json
@@ -0,0 +1,8 @@
+{
+  "name": "@foo/bar",
+  "version": "1.0.0",
+  "exports": {
+    ".": "./mod.ts"
+  },
+  "nodeModulesDir": false
+}
diff --git a/tests/testdata/publish/package_json/mod.ts b/tests/testdata/publish/package_json/mod.ts
new file mode 100644
index 00000000000000..ae98962fa28416
--- /dev/null
+++ b/tests/testdata/publish/package_json/mod.ts
@@ -0,0 +1,9 @@
+import pc from "picocolors";
+
+export function add(a: number, b: number): number {
+  return a + b;
+}
+
+export function getValue(): string {
+  return pc.green("hey");
+}
diff --git a/tests/testdata/publish/package_json/package.json b/tests/testdata/publish/package_json/package.json
new file mode 100644
index 00000000000000..c1b171f4c9ccbb
--- /dev/null
+++ b/tests/testdata/publish/package_json/package.json
@@ -0,0 +1,7 @@
+{
+  "name": "@deno/foo",
+  "version": "0.0.1",
+  "dependencies": {
+    "picocolors": "*"
+  }
+}
diff --git a/tests/util/server/src/lib.rs b/tests/util/server/src/lib.rs
index ead05641ddbbbf..9a0323433cc690 100644
--- a/tests/util/server/src/lib.rs
+++ b/tests/util/server/src/lib.rs
@@ -64,6 +64,14 @@ pub fn env_vars_for_jsr_tests() -> Vec<(String, String)> {
   ]
 }
 
+pub fn env_vars_for_jsr_npm_tests() -> Vec<(String, String)> {
+  vec![
+    ("NPM_CONFIG_REGISTRY".to_string(), npm_registry_url()),
+    ("JSR_URL".to_string(), jsr_registry_url()),
+    ("NO_COLOR".to_string(), "1".to_string()),
+  ]
+}
+
 pub fn root_path() -> PathRef {
   PathRef::new(
     PathBuf::from(concat!(env!("CARGO_MANIFEST_DIR")))