1---
2title: References
3description: Read an already-deployed Resource or Stack at plan time — Resource.ref by Logical ID with optional stack/stage props, or import a Stack tag and depend on its outputs.
4---
5
6A reference reads something **already deployed** — a different
7stage, a different Stack, or both — from the persisted
8[state store](/state-store) at plan time. References are
9lazy and don't drift: every plan re-reads the upstream's state, so
10downstream always sees whatever was actually last deployed.
11
12## Reference another stage
13
14`Resource.ref` takes a
15[Logical ID](/infrastructure-as-code/resource#logical-id); pass
16`stage` to read that Resource from a different stage of this stack:
17
18```typescript
19const { stage } = yield* Alchemy.Stack;
20
21const project = stage.startsWith("pr-")
22 ? yield* Neon.Project.ref("app-db", { stage: "staging" })
23 : yield* Neon.Project("app-db", { region: "aws-us-east-1" });
24```
25
26The ref has the same type as `yield* Neon.Project("app-db", { … })`
27— pass it anywhere the real thing is accepted. Here `staging` owns
28the database and `pr-*` stages borrow it; destroying a borrower
29never touches the Resources it references.
30
31## Reference another Stack
32
33Pass `stack` too for a Resource in a different Stack:
34
35```typescript
36const sharedBucket = yield* Storage.Bucket.ref("Assets", {
37 stack: "shared-infra",
38 stage: "prod",
39});
40```
41
42`{ stack, stage, id }` is the full address; anything you omit
43defaults to the current stack/stage. Pin `stage` when the stacks'
44stages don't line up — `pr-147` has no counterpart in
45`shared-infra`.
46
47## Depend on a Stack's outputs
48
49When the unit you consume is a whole Stack, import its tag and
50yield it:
51
52```typescript
53// backend/src/Stack.ts
54export class Backend extends Alchemy.Stack<
55 Backend,
56 { url: string }
57>()("Backend") {}
58```
59
60```typescript
61// inside the frontend Stack's Effect.gen
62const a = yield* Backend; // current stage
63const b = yield* Backend.stage.prod; // pinned to "prod"
64const c = yield* Backend.stage["pr-42"]; // any stage name
65```
66
67Every successful `apply` persists what the Stack's effect returned
68as a per-stage output record; `yield* Backend` reads it back as a
69proxy of typed Outputs, so `(yield* Backend).url` is
70`Output<string>`. Full two-package walkthrough:
71[Multiple Stacks](/project-structure/monorepo-multi-stack).
72
73## Escape hatches
74
75When the Resource constructor isn't in scope, `Output.ref` is the
76same lookup:
77
78```typescript
79const bucket = Output.ref<typeof Bucket>("Bucket", {
80 stack: "shared-infra",
81 stage: "prod",
82});
83```
84
85When a typed Stack handle isn't in scope, `Output.stackRef` reads
86the output record directly:
87
88```typescript
89const backend = yield* Output.stackRef<{ url: string }>("Backend", {
90 stage: "prod",
91});
92```
93
94Prefer `Resource.ref` and `yield* MyStack` — same lookups, real
95type bindings.
96
97## Deploy order
98
99The upstream must already be deployed to the exact
100`{ stack, stage }` the reference names, or the plan fails fast
101with a typed `InvalidReferenceError` — there is no
102deploy-and-hope path:
103
104```sh
105alchemy deploy --stage staging # creates app-db
106alchemy deploy --stage pr-147 # borrows staging's app-db
107```
108
109Destroy in reverse order. Resolution itself is the in-stack
110[Output](/infrastructure-as-code/outputs) flow with one difference: a reference's
111upstream was reconciled by a previous deploy, so only its persisted
112attributes participate in this plan.
113
114## Where next
115
116- [Resource Lifecycle](/infrastructure-as-code/resource-lifecycle) — how
117 the referenced state got persisted in the first place. Next page.
118- [Multiple Stacks](/project-structure/monorepo-multi-stack) — typed Stack
119 handles wiring a monorepo.
120- [Shared database across stages](/cloudflare/data/shared-database) —
121 the owner/borrower pattern end to end.
122- [Inputs & Outputs](/infrastructure-as-code/outputs) — the Output model
123 references plug into.
124- [State Store](/state-store) — where the persisted state
125 that refs read lives.