Skip to content

Quick Start

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 — your editor autocompletes bucketName, bucketEncryption, sseAlgorithm, and catches typos immediately. Cross-file references like bucketEncryption are resolved through standard imports at build time.

Built-in composites bundle common resource patterns into reusable factories:

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 synthesize to artifacts. Ops execute — phased, with retries and rollback. Write a minimal one:

hello.op.ts
import { Op, phase, shell } from "@intentius/chant-lexicon-temporal";
export default Op({
name: "hello",
overview: "Minimal local Op — no Temporal server required",
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

No Temporal server required — chant runs Ops locally by default. (The Op imports from @intentius/chant-lexicon-temporal, so install that package — but nothing has to be running.) For durable resume, gates, and schedules, configure a Temporal profile and pass --temporal. See Local vs Temporal.

Once resources are deployed, chant tells you when the cloud and your source disagree — without hosting a 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.