Skip to content

fix: treat @jsr/ scoped npm dependencies as JSR dependencies#1256

Open
amyssnippet wants to merge 5 commits intojsr-io:mainfrom
amyssnippet:fix/1252
Open

fix: treat @jsr/ scoped npm dependencies as JSR dependencies#1256
amyssnippet wants to merge 5 commits intojsr-io:mainfrom
amyssnippet:fix/1252

Conversation

@amyssnippet
Copy link

@amyssnippet amyssnippet commented Jan 20, 2026

Problem

JSR packages that depend on other JSR packages via npm specifiers fail to resolve when imported from JSR. For example, importing https://jsr.io/@sigmasd/gtk@0.11.0 fails with "npm package '@jsr/sigma__deno-compat' does not exist" because the package depends on npm:@jsr/sigma__deno-compat.

Root Cause

During package publishing, import statements like import "npm:@jsr/sigma__deno-compat" are analyzed and classified as npm dependencies. When users import the JSR package, Deno attempts to resolve these npm dependencies from the default npm registry (npmjs.org), but @jsr/ scoped packages are only available on JSR's npm registry. Without proper npmrc configuration pointing to JSR's registry, the import fails.

Solution

Modified the dependency collection logic to detect npm dependencies with names starting with @jsr/ and treat them as JSR dependencies instead. This ensures they are resolved from JSR's registry rather than external npm registries.

Changes

  • api/src/analysis.rs:
    • Added convert_npm_jsr_to_jsr_ref() function to convert @jsr/scope__package npm specifiers to @scope/package JSR specifiers
    • Updated collect_dependencies() to check for @jsr/ prefixes and convert them to JSR dependencies
  • api/src/publish.rs: Added test case npm_jsr_import to verify the conversion works correctly
  • api/testdata/tarballs/npm_jsr_import/: New test data directory with sample package that imports @jsr/ scoped npm dependency

Testing

  • Added integration test npm_jsr_import that verifies @jsr/ scoped npm dependencies are treated as JSR dependencies
  • The test ensures uses_npm flag is false for packages with converted dependencies
  • Code compiles successfully and logic handles edge cases properly

Closes #1252

PR Checklist

  • The PR title follows conventional commits
  • Is this closing an open issue? If so, link it, else include a proper description of the changes and reason behind them.
  • Does the PR have changes to the frontend? If so, include screenshots or a recording of the changes.

    If it affect colors, please include screenshots/recording in both light and dark mode.
  • Does the PR have changes to the backend? If so, make sure tests are added.

    And if changing database queries, be sure you have ran sqlx prepare and committed the changes in the .sqlx directory. (No database query changes made)

When a JSR package imports an npm package with a name starting with @jsr/,
such as npm:@jsr/sigma__deno-compat, treat it as a JSR dependency instead
of an npm dependency. This ensures the dependency is resolved from JSR's
registry rather than failing on external npm registries.

Added conversion logic in collect_dependencies to detect and convert
@jsr/scope__package npm specifiers to @scope/package JSR specifiers.

Added test case npm_jsr_import to verify the behavior.
- Publish dependency package first in test to ensure JSR dep exists
- Change test package name to @scope/bar to avoid self-dependency
- Update import to match published dependency version (@1.2.3)
@amyssnippet
Copy link
Author

This error was rising due to dependency issues and thats why i am update npm_jsr_import test to resolve JSR dependencies correctly

test util::test::harness_expectations ... ok
test publish::tests::payload_too_large_stream ... ok
failures:
---- publish::tests::npm_jsr_import stdout ----
Database ready
starting fake gcs server: /home/runner/work/jsr/jsr/api/../tools/bin/linux-amd64/fake-gcs-server
thread 'publish::tests::npm_jsr_import' panicked at api/src/publish.rs:1178:5:
assertion `left == right` failed: PublishingTask {
    id: d9c96535-9168-474e-b640-2f6451b242ad,
    status: Failure,
    error: Some(
        PublishingTaskError {
            code: "unresolvableJsrDependency",
            message: "unresolvable 'jsr:' dependency: '@scope/foo@1.0.0', no published version matches the constraint",
        },
    ),
    package_scope: scope,
    package_name: foo,
    package_version: Version { major: 1, minor: 2, patch: 3, pre: [], build: [] },
    config_file: "/jsr.json",
    user_id: Some(
        3fb4ffa1-1bc0-4e66-bf45-2680263e89c3,
    ),
    created_at: 2026-01-20T10:45:12.024380Z,
    updated_at: 2026-01-20T10:45:12.057682Z,
}
  left: Failure
 right: Success
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
    publish::tests::npm_jsr_import
test result: FAILED. 160 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 67.10s
error: test failed, to rerun pass `--bin registry_api`
Error: Process completed with exit code 101.

@amyssnippet
Copy link
Author

idk why, but this is failing, if any maintainer is looking at this pr, guide me regarding further process, i am a new contributor to jsr

@sigmaSd
Copy link

sigmaSd commented Jan 21, 2026

Thanks again for your work, one question: does this special treatment only happen when deno is involved ? because fetching from jsr on other runtimes wont work, for deno it should be a special case but for the others it should work as is as in the user need to setup npmrc (which is ok)

Use process_tarball_setup2 with package name bar instead of hardcoded foo
This prevents conflicts with the dependency package (@scope/foo@1.2.3)
Test Data: The npm_jsr_import package is correctly configured as @scope/bar@1.2.3
@CLAassistant
Copy link

CLAassistant commented Jan 21, 2026

CLA assistant check
All committers have signed the CLA.

@amyssnippet
Copy link
Author

image

Lastly i got an linting issue in an if else block, i will soon format it properly and will ready a new commit

…ings related to our changes. The collapsible else-if block has been properly collapsed
- Format function signatures and long lines according to rustfmt
- Collapse collapsible else-if blocks to satisfy clippy warnings
@amyssnippet
Copy link
Author

@sigmaSd That is a great question. from my understanding of the codebase, this change happens during the analysis/publish phase in the api, it effectively normalizes the imports, so, this shouldn't break other runtimes. In fact, it leverages JSR's existing compatibility layer to ensure both Deno and npm-based runtimes get the format they handle best. does that align with your understanding of the npm generation logic?

@sigmaSd
Copy link

sigmaSd commented Jan 22, 2026

I can't help with that because I have no idea about this codebase, hopefully a maintainer will take a look

@amyssnippet
Copy link
Author

Understood. Thanks for taking a look and for the initial feedback! I'll wait for a maintainer to review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

npm jsr deps can"t be used from jsr ?

3 participants