@forst/cli
v0.1.0
Published
Forst compiler CLI: install the native `forst` binary. Linux, macOS, Windows.
Maintainers
Readme
@forst/cli
Node.js distribution of the Forst compiler. This package ships a small wrapper that downloads and caches the official native forst binary for your platform from GitHub Releases—the same artifacts built with task build:release in the main repository. No local Go toolchain is required.
Use it in npm scripts, developer tooling, or as a dependency of libraries such as @forst/sidecar.
Table of contents
- Overview
- What’s included
- Requirements
- Installation
- Command-line usage
- Environment variables
- How the wrapper works
- Programmatic API
- Releases and publishing
- Security
- Upgrading
- Troubleshooting
- Relationship to
@forst/sidecar - Native compiler CLI
- Support
- License
Overview
@forst/cli bridges JavaScript/TypeScript workflows and the Forst compiler: by default the npm package version determines which native binary is downloaded (matching that semver on GitHub Releases). Callers may opt into preferLatestRelease so resolution uses semantic versioning to pick the newer of the bundled semver and GitHub’s latest release. The binary is cached per version so repeat invocations avoid redundant downloads.
The wrapper is responsible for resolution, verification, and concurrency-safe installation—not for implementing compiler features (those live in the native forst executable).
What’s included
| Deliverable | Description |
| --- | --- |
| forst on PATH | Via node_modules/.bin/forst when installed as a dependency, or npx @forst/cli / npx forst without a global install. |
| JavaScript API | resolveForstBinary, spawnForst, getCliPackageVersion, etc., for tools that need to locate or run the binary programmatically. |
| Diagnostics | npx forst --forst-cli-info prints package semver, resolved binary path, and forst version output—use this in bug reports and CI logs. |
Requirements
| Requirement | Details |
| --- | --- |
| Node.js | Version 18 or later (engines in package.json). |
| Network | HTTPS access to github.com on first use (binary download and release metadata), unless you bypass download with FORST_BINARY. |
| Platforms | Linux, macOS, and Windows on CPU architectures published for your package version on the project’s GitHub Releases. |
Installation
As a dev dependency (typical for apps and libraries):
npm install -D @forst/cliOne-off invocation without adding to package.json:
npx @forst/cli versionAfter install, the wrapper is available as node_modules/.bin/forst.
On first use, the wrapper downloads the binary for the installed package version from GitHub. For offline or locked-down CI, set FORST_BINARY to a pre-installed executable (see Environment variables).
Command-line usage
The wrapper forwards arguments to the native forst binary once it is resolved. Examples:
# After local install
npx forst version
npx forst dev --help
npx forst generateIn package.json scripts:
{
"scripts": {
"forst": "forst",
"dev:forst": "forst dev"
}
}For full command coverage (dev, generate, lsp, fmt, …), see Native compiler CLI.
Environment variables
| Variable | Purpose |
| --- | --- |
| FORST_BINARY | Absolute path to a forst executable; skips download entirely. |
| FORST_CACHE_DIR | Base directory for cached binaries. Default: ~/.cache/forst-cli on Unix, %LOCALAPPDATA%/forst-cli/cache on Windows. Each compiler version is stored in a subdirectory. |
| FORST_CLI_VERIFY | Default (unset): verify SHA-256 when GitHub release metadata includes a digest; skip verification and download anyway when no digest is available. Set 0 or false to never verify. Set 1 or strict to require a digest and refuse unverified downloads. |
Behavior: downloads retry on transient HTTP errors, use an exclusive lock when two processes install concurrently, and write the binary atomically so a partial file never replaces a good one. In air-gapped or API-restricted environments, prefer FORST_BINARY. Use FORST_CLI_VERIFY=strict only when you must refuse downloads without a digest.
How the wrapper works
By default, programmatic resolution (resolveForstBinary with no options) follows the same rules as the CLI shim:
- Read the pinned
forst.compilerReleasefrompackage.json(falls back to the npm package semver when unset). - Resolve the corresponding release assets on GitHub for that version.
- Download (unless
FORST_BINARYis set), verify when a digest is available (unlessFORST_CLI_VERIFYdisables verification), and place the binary in the cache. - Execute the native
forstwith your arguments.
Optional: follow GitHub’s latest compiler release (semantic versioning). Pass preferLatestRelease: true to resolveForstBinary (and keep allowDownload: true). The wrapper scans GitHub releases for root compiler tags (vX.Y.Z), compares the highest tag to the bundled forst.compilerRelease, and uses the higher semver for the cache path and download. The response is cached on disk under your cache root (.latest-compiler-release.json, refreshed about once per hour). If the latest check fails (offline, rate limits), resolution falls back to the bundled compiler release only.
Upgrading the npm package remains the supported way to move the minimum compiler version in Node workflows; preferLatestRelease is for integrations (for example the VS Code extension) that should track GitHub releases between extension publishes.
Programmatic API
import { resolveForstBinary, spawnForst, getCliPackageVersion } from "@forst/cli";
const bin = await resolveForstBinary();
// Optional: max(bundled semver, GitHub latest) — see "How the wrapper works" above.
// await resolveForstBinary({ preferLatestRelease: true });
// spawnForst(["generate", "-h"], {}, { version: "0.0.19" });See TypeScript definitions under dist/ after build, or source in src/.
Releases and publishing
| Topic | Details |
| --- | --- |
| Versioning | Release Please manages packages/cli; tags like cli-v* bump package.json and jsr.json (see .release-please-config.json). |
| Automation | When a GitHub Release is published, .github/workflows/publish-packages.yml publishes @forst/cli to npm and JSR. |
| npm | Package page. CI may use trusted publishing (OIDC); a repository NPM_TOKEN can still be used where a classic token fallback is required. |
| JSR | jsr.io/@forst/cli—link the repository for OIDC or configure JSR_TOKEN as documented by JSR. |
| Manual JSR | From packages/cli: npx jsr publish --dry-run or npx jsr publish. A clean git tree is expected unless you pass --allow-dirty. |
| repository.url | For trusted publishing from GitHub Actions, package.json → repository.url must exactly match the GitHub repo running CI (e.g. git+https://github.com/forst-lang/forst.git). Forks must update this field to the fork (or publish only from the upstream repo)—otherwise npm can reject the publish. |
Security
- Integrity: when GitHub exposes a digest on release assets, binaries are verified by default (
FORST_CLI_VERIFYunset). Missing digests skip verification unlessFORST_CLI_VERIFY=strict. - Install safety: atomic writes and locking reduce the risk of corrupted executables under parallel installs.
- Operational hardening: in restricted environments, supply a vetted binary via
FORST_BINARYand prefer OIDC or short-lived credentials in CI over long-lived tokens in logs.
Upgrading
Change the @forst/cli version in package.json (or your lockfile) when you need a compiler release that shipped after your current dependency. Unless you opt into preferLatestRelease in code, the wrapper binds to the installed npm semver, not an implicit “latest” on the registry—stale dependencies mean a stale compiler until you upgrade.
After upgrading, run:
npx forst --forst-cli-infoConfirm that the reported package version, binary path, and forst version match your expectations.
Troubleshooting
| Symptom | What to check |
| --- | --- |
| Download fails or 404 on an asset | A GitHub release must exist for this package version’s artifacts. Unpublished semvers or forks may need FORST_BINARY or a published CLI version. |
| Wrong OS or architecture | Override with FORST_BINARY for custom builds or unsupported matrices. |
| SHA-256 / verification errors | Checksum mismatch (CompilerBinaryChecksumMismatch): downloaded bytes differ from GitHub metadata — do not run the binary; clear the cache entry and retry, or use FORST_BINARY. May indicate corruption, proxy tampering, or supply-chain attack. Strict mode, no digest (CompilerBinaryDigestUnavailable): FORST_CLI_VERIFY=strict requires a digest but the release tag, asset name, or GitHub digest is missing — check forst.compilerRelease. Default (unset) skips verification when no digest is available and still downloads. |
| Concurrent installs | Locking prevents corruption; different versions use separate cache subdirectories. |
Relationship to @forst/sidecar
@forst/sidecar depends on this package and uses resolveForstBinary so dev-server integration and the CLI share one download and cache implementation.
Native compiler CLI
The native binary implements forst dev, forst generate, forst lsp, forst fmt, and related commands. Implementation entry point: forst/cmd/forst/main.go. Refer to the main repository for the full CLI reference and language documentation.
Support
Report issues and feature requests in the issue tracker. Include npx forst --forst-cli-info output and your OS/architecture when reporting download or verification problems.
License
MIT — see LICENSE.
