Homebrew tap for Open Constructs projects.
brew install open-constructs/tap/cdktnThe fully-qualified form works without a prior brew tap. If you plan to install other open-constructs/tap formulae later, you can tap once and install by short name:
brew tap open-constructs/tap
brew install cdktncdktn — CDK Terrain CLI
Community fork of the deprecated cdktf (CDK for Terraform) formula.
- Current version: 0.22.1 (tracks the
cdktn-clinpm release) - Source:
open-constructs/cdk-terrain - License: MPL-2.0
- Dependencies:
node@20,yarn(build-time). A Terraform-compatible binary (hashicorp/tap/terraformoropentofu) is required at runtime but not enforced by the formula — see Runtime: Terraform or OpenTofu. - Formula:
Formula/cdktn.rb
Stable (brew install cdktn): installs the prebuilt cdktn-cli npm tarball into libexec — around 390 MB installed.
Bleeding-edge (brew install --HEAD cdktn): builds from the cdk-terrain main branch via yarn build (full monorepo, tsc + jsii) — around 1.5 GB installed.
cdktn shells out to a Terraform-compatible binary at runtime. It's intentionally not a formula dependency so you can pick the binary that matches your licensing and workflow preferences:
- Why no default? Hashicorp relicensed Terraform from MPL-2.0 to the Business Source License (BSL) in August 2023. Homebrew-core subsequently dropped the
terraformformula (the community forkopentofureplaced it for users who want to stay on an open-source license). CDK Terrain itself exists as a community fork of the now-archivedterraform-cdk(CDKTF) project — we don't want to force tap users onto either side of that split.
Install whichever you prefer:
brew install hashicorp/tap/terraform # upstream Terraform (BSL)
# — or —
brew install opentofu # OpenTofu (MPL-2.0) — open-source forkIf you use OpenTofu, point the cdktn CLI at the tofu binary via the cdktf-era env var that cdktn still honors:
export TERRAFORM_BINARY_NAME=tofu(cdktn inherits TERRAFORM_BINARY_NAME from CDKTF for backwards compatibility with existing projects — no CDKTN_* alias is needed.)
Homebrew's cdktf formula was deprecated by upstream and will be disabled on 2026-12-10. To switch:
brew uninstall cdktf
brew tap open-constructs/tap
brew install cdktnThe CLI binary renames cdktf → cdktn. Existing cdktf.json config files and CDKTF_* environment variables still work (see the upstream CDKTN Rename notes).
brew install fails at brew link with a conflict on /opt/homebrew/bin/cdktn:
You have a stale global npm install of cdktn-cli on your PATH. Remove it with:
npm uninstall -g cdktn-cliThen re-run brew link cdktn. (Note: cdktn-cli on npm is the real, maintained CLI — same artifact Homebrew installs. If you prefer npm over Homebrew you can keep the npm install; the conflict only matters if you want both.)
Install size feels large for a CLI. The stable (npm) path is ~390 MB and the --HEAD path is ~1.5 GB. Both ship the CLI's runtime node_modules because the CLI is a partial esbuild bundle that loads several dependencies (cdktn, @cdktn/hcl2cdk, constructs, yargs, ...) at runtime rather than inlining them.
A few non-obvious bits future maintainers should know about Formula/cdktn.rb:
bare-*prebuild prune. The stable install block deletes non-nativeprebuilds/*directories frombare-fs,bare-os, andbare-url(transitive deps pulled in by the holepunch runtime). Without this,brew audit --new --strict --onlineflags the foreign-arch.barebinaries as "non-native binaries installed into cdktn's prefix." cdktn never loads them, so pruning is safe.- Stable vs
--HEADbranches. Stable installs the published npm tarball;--HEADdoes a full monorepoyarn install && yarn buildagainstopen-constructs/cdk-terrain'smain. The--HEADpath also rewrites"version": "0.0.0"inpackages/cdktn-cli/package.jsonsocdktn --versionmatches the formula version at build time.
To iterate on a formula change without a full GitHub round-trip, point Homebrew at a local clone of this repo. Modern Homebrew (≥5.x) clones the source path rather than symlinking, so there are two options:
git clone https://github.com/open-constructs/homebrew-tap.git
cd homebrew-tap
brew untap open-constructs/tap 2>/dev/null || true
brew tap open-constructs/tap "$(pwd)"Edit Formula/cdktn.rb in your clone, then git add && git commit, then tell the tapped copy to pull:
git -C /opt/homebrew/Library/Taps/open-constructs/homebrew-tap pullEach edit needs a local commit + git pull before brew audit / brew install sees it.
Replace the tap clone with a symlink to your working tree so edits are picked up immediately — no commit, no pull:
brew untap open-constructs/tap 2>/dev/null || true
rm -rf /opt/homebrew/Library/Taps/open-constructs/homebrew-tap
ln -s "$(pwd)" /opt/homebrew/Library/Taps/open-constructs/homebrew-tapWhen you're done, restore the real tap:
rm /opt/homebrew/Library/Taps/open-constructs/homebrew-tap
brew tap open-constructs/tapbrew audit --new --strict --online open-constructs/tap/cdktn--new applies stricter rules (used for formulae new to a tap). --online fetches the url/head to verify they resolve. Exit 0 means clean.
brew install open-constructs/tap/cdktn
cdktn --version # should print the formula's versionAdd --verbose to see every step. Add --build-from-source to force the def install block to run locally (meaningless for this formula today since it has no bottles, but useful later).
brew install --HEAD open-constructs/tap/cdktnBuilds from github.com/open-constructs/cdk-terrain main. Expect ~1.5 GB on disk.
brew test cdktnRequires the formula to be brew link-ed. If linking is blocked by a conflict (see Troubleshooting above), either resolve the conflict or read the test do block in Formula/cdktn.rb and invoke its assertions by hand against /opt/homebrew/Cellar/cdktn/<version>/bin/cdktn.
brew uninstall cdktn
brew untap open-constructs/tapVersion bumps, bug reports, and PRs welcome.
When a new cdktn-cli is published on npm:
# 1. Get the new tarball URL and its SHA256.
NEW_VERSION=$(npm view cdktn-cli@latest version)
curl -sL "https://registry.npmjs.org/cdktn-cli/-/cdktn-cli-${NEW_VERSION}.tgz" | shasum -a 256
# 2. Edit Formula/cdktn.rb — update `url` (the version number) and `sha256` to match.
# 3. Re-tap locally (Option B from "Testing locally" above), then:
brew audit --new --strict --online open-constructs/tap/cdktn
brew uninstall cdktn 2>/dev/null || true
brew install open-constructs/tap/cdktn
cdktn --version # should print $NEW_VERSION
brew test open-constructs/tap/cdktn
# 4. Commit with message: "feat(cdktn): bump to <version>"Things to watch for on a bump:
- New transitive prebuilds. If
brew auditcomplains about non-native binaries other than the already-prunedbare-*set, extend the prune glob inFormula/cdktn.rb. - Node major bumps. The formula pins
node@20; if upstream moves to a newer LTS, update thedepends_onand thewrite_env_scriptPATH. cdktf→cdktnenv-var renames. cdktn currently honorsTERRAFORM_BINARY_NAME(and otherCDKTF_*vars) for CDKTF compatibility. If upstream addsCDKTN_*aliases, mention them in the runtime section above.
Please run the audit and both install paths before opening a PR.