npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@forst/cli

v0.8.1

Published

Forst compiler CLI: install the native `forst` binary. Linux, macOS, Windows.

Downloads

1,822

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

  1. Overview
  2. What’s included
  3. Requirements
  4. Installation
  5. Command-line usage
  6. Environment variables
  7. How the wrapper works
  8. Programmatic API
  9. @forst/cli/invoke
  10. Releases and publishing
  11. Security
  12. Upgrading
  13. Troubleshooting
  14. Relationship to @forst/sidecar
  15. Native compiler CLI
  16. Support
  17. License

Overview

@forst/cli bridges JavaScript/TypeScript workflows and the Forst compiler: by default the pinned forst.compilerRelease in package.json (falling back to the npm package semver when unset) determines which native binary is downloaded from GitHub Releases. Callers may opt into preferLatestRelease so resolution uses semantic versioning to pick the newer of the bundled pin 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. | | @forst/cli/invoke | startForstInvokeServer for Node→Forst HTTP invoke lifecycle in tests and globalSetup. | | @forst/errors (transitive) | Shared invoke/harness failure classes. Installed with @forst/cli; import from @forst/errors (Promise mode, no Effect peer). Effect mode stays at @forst/errors/effect when you add the effect peer. | | Diagnostics | npx forst --forst-cli-info prints npm semver, pinned forst.compilerRelease, resolved compiler version, 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/cli

One-off invocation without adding to package.json:

npx @forst/cli version

After 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 generate

In 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. | | FORST_BASE_URL / FORST_INVOKE_URL / FORST_DEV_URL | Used by @forst/cli/invoke to attach to an existing invoke server instead of spawning. | | FORST_SKIP_SPAWN | When 1 or true, @forst/cli/invoke must attach (via ready file or URL env). Never spawns. | | FORST_CLI_INVOKE_E2E | Set to 1 to run the opt-in real spawn test in this package. |

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:

  1. Read the pinned forst.compilerRelease from package.json (falls back to the npm package semver when unset).
  2. Resolve the corresponding release assets on GitHub for that version.
  3. Download (unless FORST_BINARY is set), verify when a digest is available (unless FORST_CLI_VERIFY disables verification), and place the binary in the cache.
  4. Execute the native forst with 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/.

@forst/cli/invoke

Starts, attaches to, and stops a Forst HTTP invoke server (POST /invoke). This is the Node→Forst direction. It is orthogonal to @forst/node-runtime, which is Forst→Node RPC (startForstNodeHost).

Typical use is integration tests and globalSetup. Application code that uses a generated client usually imports helpers from @forst/gen/$testing instead; those helpers call this subpath.

import { startForstInvokeServer } from "@forst/cli/invoke";

await using server = await startForstInvokeServer({ root: process.cwd() });
// server.baseUrl → http://127.0.0.1:<port>

Behaviour in short:

  • Attach before spawn when baseUrl, FORST_SKIP_SPAWN, .forst/invoke.ready, or FORST_BASE_URL / FORST_INVOKE_URL / FORST_DEV_URL is set. Attach handles never kill the process.
  • mode: "auto" (default) reads ftconfig.json and picks embedded when server.embedded or node.hostMode is true, otherwise dev.
  • Readiness is GET /health, not log scraping.
  • stop() sends SIGTERM, then SIGKILL after 5s.

For host mode (node.hostMode in ftconfig.json), call prepareInvokeConnect() at process startup so connect-mode env and the FORST_INVOKE_AUTH_RECV_FD listener are ready. Use getInvokeAuthHandoff() with a generated client's resolveAuth when auth arrives over the host pipe instead of FORST_INVOKE_TOKEN.

Opt-in real spawn test (needs a local forst binary and Go for embedded compile):

FORST_CLI_INVOKE_E2E=1 bun test src/test-server.e2e.test.ts

Releases and publishing

| Topic | Details | | --- | --- | | Versioning | Release Please manages packages/cli with the Go compiler via the linked-versions plugin. Both share the same semver. Tags like cli-v* bump package.json and jsr.json (see .release-please-config.json). The first linked release may jump @forst/cli from its old line (for example 0.6.x) to the current compiler line. | | Compiler pin | Root compiler releases update forst.compilerRelease via Release Please extra-files in the same release PR that bumps @forst/cli. The npm version and pin stay aligned because the compiler and CLI release together. | | 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.jsonrepository.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_VERIFY unset). Missing digests skip verification unless FORST_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_BINARY and 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 bundled forst.compilerRelease pin (not the npm semver alone). Compiler and CLI releases share one semver, so upgrading @forst/cli also picks up the matching compiler pin.

After upgrading, run:

npx forst --forst-cli-info

Confirm 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 the pinned compiler version’s artifacts. When the pinned release is missing but an older release exists, the wrapper may fall back silently—check npx forst --forst-cli-info for pinned vs resolved version. Unpublished pins or forks may need FORST_BINARY or an upgraded @forst/cli. | | 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.