shovel.json

Configuration file reference. All fields are optional.


Config Expressions

String values support environment variables and expressions.

{
  "port": "$PORT || 7777",
  "platform": "$NODE_ENV === production ? cloudflare : bun"
}

Note: Operators require spaces: $VAR || default not $VAR||default.

OperatorExample
||"$PORT || 7777"
??"$PORT ?? 7777"
===, !=="$ENV === production"
? :"$DEV ? memory : redis"

Path Placeholders

PlaceholderDescription
[outdir]Build output directory
[tmpdir]System temp directory
[git]Git commit SHA

platform

ValueDescription
"node"Node.js
"bun"Bun
"cloudflare"Cloudflare Workers

port


host


workers


logging

{
  "logging": {
    "sinks": {
      "console": {
        "module": "@logtape/logtape",
        "export": "getConsoleSink"
      }
    },
    "loggers": [
      { "category": "app", "level": "info", "sinks": ["console"] }
    ]
  }
}

Sink Modules

ModuleExportDescription
@logtape/logtapegetConsoleSinkConsole
@logtape/filegetFileSinkFile
@logtape/filegetRotatingFileSinkRotating file
@logtape/otelgetOpenTelemetrySinkOpenTelemetry

Logger Fields

FieldType
categorystring | string[]
level"debug" | "info" | "warning" | "error"
sinksstring[]
parentSinks"override"

build

{
  "build": {
    "target": "es2022",
    "minify": true,
    "sourcemap": "external"
  }
}
FieldTypeDefault
targetstring | string[]"es2022"
minifybooleanfalse
sourcemapboolean | "inline" | "external"false
treeShakingbooleantrue
defineRecord<string, string>-
aliasRecord<string, string>-
externalstring[]-
pluginsBuildPluginConfig[]-

caches

{
  "caches": {
    "sessions": {
      "module": "@b9g/cache/memory",
      "maxEntries": 1000
    }
  }
}
FieldTypeDescription
modulestringModule path
exportstringNamed export
maxEntriesnumberMax entries
TTLnumberTTL in seconds

Use "*" as catch-all.


directories

{
  "directories": {
    "uploads": {
      "module": "@b9g/filesystem/node-fs",
      "path": "./uploads"
    }
  }
}
FieldTypeDescription
modulestringModule path
exportstringNamed export (default: "default")
pathstringFilesystem path (relative to project root, or absolute)
bindingstringPlatform binding (Cloudflare)
bucketstringS3 bucket
regionstringAWS region
endpointstringS3 endpoint

Built-in Directories

The names server, public, and tmp have platform defaults and do not require module or export:

NameDefault PathDescription
server[outdir]/serverServer-side bundled code
public[outdir]/publicStatic assets
tmp[tmpdir]Temporary files

Custom Directories

Any other directory name requires an explicit module (and optionally export):

{
  "directories": {
    "uploads": {
      "module": "@b9g/filesystem/node-fs",
      "path": "./uploads"
    },
    "shared": {
      "module": "@b9g/filesystem/node-fs",
      "path": "../shared-data"
    },
    "assets": {
      "module": "@b9g/filesystem-s3",
      "bucket": "my-assets",
      "region": "us-east-1"
    }
  }
}

The path field is resolved relative to the project root. Paths outside the project (e.g. "../docs") are supported. Directory traversal within opened directories is blocked at the filesystem level.


databases

{
  "databases": {
    "main": {
      "module": "@b9g/zen/bun",
      "url": "sqlite://./data.db"
    }
  }
}
FieldTypeDescription
modulestringModule path
exportstringNamed export
urlstringConnection URL

URL Formats

DatabaseFormat
SQLitesqlite://./path.db
PostgreSQLpostgres://user:pass@host:5432/db

Module/Export Pattern

{
  "module": "package-name",
  "export": "namedExport",
  "...options": "passed to factory"
}

TypeScript

Shovel generates shovel.d.ts for type-safe resource access:

const cache = await self.caches.open("sessions");  // Type-checked