Skip to content

Linkable

Reference doc for the `sst.Linkable` component.

The Linkable component and the Linkable.wrap method lets you link any resources in your app; not just the built-in SST components. It also lets you modify the links SST creates.

Linking any value

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
new sst.Linkable("MyLinkable", {
properties: { foo: "bar" }
});

You can also use this to combine multiple resources into a single linkable resource. And optionally include permissions or bindings for the linked resource.

sst.config.ts
const bucketA = new sst.aws.Bucket("MyBucketA");
const bucketB = new sst.aws.Bucket("MyBucketB");
const storage = new sst.Linkable("MyStorage", {
properties: {
foo: "bar",
bucketA: bucketA.name,
bucketB: bucketB.name
},
include: [
sst.aws.permission({
actions: ["s3:*"],
resources: [bucketA.arn, bucketB.arn]
})
]
});

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: [storage]
});

Then use the SDK to access it at runtime.

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

Linking any resource

You can also wrap any Pulumi Resource class to make it linkable.

sst.config.ts
Linkable.wrap(aws.dynamodb.Table, (table) => ({
properties: { tableName: table.name },
include: [
sst.aws.permission({
actions: ["dynamodb:*"],
resources: [table.arn]
})
]
}));

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);

Your function will also have the permissions defined above.

You can also modify how SST creates links. 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 built-in link and lets you create your own.


Constructor

new Linkable(name, definition)

Parameters

Properties

name

Type Output<string>

properties

Type Record<string, any>

Methods

static wrap

Linkable.wrap(cls, cb)

Parameters

  • cls (args: any[]) => Resource

    The resource class to wrap.
  • cb (resource: Resource) => Definition

    A callback that returns the definition for the linkable resource.

Returns void

Wrap any resource class to make it linkable. Behind the scenes this modifies the prototype of the given class.

Here we are wrapping the aws.dynamodb.Table class to make it linkable.

sst.config.ts
Linkable.wrap(aws.dynamodb.Table, (table) => ({
properties: { tableName: table.name },
include: [
sst.aws.permission({
actions: ["dynamodb:*"],
resources: [table.arn]
})
]
}));

It’s defining the properties that we want made accessible at runtime and the permissions that the linked resource should have.

Now you can link any aws.dynamodb.Table instances in your app just 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]
});

Since this applies to any resource, you can also use it to wrap SST components and modify how they are linked.

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 built-in link and lets you create your own.

In the above example, we’re modifying the permissions to access a linked sst.aws.Bucket in our app.

Definition

include?

Type (sst.aws.permission | sst.cloudflare.binding)[]

Include AWS permissions or Cloudflare bindings for the linkable resource. The linked resource will have these permissions or bindings.

Include AWS permissions.

{
include: [
sst.aws.permission({
actions: ["lambda:InvokeFunction"],
resources: ["*"]
})
]
}

Include Cloudflare bindings.

{
include: [
sst.cloudflare.binding({
type: "r2BucketBindings",
properties: {
bucketName: "my-bucket"
}
})
]
}

properties

Type Record<string, any>

Define values that the linked resource can access at runtime. These can be outputs from other resources or constants.

{
properties: { foo: "bar" }
}