Manifest Reference

Browse docs

Every lde package is described by an lde.json file at the package’s root. It is the source of truth for your package’s dependencies, features, and registry metadata.

It is a plain JSON object you can edit by hand, or use via the command line helpers with commands like lde add and lde remove.

When first resolving dependencies, lde looks at your lde.json and generates a lockfile, which is invalidated if the lde.json file changes via its hash.

Schema

A JSON Schema for the manifest is provided, which you can find at this URL:

https://raw.githubusercontent.com/lde-org/lde/master/schemas/lde.schema.json

Point your editor at it for autocompletion and validation while editing lde.json.

VSCode

Add the following to your project’s VSCode settings:

{
	"json.schemas": [
		{
			"fileMatch": ["lde.json"],
			"url": "https://raw.githubusercontent.com/lde-org/lde/master/schemas/lde.schema.json"
		}
	]
}

Zed

Add the following to your project’s Zed settings:

{
	"lsp": {
		"json-language-server": {
			"settings": {
				"json": {
					"schemas": [
						{
							"fileMatch": ["lde.json"],
							"url": "https://raw.githubusercontent.com/lde-org/lde/master/schemas/lde.schema.json"
						}
					]
				}
			}
		}
	}
}

Inline $schema

VS Code, Zed, and most other JSON tooling also honor a $schema key directly in the manifest, which needs no editor configuration:

{
	"$schema": "https://raw.githubusercontent.com/lde-org/lde/master/schemas/lde.schema.json",
	"name": "my-package",
	"version": "0.1.0"
}

Example

{
	"name": "my-package",
	"version": "0.1.0",
	"description": "A small example package",
	"authors": ["Ada Lovelace"],
	"engine": "lde",
	"bin": "src/main.lua",
	"scripts": {
		"dev": "lde run ./src/dev.lua"
	},
	"dependencies": {
		"hood": { "git": "https://github.com/bycruz/hood" },
		"ansi": { "path": "../ansi" },
		"json": { "version": "^1.0.0" },
		"luafilesystem": { "luarocks": "luafilesystem" },
		"tools": { "archive": "https://example.com/tools.tar.gz" },
		"winapi": { "git": "https://github.com/bycruz/winapi", "optional": true }
	},
	"devDependencies": {
		"test-utils": { "path": "../test-utils" }
	},
	"features": {
		"windows": ["winapi"]
	}
}

Fields

name (required)

The name of your package. Must be lowercase and may contain letters, digits, - and _, and may be namespaced as ns/name for registry namespaces:

{
	"name": "my-package"
}
{
	"name": "nexus/json"
}

lde uses the name to place the built package at target/<name>, and lde publish reads it to register the package on the registry.

version (required)

The version of your package, as three dot-separated numeric parts (semver):

{
	"version": "1.2.3"
}

lde publish uses it to register the version on the registry, and you bump it whenever you publish an update.

description

A short, human-readable description of what the package does:

{
	"description": "A fast JSON parser for Lua"
}

It is included in the metadata that lde publish pre-fills for registry pull requests.

authors

A list of the package’s authors:

{
	"authors": ["Ada Lovelace", "Alan Turing"]
}

bin

The entry point of your package, relative to the package root. Defaults to src/init.lua when omitted, which is what lde run executes when called without a file argument:

{
	"bin": "src/main.lua"
}

engine

The interpreter used to run your package. Defaults to lde:

{
	"engine": "luajit"
}
Value Meaning
lde The lde runtime
luajit A bare luajit binary on your PATH
lua A bare lua binary on your PATH

scripts

Named shell commands for the package, run from the package root:

{
	"scripts": {
		"dev": "lde run ./src/dev.lua",
		"check": "luacheck src"
	}
}

Run them with lde run <name> (extra arguments after -- are appended to the command).

Commands run through cmd.exe on Windows and /bin/sh everywhere else. See package scripts for more.

dependencies

A map from require name to dependency spec. The key is the name you require() in code, so you can alias a package by choosing a different key. Each value describes where the dependency comes from — exactly one source field per spec:

path dependencies

{
	"dependencies": {
		"ansi": { "path": "../ansi" }
	}
}

A path relative to your package directory. Path dependencies are how sibling packages in a monorepo refer to each other. lde installs them into target/ straight from the source tree (as symlinks where possible) rather than downloading them.

git dependencies

{
	"dependencies": {
		"hood": { "git": "https://github.com/codebycruz/hood" }
	}
}

A git repository URL. lde add <name> --git <url> resolves the ref up front and records the pinned commit in lde.lock, so installs are reproducible. You can pin explicitly or follow a branch:

{
	"dependencies": {
		"hood": { "git": "https://github.com/codebycruz/hood", "commit": "abc123" },
		"hood-dev": { "git": "https://github.com/codebycruz/hood", "branch": "next" }
	}
}

version / registry dependencies

{
	"dependencies": {
		"json": { "version": "^1.0.0" }
	}
}

A package from the lde registry, keyed by version. lde add <name> resolves the newest release up front and saves it as a caret range, so later installs can move to newer compatible releases; lde add <name>@1.2.0 saves ^1.2.0 the same way, and a range you spell out yourself is saved exactly as written.

The version may be a range, in which case installs resolve it to the newest version the range allows:

{
	"dependencies": {
		"json": { "version": "1.0" },
		"fs": { "version": "^0.2.0" },
		"path": { "version": ">=0.1.0 <0.2.0" }
	}
}
Form Meaning
1.2.3 exactly 1.2.3
1.2, 1, 1.2.x the whole prefix: 1.2.0 <= v < 1.3.0, 1.0.0 <= v < 2.0.0
^1.2.3 >=1.2.3 <2.0.0; the leftmost non-zero part is fixed, so ^0.2.3 is >=0.2.3 <0.3.0
~1.2.3 >=1.2.3 <1.3.0 (patch-only changes); ~> is accepted as an alias
>=1.2, >1.2, <2, <=2 comparison bounds; a partial version bounds its whole prefix
>=1.2 <2, >=1.2, <2 space- or comma-joined bounds, all of which must hold
^1.2 || ^2 either range may match
latest, * any version

Since the lockfile pins the commit a range resolved to, bump within the range with lde update, which re-resolves it (the range in lde.json is left as written).

luarocks dependencies

{
	"dependencies": {
		"luafilesystem": { "luarocks": "luafilesystem" }
	}
}

A package from luarocks.org. An optional version field constrains which rock is installed:

{
	"dependencies": {
		"luasocket": { "luarocks": "luasocket", "version": ">= 3.0" }
	}
}

archive dependencies

You can specify a URL to a raw archive file, being a tarball or zip file.

{
	"dependencies": {
		"tools": { "archive": "https://example.com/tools.tar.gz" }
	}
}

This will be downloaded and extracted.

Shared options

Every dependency spec accepts these optional fields:

Field Description
optional If true, the dependency is only installed when enabled by a feature (see features).
features Feature flags to enable for this dependency. See optional dependencies.
package The actual package name at the source, when it differs from the require key (aliasing).
rockspec Path to a .rockspec file relative to the dependency directory, for rockspec-based dependencies.

package is how git dependencies point at a specific package inside a monorepo repository, and how local/registry/archive dependencies resolve under an alias:

{
	"dependencies": {
		"parser": {
			"git": "https://github.com/example/monorepo",
			"package": "json-parser"
		}
	}
}

devDependencies

Same shape as dependencies, but only needed to develop the package itself. Ie for running tests, preprocessing, etc.

{
	"devDependencies": {
		"test-utils": { "path": "../test-utils" }
	}
}

features

Named groups of optional dependencies. A group lists the dependency keys to enable when its flag is active:

{
	"dependencies": {
		"winapi": { "git": "https://github.com/codebycruz/winapi", "optional": true },
		"luaposix": { "luarocks": "luaposix", "optional": true }
	},
	"features": {
		"windows": ["winapi"],
		"linux": ["luaposix"],
		"macos": ["luaposix"]
	}
}

lde activates windows, linux or macos automatically based on the operating system, so optional dependencies can be gated by platform with no extra configuration. Custom feature names can be defined for anything else. See optional dependencies for the full picture.