# Standalone Functions

## Feature Overview

Every method in TypeScript SDKs generated by Speakeasy is also available as a
standalone function. This alternative API is ideal for browser or serverless
environments, where bundlers can optimize applications by tree-shaking unused
functionality. This includes unused methods, Zod schemas, encoding helpers, and
response handlers. As a result, the application's final bundle size is
dramatically smaller and grows very gradually as more of the generated SDK is
used.

Using methods through the main SDK class remains a valid and generally more
ergonomic option. Standalone functions are an optimization designed for specific
types of applications.

## Usage

**Step 1: Import the Core Class and Function**

First, import the `Core` SDK class for authentication and setup, along with the
required standalone function. An SDK named `Todo`, for example, might look like
this:

```typescript filename="index.ts"

```

The `Core` SDK class is optimized for tree-shaking, and can be reused throughout
the application.

**Step 2: Instantiate the Core Class**

Create an instance of the `Core` class with the required configuration (e.g., an
API Key):

```typescript filename="index.ts"
const todoSDK = new TodoCore({
  apiKey: "TODO_API_KEY",
});
```

**Step 3: Call the Standalone Function & Handle the Result**

Invoke the standalone function, passing the core instance the first parameter.
Handle the result using a switch statement for comprehensive error handling:

```typescript filename="index.ts"
async function run() {
  const res = await todosCreate(todoSDK);

  switch (true) {
    case res.ok:
      // Successful response is processed later.
      break;
    case res.error instanceof SDKValidationError:
      // Display validation errors in a readable format.
      return console.log(res.error.pretty());
    case res.error instanceof Error:
      // Handle general errors.
      return console.log(res.error);
    default:
      // Ensure all error cases are exhaustively handled.
      res.error satisfies never;
      throw new Error("Unexpected error case: " + res.error);
  }

  const { value: todo } = res;

  // Handle the successful result.
  console.log(todo);
}

run();
```

## Result Types

Standalone functions differ from SDK methods in that they return a
`Result<Value, Error>` type to capture _known errors_ and document them through
the type system. This approach avoids throwing errors, allowing application code
to maintain clear control flow while making error handling a natural part of the
application code.

<Callout title="Note" type="info">
  The term **"known errors"** is used because standalone functions and
  JavaScript code can still throw unexpected errors (e.g., `TypeError`,
  `RangeError`, and `DOMException`). While exhaustively catching all errors may
  be addressed in future SDK versions, there&apos;s significant value in capturing
  most errors and converting them into values.
</Callout>

Another reason for this programming style is that these functions are commonly
used in front-end applications where throwing exceptions is often discouraged.
React and similar frameworks promote this approach to ensure components can
render appropriate content in all states—loading, success, and error.

Thus, the general pattern when calling standalone functions looks like this:

```typescript filename="log-something.ts"

const client = new Core();

async function run() {
  const result = await fetchSomething(client, { id: "123" });

  if (!result.ok) {
    // Either throw the error or handle it based on application requirements.
    throw result.error;
  }

  console.log(result.value);
}

run();
```

Note that, unlike a try-catch block where errors are of type `unknown` (or `any`
depending on TypeScript settings), `result.error` in this example has a
specific, explicit type.
