Skip to content

Quick Start

llms.txt lists every page for an agent
Optional: hand this page to your coding agentThe steps work by hand too.
Show the whole prompt
Read https://intentius.io/chant/getting-started/quick-start/.
Follow the page in a new directory: install the aws lexicon, run `npx chant init my-infra --lexicon aws`, and add the resources and the `LambdaNode` composite it shows.
Run `npx chant build` and `npx chant lint`, then write the `hello.op.ts` Op and run it with `npx chant run hello --no-record`.
Show me the build output and the run output, and stop there. Skip the drift step, since it reads a deployed environment.
Never deploy to a real cloud account or shared environment (with `chant run`, `chant components` or a platform's own CLI), approve (a pull request review, `chant approve` or `chant run approve`), override a policy denial (`chant approve policy-override`), or merge; never cut or publish a release (`chant release cut --yes` or `chant release publish`), push or delete a `ci/*` tag (`chant ci tick` pushes them), or change the value of an existing flag; never touch `.chant/allowed_signers` or `chant/lifecycle`.

Install a lexicon for your target platform (this also installs chant):

Terminal window
npm install --save-dev @intentius/chant-lexicon-aws # or another lexicon

Verify it works:

Terminal window
chant --version

See Installation for details.

Terminal window
chant init my-infra --lexicon aws
cd my-infra

This scaffolds a project with a chant.config.ts and starter resources in src/.

Here’s a typical chant project. Shared defaults are regular exports that other files import directly:

src/defaults.ts
import {
ServerSideEncryptionByDefault,
ServerSideEncryptionRule,
BucketEncryption,
PublicAccessBlockConfiguration,
VersioningConfiguration,
} from "@intentius/chant-lexicon-aws";
export const encryptionDefault = new ServerSideEncryptionByDefault({
SSEAlgorithm: "AES256",
});
export const encryptionRule = new ServerSideEncryptionRule({
ServerSideEncryptionByDefault: encryptionDefault,
});
export const bucketEncryption = new BucketEncryption({
ServerSideEncryptionConfiguration: [encryptionRule],
});
export const publicAccessBlock = new PublicAccessBlockConfiguration({
BlockPublicAcls: true,
BlockPublicPolicy: true,
IgnorePublicAcls: true,
RestrictPublicBuckets: true,
});
export const versioningEnabled = new VersioningConfiguration({
Status: "Enabled",
});
export const lambdaTrustPolicy = {
Version: "2012-10-17",
Statement: [
{
Effect: "Allow",
Principal: { Service: "lambda.amazonaws.com" },
Action: "sts:AssumeRole",
},
],
};
export const lambdaBasicExecutionArn =
"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole";

Resource files import types from the lexicon and reference sibling exports through direct imports:

src/data-bucket.ts
import { Bucket, Sub, AWS, Ref } from "@intentius/chant-lexicon-aws";
import { versioningEnabled, bucketEncryption, publicAccessBlock } from "./defaults";
import { environment } from "./params";
export const dataBucket = new Bucket({
BucketName: Sub`${AWS.StackName}-${Ref(environment)}-data`,
VersioningConfiguration: versioningEnabled,
BucketEncryption: bucketEncryption,
PublicAccessBlockConfiguration: publicAccessBlock,
});

Every property is typed, so your editor autocompletes bucketName, bucketEncryption and sseAlgorithm, and flags typos as you type. Cross-file references like bucketEncryption are resolved through standard imports at build time.

Built-in composites are functions that create a common group of resources:

src/main.ts
import { LambdaNode, Sub, AWS, Ref } from "@intentius/chant-lexicon-aws";
import { environment } from "./params";
export const app = LambdaNode({
name: Sub`${AWS.StackName}-${Ref(environment)}-fn`,
Code: {
ZipFile: `exports.handler = async (event) => {
console.log("Event:", JSON.stringify(event));
return {
statusCode: 200,
body: JSON.stringify({ message: "Hello from Lambda!" }),
};
};`,
},
});

LambdaNode creates an IAM Role + Lambda Function with Node.js defaults. See Composites for all built-in composites.

See the AWS CloudFormation lexicon reference for intrinsic functions, composites, custom lint rules, and examples.

Terminal window
chant build

The build command discovers all .ts files, collects exported declarables, resolves dependencies, and serializes to the target format.

Resources build to files. An Op runs phases, with retries and rollback. Write a minimal one:

hello.op.ts
import { Op, phase, shell } from "@intentius/chant/op";
export default Op({
name: "hello",
overview: "Minimal Op — nothing to install, nothing to run",
taskQueue: "hello",
phases: [
phase("Greet", [
shell("echo hello from chant"),
]),
],
});
Terminal window
chant run hello
[phase] Greet
✓ shellCmd(cmd=echo hello from chant) 42ms
Op "hello" completed in 0.1s

Op, phase and shell come from @intentius/chant/op, and chant run executes the phases in this process. A gate works here too: the run reads the gate ledger and either walks through or records that it is waiting. When an Op needs a machine of its own, a standing record, or a cadence nobody triggers, chant run <op> --on fountain hands the same declaration to a steward. See Ops as teammates.

Once resources are deployed, chant reports where the cloud and your source differ, with no hosted state file:

Terminal window
chant lifecycle diff prod --live

That’s the observe position: report drift, change nothing. From there you turn the dial up per environment — open cloud → code PRs (ReconcileOp) or apply code → cloud behind a gate (ApplyOp). The lifecycle-reconcile-aws example walks the whole loop; Lifecycle Models explains the dial.

chant