#6895·sst

Feature request: documented path for custom/reusable SST v3/Ion components

Author: iDVBCreated May 29, 2026Updated Sep 14, 2026

We are evaluating SST v3/Ion for a large monorepo with many independent sites/services, each with its own sst.config.ts.

In SST v2 we built internal reusable constructs that wrapped SST constructs with our organization defaults:

typescript
new CompanyXNextjsSite(stack, "Site", {
  path: "sites/media/next-app",
  domain,
  waf,
  secrets,
})

With SST v3/Ion, the recommended model appears to be procedural composition from sst.config.ts using dynamic imports:

typescript
/// <reference path="./.sst/platform/config.d.ts" />

export default $config({
  app() {
    return { name: "media", home: "cloudflare" }
  },
  async run() {
    const { createSite } = await import("./infra/site")
    createSite("Media")
  },
})

This works for app-local infra/* files, but we are unsure what the supported path is for a shared monorepo package that creates SST components internally.

Desired shape:

typescript
// packages/sst-components/src/companyx-function.ts
export function createCompanyXFunction(name: string, args: CompanyXFunctionArgs) {
  return new sst.aws.Function(name, {
    runtime: "nodejs22.x",
    architecture: "arm64",
    ...args,
  })
}

Used by multiple apps:

typescript
// sites/media/sst.config.ts
export default $config({
  app() {
    return { name: "media", home: "aws" }
  },
  async run() {
    const { createCompanyXFunction } = await import("@companyx/sst-components/companyx-function")

    createCompanyXFunction("Api", {
      handler: "src/api.handler",
    })
  },
})

The challenge is that sst, provider globals, $app, $interpolate, etc. are provided by the generated SST config context, and it is not clear how a shared package should type or access them.

We also noticed that the component types appear to exist in SST's platform source, for example FunctionArgs and Function, but do not appear to be available through a clean public import path from the published sst package.

Ideally, we could do something like:

typescript
import { Function } from "sst/aws/function"
import type { FunctionArgs } from "sst/aws/function"

or:

typescript
import type { FunctionArgs } from "sst"

But from what we can tell, the published sst package primarily exposes runtime/client modules like sst/resource, sst/auth, sst/event, etc., while the infrastructure components are exposed as generated globals inside sst.config.ts.

A dependency-injection workaround might be:

typescript
// sites/media/sst.config.ts
export default $config({
  app() {
    return { name: "media", home: "aws" }
  },
  async run() {
    const { createCompanyXFunction } = await import("@companyx/sst-components/companyx-function")

    createCompanyXFunction(
      { sst, app: $app, interpolate: $interpolate },
      {
        name: "Api",
        handler: "src/api.handler",
      },
    )
  },
})
typescript
// packages/sst-components/src/companyx-function.ts
export function createCompanyXFunction(ctx: CompanyXSstContext, args: CompanyXFunctionArgs) {
  return new ctx.sst.aws.Function(args.name, {
    runtime: "nodejs22.x",
    architecture: "arm64",
    handler: args.handler,
  })
}

But this feels like a workaround. It either forces us to recreate a partial structural type surface for SST components, or type the context loosely, and we are not sure whether this is the intended pattern.

Questions:

  1. Is there a supported way to build reusable SST v3/Ion components?
  2. Can a shared package directly import and type SST components, for example Function, FunctionArgs, ApiGatewayV2, Worker, etc.?
  3. Are there public/semi-public import paths for SST infrastructure component classes/types, or are generated globals the only supported interface?
  4. Should shared abstractions use SST globals via dependency injection from sst.config.ts?
  5. Should shared abstractions avoid SST components entirely and only export plain Pulumi ComponentResource classes?
  6. Is subclassing/extending SST components intentionally unsupported in v3/Ion?
  7. If the recommended answer is procedural factory functions, can the docs include a monorepo example where a shared package creates SST components internally?

A documented happy path here would be very helpful for teams migrating from SST v2 constructs to SST v3/Ion while preserving organization-specific reusable infrastructure components.