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 🙏

© 2024 – Pkg Stats / Ryan Hefner

sst-custom

v0.0.11

Published

A Pulumi provider for defining custom SST components.

Downloads

28

Readme

sst-custom

A custom pulumi provider, providing support for defining custom SST components as if they were standard.

Why?

If you've defined custom sst components in the past, you may have run into issues in CI or installing everything from scratch. The main issue is when components import from the generated .sst directory; when doing this, the files imported into the custom components must exist before sst has generated them otherwise errors are thrown! This means you have to commit ALL (transitively) dependent sst-generated files into source control and ensure they are always there before running sst install.

This package gets around that, allowing you to define custom components as you'd expect.

Usage

Add the provider:

sst add sst-custom

Configure the provider in your sst.config.ts:

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

export default $config({
	app(input) {
		return {
			name: "my-sst-app",
			removal: input?.stage === "production" ? "retain" : "remove",
			home: "aws",
			providers: {
				"sst-custom": { root: "./infra/custom" },
			},
		};
	},
  async run() {
    // ....
  }
});

Define your components in /infra/custom/platform/src/components/. For example, ./infra/custom/platform/src/components/cloudflare/my-custom-component.ts:

import { Component } from "../../component";

export interface MyCustomComponentArgs {
   // ... define args
}

export class MyCustomComponent extends Component {
  	constructor(
		name: string,
		args: MyCustomComponentArgs,
		opts: $util.ComponentResourceOptions = {}
	) {
		super(__pulumiType, name, args, opts);

    // ... Implementation
  }
}

// Following sst standards
const __pulumiType = "sst:cloudflare:MyCustomComponent";
// @ts-expect-error
MyCustomComponent.__pulumiType = __pulumiType;

Use your component in your sst.config.ts:

  // ... rest of config
  async run() {
    new sst.cloudflare.MyCustomComponent('MyComponent', { ... })
  }

Bun

If sst is configured to use bun, then your custom components will not be installed when you run sst add or sst install because Bun will block the postinstall script. In this case, you can either:

  1. Run NO_BUN=1 sst install to run the install with npm instead
  2. Run bun sst-custom-install to manually install the components
  3. See this FAQ

In either case, you will have to use that option in place of sst install whenever you want to install your custom components.

Imports

You should use typescript rootDirs to resolve imports in your custom components relative to the .sst directory. This means you can import, for example, from the aws directory as if your file was in there already.

For example, if your custom components were located in $ROOT/infra/custom, you could use the following tsconfig.json, placed at $ROOT/infra/custom/tsconfig.json:

{
	"compilerOptions": {
		"rootDirs": ["./../../.sst", "."],
		"lib": ["esnext"],
		"moduleResolution": "bundler",
		"module": "esnext",
		"target": "esnext",
		"types": ["@types/node"]
	},
	"include": ["./../../.sst/platform/**/*", "./platform/**/*"],
}

Platforms

Built-In Platforms

If you want to add a new component to an existing platform (i.e., aws or cloudflare), define it in platform/src/components/[PLATFORM] and it will be copied over to .sst/platform/src/components/[PLATFORM] and it will be added under the platform namespace so you can use it as e.g.,:

new sst.cloudflare.MyCustomComponent('MyComponent', { ... })

New Platforms

For new platforms, you must define the index.ts barrel file yourself, exporting all necessary components. A custom namespace for this platform will then be generated in .sst/platform/src/components/index.ts:

new sst.myplatform.MyCustomComponent('MyComponent', { ... })

Functions

You can add functions in the platform/functions directory and they will also be copied over to .sst/platform/functions.

FAQ

When should I use this?

When you have custom SST components that import from the generated .sst folder. If you have custom components that do not import from .sst, you do not need this.

Why not place the components in .sst myself?

The .sst folder gets destroyed on every .sst install

Why not place my components in a source code directory and leave it as-is?

You would need to then commit any files that you import (and any files they import, and so on). SST does release updates often so you'll find yourself having to commit updates on almost every update.

It says my components are not defined

Verify your custom components have been installed correctly by inspecting .sst/platform/src/.... If your components are not there, run sst install.

However, if sst is configured to use bun, check out the bun section.

How do I update my components

Whenever you make change to the source code of your components, you must run sst install again (or one of the options in the bun section).

Where should I place my utils?

Do not place your utils in a directory directly under platform/src/components e.g., platform/src/components/utils/index.ts, otherwise it will be available as sst.utils, which may be undesired - just place it in a nested directory or outside of src/components, or just do not name the file index.ts.

I keep getting sst is not defined errors

You should not be using the sst namespace in your custom components as this is only resolved at dev/deploy time - you should be directly importing the modules you need, just like the standard sst components do. The same is true for any Pulumi providers you may be referencing.

For example, if we want to create a custom component wrapping sst.aws.Function, we would import Function from ./sst/platform/src/components/aws/function.ts

// Assuming your file is in `infra/custom/platform/src/components/aws/mycomponent.ts
import { Function } from "./function"

// ... and use it in your code instead of `sst.aws.Function`.

Instead of sst.aws.Function.

How can I use other Pulumi providers

Like the sst namespace, you should not be using the Pulumi provider namespace that sst creates in your custom components. Instead, install the provider manually (adding it to your root package.json) and import from that module instead.

For example, if we want to use a Pulumi component from @pulumi/gcp, we'd add @pulumi/gcp to the root package.json and then use imports like

import gcp from "@pulumi/gcp";

Instead of using the global gcp namespace that sst would add if we ran sst add gcp

I keep forgetting to update my components!

You can add the following import to the top of your sst.config.ts so components are reinstalled on every deploy/dev:

import "sst-custom/install";

There's also an install method that you can call in your run function of your sst.config.ts if you'd like to be more explicit:

  // ... rest of config
  async run() {
    sstcustom.install();
  }

Both do the same thing and it is personal preference.