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:

index.ts
import { TodoCore } from "todo/core.js";
import { todosCreate } from "todo/funcs/todosCreate.js";

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):

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:

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.

Info Icon

NOTE

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’s significant value in capturing most errors and converting them into values.

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:

log-something.ts
import { Core } from "<sdk-package-name>";
import { fetchSomething } from "<sdk-package-name>/funcs/fetchSomething.js";
const client = new Core();
async function run() {
const result = await fetchSomething(client, { id: "123" });
if (!result.ok) {
// You can throw the error or handle it. It's your choice now.
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.