# Linking

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.

```
   const bucket = new sst.aws.Bucket("MyBucket");
   ```

2. Link it to your function or frontend, using the `link` prop.

```
   new sst.aws.Nextjs("MyWeb", {
     
     link: [bucket]
   });
   ```
   
   ```
   new sst.aws.Remix("MyWeb", {
     
     link: [bucket]
   });
   ```
   
   ```
   new sst.aws.Astro("MyWeb", {
     
     link: [bucket]
   });
   ```
   
   ```
   new sst.aws.Function("MyFunction", {
     
     handler: "src/lambda.handler",
     
     link: [bucket]
   });
   ```

3. Use the [SDK](https://sst.dev/docs/reference/sdk/) to access the linked resource in your runtime in a typesafe way.

```
   import { Resource } from "sst";

console.log(Resource.MyBucket.name);
   ```

Learn how to use the SDK in [Python](https://sst.dev/docs/reference/sdk/#python), [Golang](https://sst.dev/docs/reference/sdk/#golang), and [Rust](https://sst.dev/docs/reference/sdk/#rust).

---

### 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`](https://sst.dev/docs/reference/cli/#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.

```
sst dev next dev
```

```
sst dev remix dev
```

```
sst dev astro dev
```

```
sst 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.

---

### Injecting links

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](https://esbuild.github.io/). While bundling, SST injects the resource links into the [`globalThis`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis). These are encrypted and added to the function bundle. And they are synchronously decrypted on load by the SST SDK.

#### 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.

Resource links are only available on the server-side of your frontend. If you want to access them in your client components, you’ll need to pass them in explicitly.

---

### 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 project root with types for **all** the linked resources in the app.
2. 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 is usually just a small reference shim to the root `sst-env.d.ts` file.

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`](https://sst.dev/docs/component/linkable/) component.

---

### Link any value

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

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

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

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

Then use the [SDK](https://sst.dev/docs/reference/sdk/) to access that at runtime.

```javascript
import { Resource } from "sst";
console.log(Resource.MyLinkable.foo);
```

Read more about [`sst.Linkable`](https://sst.dev/docs/component/linkable/).

---

### Link any resource

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

```javascript
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.

```javascript
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](https://sst.dev/docs/reference/sdk/) to access it at runtime.

```javascript
import { Resource } from "sst";
console.log(Resource.MyTable.tableName);
```

---

### Modify built-in links

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

```javascript
 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`](https://sst.dev/docs/component/linkable/#static-wrap).

---

### Link integration with external providers

If you want to pass links to compute not managed by SST, like a native ECS task definition or a Kubernetes pod, use `Linkable.env()`. It converts your linked resources into `SST_RESOURCE_*` environment variables so `Resource.MyResource` works at runtime.

```javascript
const bucket = new sst.aws.Bucket("MyBucket");

const environment = sst.Linkable.env([bucket]);
```

This returns an `Output<Record<string, string>>` that you can pass to any provider that accepts environment variables.

```javascript
new kubernetes.apps.v1.Deployment("MyDeployment", {
  spec: {
    template: {
      spec: {
        containers: [{
          name: "app",
          image: "my-image",
          env: sst.Linkable.env([bucket]).apply((env) =>
            // Kubernetes requires environment variables to be an array of objects
            Object.entries(env).map(([name, value]) => ({ name, value: String(value) })),
          ),
        }],
      },
    },
  },
});
```

Read more about [`sst.Linkable.env`](https://sst.dev/docs/component/linkable/#static-env).
