@alessandrolattao/sst

中文文档
4.17.2-alessandrolattao.36发布于 2026/10/21MITTypeScriptES Module构建来源已验证近 30 天下载 9643

SST CLI fork with a parallel Go build pipeline

原始使用文档
文档目录8 节
  1. What is different
  2. What it costs
  3. Installation
  4. Starting a new project
  5. Relationship with upstream
  6. Upstream documentation
  7. Running locally
  8. License
  ░██████     ░██████   ░██████████
 ░██   ░██   ░██   ░██      ░██    
░██         ░██             ░██    
 ░████████   ░████████      ░██    
        ░██         ░██     ░██    
 ░██   ░██   ░██   ░██      ░██    
  ░██████     ░██████       ░██    

Alessandro Lattao version
Unofficial fork of SST · parallel Go builds, working dev rebuilds, deploys that skip what did not change

npm fork of sst/sst MIT


A personal fork of SST that makes Go projects build faster and behave properly in dev mode.

Everything SST does, it still does. The changes live entirely in the Go runtime and in the dev rebuild loop, and they matter most on a monorepo with many handlers: this fork was built against one with 438 Go Lambda functions.

What is different

  • Go builds run in parallel. The Go runtime held an exclusive lock around the whole build, so it compiled one function at a time no matter how many cores were available. The lock now guards only its own bookkeeping.

  • SST_BUILD_CONCURRENCY_FUNCTION works for Go. The documented knob was implemented for Node and Python only, and silently ignored for Go handlers. It now caps Go builds too, at 4 by default.

  • Rebuilds follow real imports. In dev, SST decided what to rebuild from the directory a changed file sits in. It now uses the handler's actual import graph, so editing a shared package rebuilds every function that imports it, and nothing else.

  • Invalidated handlers rebuild together. Once rebuild scope follows imports, one save can invalidate hundreds of handlers. They used to be recompiled one after another; now they are compiled concurrently, under a limit.

  • A deploy stops recompiling handlers one at a time. Every deploy drops the dev build cache, and each worker then restarts and compiles whatever it no longer finds there, one after another on the event loop. On a stage with 18 Go handlers in dev that was 50 seconds of wall clock, for source that had not changed. The same set now goes through the concurrent rebuild above, and handlers whose runtime starts lazily are left to compile when something invokes them.

  • Editing a shared package no longer redeploys every function. Go stamps each binary with a hash of every source file that fed the build, including the ones the linker then discards as unreachable. Touch one file in a package that hundreds of handlers import and every artifact gets a new hash, so the deploy uploads all of them and updates every Function, for programs whose code is byte-identical to what is already deployed. Deploy builds now link with -buildid=, so two builds differ when the program differs and not before. What that gives up is NT_GNU_BUILD_ID, which -s -w had already made useless here.

  • Deploys stop paying for dev-only work. The import graph is only ever read by the dev file watcher, but it was captured after every build, roughly doubling the cost of every deploy build. It is now captured only in dev.

  • Every Go build says how long it took. A deploy printed nothing between asking for a build and the Function resource turning up minutes later, so the compile time of a single handler was only visible by reading the debug log. Each finished build now prints a Built line with its handler and its seconds, in the same shape as the Created/Updated lines that already carry a duration. It rides on the one event SST's UI prints verbatim, so this stays a change to the Go runtime: no new event type, no case added to the printer, nothing for an upstream merge to land on.

  • A big deploy stops flooding the terminal. The deploy footer lists every resource in flight and redraws in place every 100ms, by moving the cursor back up to its first line. With more resources in flight than the terminal has rows, the cursor stops at the top row, so every redraw left the whole list in the scrollback again: the same Creating line tens of thousands of times. The footer now shows only the lines that fit, with the status line still last. What it says and when is unchanged.

  • The state is half the size. SST runs Pulumi against its local DIY backend, which rewrote the whole state as indented JSON after every resource it changed, while SST uploaded that same file to the state bucket during the deploy. Pulumi has written it compact since 3.238, and the fork is on Pulumi 3.270: on a test app with 40 components the state went from 164 KB to 82 KB. Pulumi's Node.js SDK now needs Node.js 22 or later.

  • Smaller fixes. Resolving GOMODCACHE is cancellable instead of outliving a Ctrl-C, go list output is decoded through explicit JSON tags, and an unparsable concurrency value warns and keeps the default instead of quietly falling back to serial builds.

What it costs

Measured on the 438-handler monorepo this was written for, on a no-op deploy where nothing changed:

beforeafter
build concurrency1 (peak 2)up to the configured limit
per-handler build~1.4s, of which half was the dev-only graph capture~0.6s

And on a deploy that did change something: one file edited in the shared handler framework, which 434 of those modules import. Before, all 434 were uploaded again and had their Function updated. After, only the handlers whose linked program actually changed, which for that edit was one.

Installation

npm install @alessandrolattao/sst
# bun add @alessandrolattao/sst

Built for Linux (x64 and arm64) and macOS (Apple silicon and Intel). The binary is still called sst, so bunx sst, npx sst and every existing script keep working unchanged.

Versions are published as pre-releases (4.17.1-alessandrolattao.1), which means they must be pinned explicitly and will never be picked up by a ^4 range by accident. If your sst.config.ts declares a version constraint, it needs a pre-release floor to accept one, since SST checks it with Masterminds/semver where a plain >= never matches a pre-release:

version: ">= 4.13.1-0",

Starting a new project

sst init writes an sst.config.ts for whatever it finds in the current directory, so install the CLI first and let it generate the config:

mkdir my-app && cd my-app
npm init -y
npm install @alessandrolattao/[email protected]
npx sst init

Then open the generated sst.config.ts and add the pre-release floor to its app() return, otherwise the CLI refuses to run against its own config:

export default $config({
  app(input) {
    return {
      name: "my-app",
      version: ">= 4.13.1-0",
      home: "aws",
    };
  },
  async run() {},
});

From here everything is upstream SST: npx sst deploy --stage dev, npx sst dev, and the getting started guides apply unchanged.

Relationship with upstream

This fork tracks sst/sst and is kept in sync with it automatically: a daily job rebases the patches onto each new upstream release, verifies the result builds and passes, and publishes a matching build. When a rebase conflicts it stops and opens an issue instead of publishing something nobody read. Branches:

  • dev — a plain mirror of upstream, never committed to directly
  • feat/… — one branch per change, rebased on dev, each self-contained enough to be sent upstream
  • alessandrolattao — what actually gets built and published: upstream plus the patches plus the fork's own naming

The published package is renamed so it can sit next to the real one without claiming its name. Everything else, including the SST_BIN_PATH escape hatch, behaves exactly as upstream.

Upstream documentation

The fork changes no behaviour you interact with, so upstream's docs apply as they are:

Running locally

Run bun run setup. You need Go and Bun installed.

cd examples/aws-api
go run ../../cmd/sst <command>

To try a build of this fork against a real project without publishing anything, point SST_BIN_PATH at it:

go build -o /tmp/sst ./cmd/sst
SST_BIN_PATH=/tmp/sst bunx sst deploy --stage dev

License

MIT, same as upstream. See LICENSE, which keeps the original SST copyright.

版本与发布记录

@alessandrolattao/sst 共发布 14 个版本,首次发布于 2026/08/25;过去 12 个月发布了 14 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
4.17.2-alessandrolattao.36latest2026/10/2117 天前
4.17.2-alessandrolattao.332026/10/1128 天前
4.17.1-alessandrolattao.322026/10/021 个月前
4.17.1-alessandrolattao.302026/10/011 个月前
4.17.1-alessandrolattao.292026/09/161 个月前
4.17.1-alessandrolattao.282026/09/161 个月前

关于 @alessandrolattao/sst 的常见问题

@alessandrolattao/sst 是什么?

SST CLI fork with a parallel Go build pipeline

如何安装 @alessandrolattao/sst?

在项目目录运行 npm install @alessandrolattao/sst,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 sst,可以用 npx sst 直接运行。

@alessandrolattao/sst 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@alessandrolattao/sst 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@alessandrolattao/sst 可以商用吗?

@alessandrolattao/sst 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@alessandrolattao/sst 的下载量有多少?

根据 npm 官方下载统计,@alessandrolattao/sst 在 2026/10/06 – 2026/11/04 这 30 天内被下载 9,643 次,日均约 321 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@alessandrolattao/sst 还在维护吗?

最新版本 4.17.2-alessandrolattao.36 发布于 2026/10/21(17 天前);至今共发布 14 个版本,其中过去 12 个月发布了 14 个;首次发布于 2026/08/25。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。