Home Documentation Templates Examples Showcase GitHub
Theme

Project internals

.nift/config.json.

The project config tells Nift where content lives, where generated files go, which extensions and template are the defaults, how builds should use threads and detect changes, and which project-wide JSON contracts are available.

A typical web project

{
  "config": {
    "content-dir": "content/",
    "content-ext": ".html",
    "output-dir": "public/",
    "output-ext": ".html",
    "default-template": "templates/template.html",
    "build-threads": -1,
    "incremental-mode": "modified",
    "minify-exts": [],
    "contracts": {
      "routes": ".nift/routes.json"
    }
  }
}

For a web project, public/ is a useful conventional output directory because many servers, hosts and frameworks already use that name for browser-facing files. Nift does not require the directory to be called public/; it simply uses the value in output-dir.

Fields

FieldMeaning
content-dirBase directory used to derive content paths for tracked names. It must be non-empty.
content-extDefault content-file extension. It must begin with ..
output-dirBase directory used to derive generated output paths. For web projects, public/ is a convenient convention.
output-extDefault output extension. It must begin with ..
default-templateTemplate used by newly tracked items when a different template is not supplied.
build-threadsControls build and incremental-analysis worker count. A positive value uses that many threads; 0 uses hardware concurrency; a negative value is a hardware-concurrency multiplier, so -1 means 1× available hardware threads and -2 means 2×.
incremental-modeHow Nift determines whether dependencies changed: modified, hash, or hybrid.
minify-extsOptional array of final output extensions to minify automatically, for example [".html", ".css", ".js"]. Supported formats are documented on the Minification page.
contractsOptional object mapping project-wide contract namespace names to project-relative JSON source paths. Referenced contracts become checked dependencies and are available through $[...].

How tracked names become paths

With this config:

{
  "config": {
    "content-dir": "content/",
    "content-ext": ".html",
    "output-dir": "public/",
    "output-ext": ".html",
    "default-template": "templates/template.html",
    "build-threads": -1,
    "incremental-mode": "modified",
    "minify-exts": []
  }
}

a tracked name such as about resolves naturally to:

content/about.html     →     public/about.html

and a nested name:

docs/getting-started

content/docs/getting-started.html
             ↓
public/docs/getting-started.html

The tracked item stores the name/title/template; the project config supplies the default directory and extension rules that turn the name into concrete content and output paths.

Project contracts

The optional contracts object declares project-wide named JSON sources:

"contracts": {
  "routes": ".nift/routes.json",
  "services": "data/services.json"
}

A declared namespace can then be read anywhere through the normal value syntax, for example $[routes.users.list]. Contract namespaces are reserved project-wide, cannot be shadowed by @json or loop bindings, and are loaded only when referenced. Nift records both the contract source and .nift/config.json as dependencies of outputs that use them.

Read the project contracts reference →

Automatic minification

minify-exts is an optional array. A tracked output is minified after rendering when its final extension is listed:

"minify-exts": [".html", ".css", ".js", ".json", ".svg"]

Individual tracked entries can override the project decision with "minify": true or false. Changing the effective setting invalidates the previous incremental build metadata. See the minification guide →

Incremental modes

modified

Uses modification information to decide whether inputs have changed. This is the generated default and is fast for everyday development.

hash

Uses stored content hashes when determining changes. Files and directory dependencies are hashed by content; directories include their names and nested contents deterministically.

hybrid

Checks modification times or content hashes. It catches ordinary timestamp changes quickly while also detecting content changes whose mtime was preserved.

Should you edit it?

Yes, when you want to change project-wide defaults such as moving generated files to public/, changing the default template, or choosing an incremental mode. It is deliberately ordinary JSON so the project setup is inspectable and easy for humans, scripts and AI assistants to understand.

config.json describes the project-wide rules.

tracked.json describes the individual things Nift manages within those rules.