> ## Documentation Index
> Fetch the complete documentation index at: https://namespace.so/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Run commands on an instance

> Run commands on a running Namespace compute instance with the TypeScript SDK.

`client.command` runs a command on a running instance. Use `runCommand()` to stream output as it is produced, or `runCommandSync()` to wait for the command to finish and read its combined output.

The examples on this page use a Compute client:

```typescript theme={null}
import { createComputeClient } from "@namespacelabs/sdk/api/compute";

const client = createComputeClient();
```

Both methods take an optional `targetContainerName`. Set it to run the command in that container, which must already be running on the instance. See [Create and manage compute instances](/docs/reference/typescript-sdk/compute/manage) to start containers at creation time. Omit it to run the command directly in the guest, as macOS instances do.

## `command.runCommand()`

Run a command and stream its output. Stdout and stderr arrive as individual responses. The final response carries an `exitStatus` with the command's exit code.

<h3 id="command-runcommand-example">
  Example
</h3>

```typescript {3-7} theme={null}
const decoder = new TextDecoder();

for await (const response of client.command.runCommand({
  instanceId,
  targetContainerName: "app",
  command: { command: ["ls", "-la"], cwd: "/srv" },
})) {
  if (response.exitStatus) {
    console.log(`exited with ${response.exitStatus.exitCode}`);
  } else {
    process.stdout.write(decoder.decode(response.data));
  }
}
```

<h3 id="command-runcommand-api-reference">
  API reference
</h3>

```typescript theme={null}
runCommand(
  request: MessageInitShape<typeof RunCommandRequestSchema>,
  options?: CallOptions,
): AsyncIterable<RunCommandResponse>
```

<h4 id="command-runcommand-arguments-and-options">
  Arguments and options
</h4>

<ResponseField name="instanceId" type="string" required>
  The instance the command runs on.
</ResponseField>

<ResponseField name="targetContainerName" type="string">
  The name of the container to run the command in. When omitted, the command runs directly in the guest.
</ResponseField>

<ResponseField name="command" type="Command" required>
  The command to execute.

  <Expandable title="properties" defaultOpen>
    <ResponseField name="command" type="string[]" required>
      The command and its arguments, such as `["ls", "-la"]`.
    </ResponseField>

    <ResponseField name="envVars" type="EnvironmentVariable[]">
      Environment variables to set for the command. Each entry has a `name` and either a `value` or a `fromSecretId`.
    </ResponseField>

    <ResponseField name="cwd" type="string">
      The working directory for the command.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="options" type="CallOptions">
  Cancellation, timeout, and header options. See [Shared call options](/docs/reference/typescript-sdk/compute/manage#shared-call-options).
</ResponseField>

<h4 id="command-runcommand-return-value">
  Return value
</h4>

Returns an async iterable of `RunCommandResponse`.

<ResponseField name="stream" type="RunCommandResponse_Stream">
  The output stream the chunk belongs to: `STDOUT`, `STDERR`, or `STREAM_UNKNOWN`.
</ResponseField>

<ResponseField name="data" type="Uint8Array">
  A chunk of output data. Decode it with a `TextDecoder` for text output.
</ResponseField>

<ResponseField name="exitStatus" type="RunCommandResponse_ExitStatus">
  Set only on the last message in the stream. Carries the command's `exitCode`.
</ResponseField>

If the instance does not exist, the call fails with `NotFound`. The same applies when `targetContainerName` is set and no such container exists.

***

## `command.runCommandSync()`

Run a command and wait for it to complete. Stdout and stderr are buffered and returned in a single response.

<h3 id="command-runcommandsync-example">
  Example
</h3>

```typescript {3-7} theme={null}
const decoder = new TextDecoder();

const result = await client.command.runCommandSync({
  instanceId,
  targetContainerName: "app",
  command: { command: ["sh", "-c", "npm test"] },
});

console.log(decoder.decode(result.stdout));

if (result.exitCode !== 0) {
  console.error(decoder.decode(result.stderr));
}
```

<h3 id="command-runcommandsync-api-reference">
  API reference
</h3>

```typescript theme={null}
runCommandSync(
  request: MessageInitShape<typeof RunCommandRequestSchema>,
  options?: CallOptions,
): Promise<RunCommandSyncResponse>
```

<h4 id="command-runcommandsync-arguments-and-options">
  Arguments and options
</h4>

`runCommandSync()` takes the same `RunCommandRequest` as [`runCommand()`](#command-runcommand-arguments-and-options).

<ResponseField name="options" type="CallOptions">
  Cancellation, timeout, and header options. See [Shared call options](/docs/reference/typescript-sdk/compute/manage#shared-call-options).
</ResponseField>

<h4 id="command-runcommandsync-return-value">
  Return value
</h4>

Returns a `RunCommandSyncResponse`.

<ResponseField name="stdout" type="Uint8Array">
  The combined stdout output.
</ResponseField>

<ResponseField name="stderr" type="Uint8Array">
  The combined stderr output.
</ResponseField>

<ResponseField name="exitCode" type="number">
  The exit code of the command.
</ResponseField>

If the instance does not exist, the call fails with `NotFound`. The same applies when `targetContainerName` is set and no such container exists.

<Info>
  The whole command runs within a single RPC. Raise `timeoutMs` in the call options for long-running commands, or use `runCommand()` and consume output as it arrives.
</Info>

## Related documentation

<Columns cols={2}>
  <Card title="Create and manage instances" icon="server" href="/docs/reference/typescript-sdk/compute/manage">
    Create instances and start the containers commands run in.
  </Card>

  <Card title="Instance logs" icon="scroll-text" href="/docs/reference/typescript-sdk/compute/observability">
    Stream and fetch logs from an instance.
  </Card>
</Columns>
