# How to Configure Deno Using deno.json: Complete Guide to Configuration File Options

> Configure Deno using deno.json! Learn to set compiler options, import maps, tasks, permissions, and runtime behavior. Avoid CLI flags with this comprehensive guide.

- Repository: [Deno/deno](https://github.com/denoland/deno)
- Tags: how-to-guide
- Published: 2026-02-26

---

**You can configure Deno by creating a [`deno.json`](https://github.com/denoland/deno/blob/main/deno.json) or `deno.jsonc` file in your project root, which Deno automatically discovers to set compiler options, import maps, tasks, permissions, and runtime behavior without requiring CLI flags for every command.**

Deno uses [`deno.json`](https://github.com/denoland/deno/blob/main/deno.json) (or `deno.jsonc` for JSON with comments) as its native configuration file to centralize project settings. When present in your working directory, Deno automatically detects and applies these settings across all commands including `deno run`, `deno test`, and `deno task`. This guide explains how to configure Deno using [`deno.json`](https://github.com/denoland/deno/blob/main/deno.json) based on the actual source code implementation in the `denoland/deno` repository.

## Automatic Config File Discovery

Deno implements automatic configuration discovery through the `ConfigFlag` enum defined in [`cli/args/flags.rs`](https://github.com/denoland/deno/blob/main/cli/args/flags.rs) at line 74. When you omit the `--config` flag, the CLI defaults to `ConfigFlag::Discover`, which triggers a directory tree walk. The discovery logic in [`cli/factory.rs`](https://github.com/denoland/deno/blob/main/cli/factory.rs) (lines 1354-1364) searches upward from the working directory for [`deno.json`](https://github.com/denoland/deno/blob/main/deno.json) or `deno.jsonc` files using `ConfigFile::maybe_find_in_folder` in [`libs/config/deno_json/mod.rs`](https://github.com/denoland/deno/blob/main/libs/config/deno_json/mod.rs) (lines 1325-1330).

You can control configuration loading through three distinct behaviors:

- **Automatic discovery**: `deno run script.ts` finds the nearest config file automatically via `ConfigFlag::Discover`.
- **Explicit path**: `deno run --config ./my-config.json script.ts` loads a specific file using `ConfigFlag::Path`.
- **Disabled**: `deno run --config=none script.ts` skips configuration entirely using `ConfigFlag::Disabled`.

The file reader caches results in a `ConfigFileRc` and gracefully handles skippable I/O errors like permission denied, allowing Deno to continue searching up the directory hierarchy.

## Core Configuration Structure

At the heart of Deno's configuration system lies the `ConfigFile` struct, which stores the absolute URL of the configuration file and its deserialized contents. The strongly typed `ConfigFileJson` struct (defined in [`libs/config/deno_json/mod.rs`](https://github.com/denoland/deno/blob/main/libs/config/deno_json/mod.rs) between lines 1110-1142) represents every valid top-level key using `Option<Value>` fields. Because the struct uses `#[serde(deny_unknown_fields)]`, unknown keys trigger deserialization errors, ensuring strict validation.

### Important Configuration Keys

The [`deno.json`](https://github.com/denoland/deno/blob/main/deno.json) schema supports these primary configuration categories:

- **`compilerOptions`**: TypeScript compiler settings (target, lib, types) equivalent to [`tsconfig.json`](https://github.com/denoland/deno/blob/main/tsconfig.json).
- **`importMap`**: Path to an import map file (file URLs only; remote URLs require the `--import-map` flag).
- **`imports` / `scopes`**: Inline import map entries embedded directly in the config.
- **`tasks`**: Named scripts executable via `deno task <name>`, processed by [`cli/tools/task.rs`](https://github.com/denoland/deno/blob/main/cli/tools/task.rs).
- **`permissions`**: Default permission grants using `allow`, `deny`, and `prompt` arrays, parsed into `PermissionsConfig`.
- **`lint`** and **`fmt`**: Configuration for `deno lint` and `deno fmt` commands.
- **`nodeModulesDir`**: npm compatibility mode (`"auto"`, `"none"`, or `"manual"`).
- **`vendor`**: Boolean enabling automatic dependency vendoring into a `vendor/` folder.
- **`unstable`**: Array of unstable API flags to enable without CLI arguments.
- **`lock`**: Path to a lockfile for deterministic dependency versions.

## Practical Configuration Examples

### Minimal Import Map Configuration

For projects requiring only import mapping, create a minimal [`deno.json`](https://github.com/denoland/deno/blob/main/deno.json):

```json
{
  "importMap": "./import_map.json"
}

```

Deno resolves the path relative to the configuration file location. The `ConfigFile::to_import_map_path` method enforces that `importMap` values must be file specifiers; attempting to use a remote URL here throws an `OnlyFileSpecifiersSupported` error.

### Complete Production Configuration

A comprehensive [`deno.json`](https://github.com/denoland/deno/blob/main/deno.json) for a TypeScript project with tasks, permissions, and formatting rules:

```json
{
  "compilerOptions": {
    "target": "es2022",
    "lib": ["es2022", "dom"]
  },
  "importMap": "./import_map.json",
  "lint": {
    "rules": { "exclude": ["no-explicit-any"] },
    "include": ["src/**/*.ts"]
  },
  "fmt": {
    "indentWidth": 2,
    "lineWidth": 80
  },
  "tasks": {
    "dev": "deno run -A src/main.ts",
    "test": "deno test --coverage"
  },
  "permissions": {
    "allow": ["read", "write", "net"],
    "deny": ["env"]
  },
  "nodeModulesDir": "auto",
  "vendor": true,
  "unstable": ["byonm"]
}

```

This configuration sets TypeScript compilation targets in [`runtime/tsc/mod.rs`](https://github.com/denoland/deno/blob/main/runtime/tsc/mod.rs), defines reusable scripts for the task runner, establishes secure default permissions, and enables automatic `node_modules` generation for npm compatibility.

## Runtime Configuration Application

Deno applies [`deno.json`](https://github.com/denoland/deno/blob/main/deno.json) settings through a structured pipeline before executing user code. First, the configuration loads into the `ConfigFile` struct, with `ConfigFile::to_import_map_path` resolving import map references. The TypeScript compiler receives `compilerOptions` through [`runtime/tsc/mod.rs`](https://github.com/denoland/deno/blob/main/runtime/tsc/mod.rs), while the permission system initializes using `PermissionsConfig` from the `permissions` object.

For task execution, [`cli/tools/task.rs`](https://github.com/denoland/deno/blob/main/cli/tools/task.rs) expands environment variables in the `tasks` map and spawns subprocesses. Each subsystem—linting, formatting, testing—accesses its respective configuration slice (such as `LintConfig` or `FmtConfig`) derived from `ConfigFileJson`. This architecture ensures consistent behavior across `deno run`, `deno test`, `deno compile`, and deployment commands.

## Summary

- **Automatic discovery**: Deno walks up the directory tree to find [`deno.json`](https://github.com/denoland/deno/blob/main/deno.json) or `deno.jsonc` unless you specify `--config` or `--config=none`.
- **Strict validation**: The configuration parses into `ConfigFileJson` with `#[serde(deny_unknown_fields)]`, rejecting unknown keys while validating compiler options, import maps, tasks, and permissions.
- **Single source of truth**: All CLI commands respect the same configuration file, eliminating the need to repeat flags.
- **File-only import maps**: The `importMap` key in [`deno.json`](https://github.com/denoland/deno/blob/main/deno.json) requires local file paths; use CLI `--import-map` for remote URLs.
- **Task automation**: Define project scripts in the `tasks` object to standardize development workflows across your team.

## Frequently Asked Questions

### What is the difference between deno.json and deno.jsonc?

**Deno supports both [`deno.json`](https://github.com/denoland/deno/blob/main/deno.json) (standard JSON) and `deno.jsonc` (JSON with comments).** The `jsonc` variant allows you to include comments and trailing commas for better documentation, which the parser strips before processing. Both files are discovered automatically through the same `ConfigFlag::Discover` mechanism in [`cli/factory.rs`](https://github.com/denoland/deno/blob/main/cli/factory.rs) and use identical schemas.

### Can I use a remote URL for the importMap field in deno.json?

**No, the `importMap` field in [`deno.json`](https://github.com/denoland/deno/blob/main/deno.json) only supports local file paths.** According to the source in [`libs/config/deno_json/mod.rs`](https://github.com/denoland/deno/blob/main/libs/config/deno_json/mod.rs), the `to_import_map_path` method validates that import map specifiers are file URLs, and attempting to specify a remote URL triggers an `OnlyFileSpecifiersSupported` error. For remote import maps, use the `--import-map` CLI flag instead.

### How do I disable automatic configuration discovery?

**Use the `--config=none` flag to completely disable configuration file discovery.** This sets `ConfigFlag::Disabled` in [`cli/args/flags.rs`](https://github.com/denoland/deno/blob/main/cli/args/flags.rs), preventing Deno from walking the directory tree for [`deno.json`](https://github.com/denoland/deno/blob/main/deno.json) or `deno.jsonc`. Alternatively, the explicit `--config /path/to/file.json` flag bypasses automatic discovery and loads only the specified configuration via `ConfigFlag::Path`.

### Where does Deno store the parsed configuration in memory?

**Deno caches the parsed configuration in a `ConfigFileRc` (reference-counted `ConfigFile` instance) returned by `ConfigFile::maybe_find_in_folder`.** The `CliFactory` in [`cli/factory.rs`](https://github.com/denoland/deno/blob/main/cli/factory.rs) holds this reference and distributes configuration slices to subsystems: `compilerOptions` routes to the TypeScript compiler in [`runtime/tsc/mod.rs`](https://github.com/denoland/deno/blob/main/runtime/tsc/mod.rs), permissions populate `PermissionsConfig`, and tasks feed into [`cli/tools/task.rs`](https://github.com/denoland/deno/blob/main/cli/tools/task.rs) for execution.