Skip to content

Configuration

The jac.toml file is the central configuration for Jac projects. It defines project metadata, dependencies, command defaults, and plugin settings.

jac create myapp
cd myapp

This creates a jac.toml with default settings.


Project metadata:

[project]
name = "myapp"
version = "1.0.0"
description = "My Jac application"
authors = ["Your Name <you@example.com>"]
license = "MIT"
entry-point = "main.jac"
jac-version = ">=0.9.0"
[project.urls]
homepage = "https://example.com"
repository = "https://github.com/user/repo"
FieldDescription
nameProject name (required)
versionSemantic version
descriptionBrief description
authorsList of authors
licenseLicense identifier
entry-pointMain file (default: main.jac)
jac-versionRequired Jac version

Python/PyPI packages and Jac plugins:

[dependencies]
requests = ">=2.28.0"
numpy = "1.24.0"
byllm = ">=0.4.8"
[dev-dependencies]
pytest = ">=8.0.0"
[dependencies.git]
my-lib = { git = "https://github.com/user/repo.git", branch = "main" }

Version specifiers:

FormatExampleMeaning
Exact"1.0.0"Exactly 1.0.0
Minimum">=1.0.0"1.0.0 or higher
Range">=1.0,<2.0"1.x only
Compatible"~=1.4.2"1.4.x

Default behavior: When you run jac add requests without a version, the package is installed unconstrained and then the actual installed version is queried. A compatible-release spec (~=X.Y) is recorded — e.g., if pip installs 2.32.5, jac.toml gets requests = "~=2.32". The jac update command also uses this format when writing updated versions back.


Defaults for jac run:

[run]
session = "" # Session name for persistence
main = true # Run as main module
cache = true # Use bytecode cache

Defaults for jac start:

[serve]
port = 8000 # Server port
session = "" # Session name
main = true # Run as main module
cl_route_prefix = "cl" # URL prefix for client apps
base_route_app = "" # Client app to serve at /

Build configuration:

[build]
typecheck = false # Enable type checking
dir = ".jac" # Build artifacts directory

The dir setting controls where all build artifacts are stored:

  • .jac/cache/ - Bytecode cache
  • .jac/venv/ - Project virtual environment
  • .jac/client/ - Client-side builds
  • .jac/data/ - Runtime data

Defaults for jac test:

[test]
directory = "" # Test directory (empty = current directory)
filter = "" # Filter pattern
verbose = false # Verbose output
fail_fast = false # Stop on first failure
max_failures = 0 # Max failures (0 = unlimited)

Defaults for jac format:

[format]
outfile = "" # Output file (empty = in-place)

Defaults for jac check:

[check]
print_errs = true # Print errors to console
warnonly = false # Treat errors as warnings

Configure which auto-lint rules are active during jac lint and jac lint --fix. Rules use a select/ignore model with two group keywords:

  • "default" - code-transforming rules only (safe, auto-fixable)
  • "all" - every rule, including unfixable rules like no-print
[check.lint]
select = ["default"] # Code-transforming rules only (default)
ignore = ["combine-has"] # Disable specific rules
exclude = [] # File patterns to skip (glob syntax)

To enable all rules including warning-only rules:

[check.lint]
select = ["all"] # Everything, including no-print

To add specific rules on top of defaults:

[check.lint]
select = ["default", "no-print"] # Defaults + no-print warnings

To enable only specific rules:

[check.lint]
select = ["combine-has", "remove-empty-parens"]

Available lint rules:

Rule NameDescriptionGroup
combine-hasCombine consecutive has statements with same modifiersdefault
combine-globCombine consecutive glob statements with same modifiersdefault
staticmethod-to-staticConvert @staticmethod decorator to static keyworddefault
init-to-canConvert def __init__ / def __post_init__ to can init / can postinitdefault
remove-empty-parensRemove empty parentheses from declarations (def foo()def foo)default
remove-kwescRemove unnecessary backtick escaping from non-keyword namesdefault
hasattr-to-null-okConvert hasattr(obj, "attr") to null-safe access (obj?.attr)default
simplify-ternarySimplify x if x else default to x or defaultdefault
remove-future-annotationsRemove import from __future__ { annotations } (not needed in Jac)default
fix-impl-signatureFix signature mismatches between declarations and implementationsdefault
remove-import-semiRemove trailing semicolons from import from X { ... }default
no-printError on bare print() calls (use console abstraction instead)all

Excluding files from lint:

Use exclude to skip files matching glob patterns:

[check.lint]
select = ["all"]
exclude = [
"docs/*",
"*/examples/*",
"*/tests/*",
"legacy_module.jac",
]

Patterns are matched against file paths relative to the project root. Use * for single-directory wildcards and ** for recursive matching.


Defaults for jac dot (graph visualization):

[dot]
depth = -1 # Traversal depth (-1 = unlimited)
traverse = false # Traverse connections
bfs = false # Use BFS (default: DFS)
edge_limit = 512 # Maximum edges
node_limit = 512 # Maximum nodes
format = "dot" # Output format

Bytecode cache settings:

[cache]
enabled = true # Enable caching
dir = ".jac_cache" # Cache directory

File storage configuration:

[storage]
storage_type = "local" # Storage backend (local)
base_path = "./storage" # Base directory for files
create_dirs = true # Auto-create directories
FieldDescriptionDefault
storage_typeStorage backend type"local"
base_pathBase directory for file storage"./storage"
create_dirsAutomatically create directoriestrue

Environment Variable Overrides:

VariableDescription
JAC_STORAGE_TYPEStorage type (overrides config)
JAC_STORAGE_PATHBase directory (overrides config)
JAC_STORAGE_CREATE_DIRSAuto-create directories ("true"/"false")

Configuration priority: jac.toml > environment variables > defaults.

See Storage Reference for the full storage API.


Plugin configuration:

[plugins]
discovery = "auto" # "auto", "manual", or "disabled"
enabled = ["byllm"] # Explicitly enabled
disabled = [] # Explicitly disabled
# Plugin-specific settings
[plugins.byllm]
model = "gpt-4"
temperature = 0.7
api_key = "${OPENAI_API_KEY}"
# Webhook settings (jac-scale)
[plugins.scale.webhook]
secret = "your-webhook-secret-key"
signature_header = "X-Webhook-Signature"
verify_signature = true
api_key_expiry_days = 365
# Kubernetes version pinning (jac-scale)
[plugins.scale.kubernetes.plugin_versions]
jaclang = "latest"
jac_scale = "latest"
jac_client = "latest"
jac_byllm = "none" # Use "none" to skip installation

Prometheus Metrics (jac-scale):

[plugins.scale.metrics]
enabled = true
endpoint = "/metrics"
namespace = "myapp"
walker_metrics = true

See Prometheus Metrics for details.

Kubernetes Secrets (jac-scale):

[plugins.scale.secrets]
OPENAI_API_KEY = "${OPENAI_API_KEY}"
DATABASE_PASSWORD = "${DB_PASS}"

See Kubernetes Secrets for details.

See also jac-scale Webhooks and Kubernetes Deployment for more options.


Custom command shortcuts:

[scripts]
dev = "jac run main.jac"
test = "jac test -v"
build = "jac build main.jac -t"
lint = "jac lint . --fix"
format = "jac format ."

Run with:

jac script dev
jac script test

Environment-specific overrides:

[environment]
default_profile = "development"
[environments.development]
[environments.development.run]
cache = false
[environments.development.plugins.byllm]
model = "gpt-3.5-turbo"
[environments.production]
inherits = "development"
[environments.production.run]
cache = true
[environments.production.plugins.byllm]
model = "gpt-4"

Activate a profile:

JAC_PROFILE=production jac run main.jac

Use environment variable interpolation:

[plugins.byllm]
api_key = "${OPENAI_API_KEY}" # Required
model = "${MODEL:-gpt-3.5-turbo}" # With default
secret = "${SECRET:?Secret is required}" # Required with error
SyntaxDescription
${VAR}Use variable (error if not set)
${VAR:-default}Use default if not set
${VAR:?error}Custom error if not set

Most settings can be overridden via CLI flags:

# Override run settings
jac run --no-cache --session my_session main.jac
# Override test settings
jac test --verbose --fail-fast
# Override serve settings
jac start --port 3000

[project]
name = "my-ai-app"
version = "1.0.0"
description = "An AI-powered application"
entry-point = "main.jac"
[dependencies]
byllm = ">=0.4.8"
requests = ">=2.28.0"
[dev-dependencies]
pytest = ">=8.0.0"
[run]
main = true
cache = true
[serve]
port = 8000
cl_route_prefix = "cl"
[test]
directory = "tests"
verbose = true
[build]
typecheck = true
dir = ".jac"
[check.lint]
select = ["all"]
ignore = []
exclude = []
[plugins]
discovery = "auto"
[plugins.byllm]
model = "${LLM_MODEL:-gpt-4}"
api_key = "${OPENAI_API_KEY}"
[scripts]
dev = "jac run main.jac"
test = "jac test"
lint = "jac lint . --fix"

The .jacignore file controls which Jac files are excluded from compilation and analysis. Place it in the project root.

One pattern per line, similar to .gitignore:

# Comments start with #
vite_client_bundle.impl.jac
test_fixtures/
*.generated.jac

Each line is a filename or pattern that should be skipped during Jac compilation passes (type checking, formatting, etc.).


VariableDescription
NO_COLORDisable colored terminal output
NO_EMOJIDisable emoji in terminal output
JAC_PROFILEActivate a configuration profile (e.g., production)
JAC_BASE_PATHOverride base directory for data/storage
VariableDescription
JAC_STORAGE_TYPEStorage backend type
JAC_STORAGE_PATHBase directory for file storage
JAC_STORAGE_CREATE_DIRSAuto-create directories
VariableDescription
MONGODB_URIMongoDB connection URI
REDIS_URLRedis connection URL
VariableDescriptionDefault
JWT_SECRETSecret key for JWT signingsupersecretkey
JWT_ALGORITHMJWT algorithmHS256
JWT_EXP_DELTA_DAYSToken expiration in days7
SSO_HOSTSSO callback host URLhttp://localhost:8000/sso
SSO_GOOGLE_CLIENT_IDGoogle OAuth client IDNone
SSO_GOOGLE_CLIENT_SECRETGoogle OAuth client secretNone
VariableDescription
WEBHOOK_SECRETSecret for webhook HMAC signatures
WEBHOOK_SIGNATURE_HEADERHeader name for signature
WEBHOOK_VERIFY_SIGNATUREEnable signature verification
WEBHOOK_API_KEY_EXPIRY_DAYSAPI key expiry in days
VariableDescriptionDefault
APP_NAMEApplication name for K8s resourcesjaseci
K8s_NAMESPACEKubernetes namespacedefault
K8s_NODE_PORTExternal NodePort30001
K8s_CPU_REQUESTCPU resource requestNone
K8s_CPU_LIMITCPU resource limitNone
K8s_MEMORY_REQUESTMemory resource requestNone
K8s_MEMORY_LIMITMemory resource limitNone
DOCKER_USERNAMEDockerHub usernameNone
DOCKER_PASSWORDDockerHub password/tokenNone