> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/solana-foundation/anchor/llms.txt
> Use this file to discover all available pages before exploring further.

# Workspace

> Automatically load programs from your Anchor workspace

## Overview

The `workspace` object provides a convenient way to automatically load and access Anchor programs defined in your workspace. It searches for compiled IDLs in the `target/idl` directory and creates `Program` instances on demand.

<Warning>
  The `workspace` API is only available in Node.js environments, not in browsers.
</Warning>

## Usage

```typescript theme={null}
import * as anchor from "@anchor-lang/anchor";
import { Program } from "@anchor-lang/anchor";
import { MyProgram } from "./target/types/my_program";

// Access program from workspace
const program = anchor.workspace.MyProgram as Program<MyProgram>;

// TypeScript types are automatically inferred
const tx = await program.methods.initialize().rpc();
```

## How It Works

The workspace object uses a JavaScript `Proxy` to dynamically load programs when accessed:

1. **IDL Discovery**: Searches the `target/idl` directory for matching IDL files
2. **Name Matching**: Converts the property name to camelCase and matches against IDL filenames
3. **Program Creation**: Automatically creates a `Program` instance with the loaded IDL
4. **Caching**: Caches loaded programs for subsequent access

## Workspace Type

```typescript theme={null}
type Workspace = {
  [programName: string]: Program;
};
```

The workspace acts as a dictionary where keys are program names (in any case format) and values are `Program` instances.

## Program Name Resolution

The workspace converts program names to camelCase for flexible access:

```typescript theme={null}
// All of these access the same program:
anchor.workspace.myProgram
anchor.workspace.MyProgram
anchor.workspace["my-program"]
anchor.workspace["my_program"]
```

## Configuration

### Anchor.toml Override

You can override workspace program locations in `Anchor.toml`:

```toml theme={null}
[provider]
cluster = "localnet"

[programs.localnet]
my_program = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"

# Override IDL location
[programs.localnet.my_program]
idl = "./custom/path/to/idl.json"
address = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"
```

### Default Behavior

Without configuration overrides, the workspace:

* Reads IDL files from `target/idl/`
* Matches filenames against the requested program name (after converting both to camelCase)
* Uses the program address specified in the IDL's `address` field

## Properties

<ResponseField name="[programName]" type="Program">
  Access a program by name. The name is case-insensitive and can use any format.

  ```typescript theme={null}
  const program = anchor.workspace.MyProgram;
  ```
</ResponseField>

## Error Handling

### Browser Environment

Attempting to use workspace in a browser throws an error:

```typescript theme={null}
// Error: Workspaces aren't available in the browser
const program = anchor.workspace.MyProgram;
```

### IDL Not Found

If no matching IDL file is found:

```typescript theme={null}
// Error: Failed to find IDL of program `myProgram`
const program = anchor.workspace.NonExistent;
```

### IDL File Missing

If the IDL path doesn't exist:

```typescript theme={null}
// Error: target/idl/my_program.json doesn't exist. 
// Did you run `anchor build`?
const program = anchor.workspace.MyProgram;
```

## Usage Examples

### Basic Test Setup

```typescript theme={null}
import * as anchor from "@anchor-lang/anchor";
import { Program } from "@anchor-lang/anchor";
import { MyProgram } from "../target/types/my_program";
import { assert } from "chai";

describe("my-program", () => {
  // Configure the client to use the local cluster
  anchor.setProvider(anchor.AnchorProvider.env());

  const program = anchor.workspace.MyProgram as Program<MyProgram>;

  it("initializes", async () => {
    const tx = await program.methods.initialize().rpc();
    console.log("Transaction signature:", tx);
  });
});
```

### Multiple Programs

```typescript theme={null}
import * as anchor from "@anchor-lang/anchor";

const tokenProgram = anchor.workspace.TokenProgram;
const nftProgram = anchor.workspace.NftProgram;
const stakingProgram = anchor.workspace.StakingProgram;

// All programs share the same provider
const provider = anchor.getProvider();
```

### Type-Safe Access

```typescript theme={null}
import { Program } from "@anchor-lang/anchor";
import { MyProgram } from "../target/types/my_program";

// TypeScript knows all available methods and accounts
const program = anchor.workspace.MyProgram as Program<MyProgram>;

// Autocomplete works for instruction names
const tx = await program.methods
  .initialize()
  .accounts({
    // Autocomplete works for account names
    myAccount: myAccountPubkey,
  })
  .rpc();

// Autocomplete works for account types
const account = await program.account.myAccount.fetch(address);
console.log(account.balance); // Type-safe access to fields
```

### Testing with Multiple Clusters

```typescript theme={null}
import * as anchor from "@anchor-lang/anchor";
import { Program } from "@anchor-lang/anchor";
import { MyProgram } from "../target/types/my_program";

describe("my-program", () => {
  let program: Program<MyProgram>;

  before(async () => {
    // Set up provider for desired cluster
    const provider = anchor.AnchorProvider.local();
    anchor.setProvider(provider);

    // Load program from workspace
    program = anchor.workspace.MyProgram;
  });

  it("works on localnet", async () => {
    const tx = await program.methods.initialize().rpc();
    assert.ok(tx);
  });
});
```

### Custom IDL Path

For programs with custom IDL locations specified in `Anchor.toml`:

```toml theme={null}
# Anchor.toml
[programs.localnet.my_program]
idl = "./idls/custom_location.json"
address = "YourProgramAddress"
```

```typescript theme={null}
// Still access the same way
const program = anchor.workspace.MyProgram;

// The workspace automatically uses the custom IDL path
```

### Accessing Program Properties

```typescript theme={null}
const program = anchor.workspace.MyProgram;

// Program ID from IDL
console.log("Program ID:", program.programId.toString());

// Provider connection
console.log("Cluster:", program.provider.connection.rpcEndpoint);

// IDL metadata
console.log("Instructions:", program.idl.instructions.map(i => i.name));
console.log("Accounts:", program.idl.accounts?.map(a => a.name));
```

## Integration with Anchor CLI

The workspace object is designed to work seamlessly with the Anchor CLI workflow:

```bash theme={null}
# Build programs and generate IDLs
anchor build

# IDLs are output to target/idl/
# TypeScript types are output to target/types/

# Run tests that use workspace
anchor test
```

## Best Practices

<AccordionGroup>
  <Accordion title="Always Type Your Programs">
    Use the generated TypeScript types for type safety:

    ```typescript theme={null}
    // Good - type-safe
    const program = anchor.workspace.MyProgram as Program<MyProgram>;

    // Bad - no type checking
    const program = anchor.workspace.MyProgram;
    ```
  </Accordion>

  <Accordion title="Run anchor build First">
    Ensure your programs are built before accessing the workspace:

    ```bash theme={null}
    anchor build
    anchor test
    ```
  </Accordion>

  <Accordion title="Use in Tests, Not Production">
    The workspace is ideal for testing but shouldn't be used in production clients:

    ```typescript theme={null}
    // Good - test environment
    describe("tests", () => {
      const program = anchor.workspace.MyProgram;
    });

    // Bad - production app
    // Use explicit Program constructor instead
    const program = new Program(idl, provider);
    ```
  </Accordion>

  <Accordion title="Handle Missing Programs Gracefully">
    Check if a program exists before using it:

    ```typescript theme={null}
    try {
      const program = anchor.workspace.MyProgram;
      // Use program...
    } catch (error) {
      console.error("Program not found. Run 'anchor build' first.");
    }
    ```
  </Accordion>
</AccordionGroup>
