Skip to content

Linking

Link resources together and access them in a typesafe and secure way.

Resource Linking allows you to access your infrastructure in your runtime code in a typesafe and secure way.

  1. Create a resource that you want to link to. For example, a bucket.

    sst.config.ts
    const bucket = new sst.aws.Bucket("MyBucket");
  2. Link it to your function or frontend, using the link prop.

    sst.config.ts
    new sst.aws.Nextjs("MyWeb", {
    link: [bucket]
    });
  3. Use the SDK to access the linked resource in your runtime in a typesafe way.

    app/page.tsx
    import { Resource } from "sst";
    console.log(Resource.MyBucket.name);

Working locally

The above applies to your app deployed through sst deploy.

To access linked resources locally you’ll need to be running sst dev. By default, the sst dev CLI runs a multiplexer that also starts your frontend for you. This loads all your linked resources in the environment. Read more about sst dev.

However if you are not using the multiplexer.

sst dev --mode=basic

You’ll need to wrap your frontend’s dev command with the sst dev command.

Terminal window
sst dev next dev

How it works

At high level when you link a resource to a function or frontend, the following happens:

  1. The links that the resource exposes are injected into the function package.

  2. The types to access these links are generated.

  3. The function is given permission to access the linked resource.


Resource links are injected into your function or frontend package when you run sst dev or sst deploy. But this is done in a slightly different way for both these cases.

Functions

The functions in SST are tree shaken and bundled using esbuild. While bundling, SST injects the resource links into the globalThis.

Frontends

The frontends are not bundled by SST. Instead, when they are built, SST injects the resource links into the process.env object using the prefix SST_RESOURCE_.

This is why when you are running your frontend locally, it needs to be wrapped in the sst dev command.


Generating types

When you run sst dev or sst deploy, it generates the types to access the linked resources. These are generated as:

  1. A sst-env.d.ts file in the same directory of the nearest package.json of the function or frontend that’s receiving the links. This contains the types for the resources that are linked to it.
  2. A .sst/types.generated.ts file that can be referenced from a sst-env.d.ts. This is useful for monorepo packages that don’t have a function or frontend. For example, if you have a core package that contains some shared code.

You can check the generated sst-env.d.ts types into source control. This will let your teammates see the types without having to run sst dev when they pull your changes.


Extending linking

The examples above are built into SST’s components. You might want to modify the permissions that are granted as a part of these links.

Or, you might want to link other resources from the Pulumi/Terraform ecosystem. Or want to link a different set of outputs than what SST exposes.

You can do this using the sst.Linkable component.


The Linkable component takes a list of properties that you want to link. These can be outputs from other resources or constants.

sst.config.ts
const myLinkable = new sst.Linkable("MyLinkable", {
properties: { foo: "bar" }
});

You can optionally include permissions or bindings for the linked resource.

Now you can now link this resource to your frontend or a function.

sst.config.ts
new sst.aws.Function("MyApi", {
handler: "src/lambda.handler",
link: [myLinkable]
});

Then use the SDK to access that at runtime.

src/lambda.ts
import { Resource } from "sst";
console.log(Resource.MyLinkable.foo);

Read more about sst.Linkable.


You can also wrap any resource class to make it linkable with the Linkable.wrap static method.

sst.config.ts
Linkable.wrap(aws.dynamodb.Table, (table) => ({
properties: { tableName: table.name }
}));

Now you create an instance of aws.dynamodb.Table and link it in your app like any other SST component.

sst.config.ts
const table = new aws.dynamodb.Table("MyTable", {
attributes: [{ name: "id", type: "S" }],
hashKey: "id"
});
new sst.aws.Nextjs("MyWeb", {
link: [table]
});

And use the SDK to access it at runtime.

app/page.tsx
import { Resource } from "sst";
console.log(Resource.MyTable.tableName);

You can also modify the links SST creates. For example, you might want to change the permissions of a linkable resource.

sst.config.ts
sst.Linkable.wrap(sst.aws.Bucket, (bucket) => ({
properties: { name: bucket.name },
include: [
sst.aws.permission({
actions: ["s3:GetObject"],
resources: [bucket.arn]
})
]
}));

This overrides the existing link and lets you create your own.

Read more about sst.Linkable.wrap.