Skip to content

Support for custom conditional exports in npm specifier #23757

@nestarz

Description

@nestarz
Contributor

What is the problem this feature would solve?

Deno currently does not provide a way to specify custom export conditions when importing npm packages. This makes it impossible to import non-default exports that are conditionally exported based on certain conditions, such as the "react-server" condition used by React Server Components.

See:
https://nodejs.org/api/packages.html#conditional-exports
https://github.com/reactjs/rfcs/blob/main/text/0227-server-module-conventions.md

What is the feature you are proposing to solve the problem?

Add support for a config flag in Deno, similar to the one supported by Node.js and Bun. This flag would allow specifying custom export conditions when importing npm packages.

For example, in Bun, thanks to this issue oven-sh/bun#8990 you can do:

bun --conditions special-condition

Then, if you import an npm package, it will follow the conditions specified in the package's exports field.

Ideally, it would be great to set up this condition inside the deno.json config, so that it can be used by Deno Deploy as well. An other option would be to specify it directly in the npm specifier, so that no config file are needed ?

What alternatives have you considered?

One workaround would be to directly import the specific file path, like:

import "npm:/react@19.0.0-beta-b498834eab-20240506/cjs/react.react-server.development.js"

However, this doesn't work if the file is not explicitly exported in the package's exports field:

Uncaught TypeError: Failed resolving package subpath './cjs/react.react-server.development.js' for '/Users/Library/Caches/deno/npm/registry.npmjs.org/react/19.0.0-beta-b498834eab-20240506/package.json'
  Caused by:
    [ERR_PACKAGE_PATH_NOT_EXPORTED] Package subpath './cjs/react.react-server.development.js' is not defined by "exports" in '/Users/Library/Caches/deno/npm/registry.npmjs.org/react/19.0.0-beta-b498834eab-20240506/package.json' imported from '/Users/code/$deno$repl.ts'

I think this is intentional from the Deno team to not expose what's not exposed through the exports option. But then, Deno should provide a way to define the export conditions like Bun and Node does.

Activity

terrablue

terrablue commented on Aug 10, 2024

@terrablue

I would welcome such a change. It would be particularly useful during compilation using deno compile, in order to tap into a runtime condition which only imports packages/package paths needed during runtime. A prominent example is Svelte: excluding svelte/compiler during runtime is only possible with export conditions, and that's how we're currently doing it with Bun.

kigawas

kigawas commented on Oct 14, 2024

@kigawas

I've observed the following behavior

When there is a package A with exports deno condition, if we import A directly with deno, deno export works. If we import package B using package A, deno export will not work

#17964 (reply in thread)

davesteinberg

davesteinberg commented on Oct 15, 2024

@davesteinberg

I seem to have hit a dead-end trying to use Deno, Drizzle, and libsql together. The issue is that libsql uses a conditional export to determine whether to export its node or web client by default, and for "deno", you get the less capable web client, even though Deno can run the node client just fine. I've described the problem in more detail here. I don't know if Drizzle might provide a solution, but it seems to me that being able to customize the export condition would solve it from the Deno side.

davesteinberg

davesteinberg commented on Oct 15, 2024

@davesteinberg

After looking at conditional exports some more, I suppose allowing additional conditions to be specified wouldn't actually solve my problem, since there is no higher priority condition in libsql's export than "deno" that could be used to export the node client.

I would need to be able to remove the default "deno" condition, or some change would be required on the libsql side, as well, such as adding a higher priority "node-override" condition.

terrablue

terrablue commented on Oct 15, 2024

@terrablue

@davesteinberg The semantics of custom conditional exports somewhat compete with the semantics of specific runtime keys. In custom exports, the idea is to buy into a certain feature (say, in a compile vs run situation), whilst runtime keys indicate what is supported for the given runtime. The way I read it, libsql would need to signal it fully supports Node by Deno by switching from web to node for Deno. Given that Deno's NPM compat is only somewhat recent, it isn't surprising their default is web, but it might merit a refresh with Deno 2.

davesteinberg

davesteinberg commented on Oct 15, 2024

@davesteinberg

@terrablue Agreed, there seems to be a bit of competition between feature vs. runtime conditions. And here there's kind of a mix between what the runtime supports and what is desirable in a given situation (simpler client, fewer permissions required vs. file: DB URL support).

I opened a libsql issue to ask whether they would consider changing the default export for Deno.

If they don't want to change the default, I also proposed a simpler set of conditions that I think would give the same default client on all runtimes but also allow you to choose the other one. Of course, that would only help if/when Deno supports custom conditional exports.

mintydev789

mintydev789 commented on May 15, 2025

@mintydev789

What is the current status of this issue? This missing feature is currently the only reason I still have to have Node/NPM installed to be able to work with my project that relies on Drizzle :(

bartlomieju

bartlomieju commented on Jun 4, 2025

@bartlomieju
Member

This will be shipped in Deno v2.3.6 later this week and available as the --unstable-node-conditions flag. I would appreciate trying out once it lands and letting us know if there are any troubles. We'll try to stabilize it for Deno v2.4.

22 remaining items

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    node compatsuggestionsuggestions for new features (yet to be agreed)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @dsherret@davesteinberg@kigawas@nestarz@bartlomieju

      Issue actions

        Support for custom conditional exports in npm specifier · Issue #23757 · denoland/deno