denoland/deno · error

Missing 'exports' field in '{}'. Add an exports field like:

Error message

Missing 'exports' field in '{}'. Add an exports field like:
  {
    "exports": "./mod.ts",
    ...
  }

What it means

`deno pack` requires an `exports` field in the standalone deno.json because JSR packages must declare their entrypoint(s). Without `exports` there is no public API surface to pack. The message suggests the minimal `"./mod.ts"` shape.

Source

Thrown at cli/tools/pack/mod.rs:78

  // Get package configs
  let mut packages = cli_options.start_dir.jsr_packages_for_publish();
  if packages.is_empty() {
    match cli_options.start_dir.member_deno_json() {
      Some(deno_json) => {
        let Some(name) = deno_json.json.name.clone() else {
          bail!(
            "Missing 'name' field in '{}'. Add a package name like:\n  {{\n    \"name\": \"@scope/package-name\",\n    ...\n  }}",
            deno_json.specifier
          );
        };
        if deno_json.json.version.is_none() {
          bail!(
            "Missing 'version' field in '{}'. Add a version like:\n  {{\n    \"version\": \"1.0.0\",\n    ...\n  }}",
            deno_json.specifier
          );
        }
        if deno_json.json.exports.is_none() {
          bail!(
            "Missing 'exports' field in '{}'. Add an exports field like:\n  {{\n    \"exports\": \"./mod.ts\",\n    ...\n  }}",
            deno_json.specifier
          );
        }

        packages.push(JsrPackageConfig {
          name,
          member_dir: cli_options.start_dir.workspace.root_dir().clone(),
          config_file: deno_json.clone(),
          license: deno_json
            .json
            .license
            .as_ref()
            .and_then(|l| l.as_str().map(|s| s.to_string())),
          should_publish: true,
        });
      }
      None => {

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Add `"exports": "./mod.ts"` (or an exports map object) pointing at the real entrypoint.
  2. For multi-entry packages use an exports map: `{"exports": {".": "./mod.ts", "./sub": "./sub.ts"}}`.
  3. If you did not intend to publish this directory, run `deno pack` from the actual package directory instead.

Example fix

// deno.json (before)
{
  "name": "@scope/pkg",
  "version": "1.0.0"
}
// deno.json (after)
{
  "name": "@scope/pkg",
  "version": "1.0.0",
  "exports": "./mod.ts"
}
Defensive patterns

Strategy: validation

Validate before calling

const cfg = JSON.parse(readFileSync("deno.json", "utf8"));
if (cfg.exports == null) {
  console.error("deno.json is missing required field: exports");
  process.exit(1);
}

Type guard

const hasExports = (cfg: unknown): boolean =>
  typeof cfg === "object" && cfg !== null && "exports" in cfg;

Prevention

When it happens

Trigger: Running `deno pack` in a directory whose deno.json has `name` and `version` but no `exports` field.

Common situations: Library scaffolding where mod.ts exists but exports were never wired up; private scripts mistaken for publishable packages.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/5ad2e53579152e52. Report an issue: GitHub.