The TypeScript SDK (@palantir/compute-module) for compute modules enables you to build deployed functions using TypeScript or JavaScript. The SDK provides type-safe function registration with schema validation, structured logging, and utilities for working with Foundry resources.
The TypeScript SDK provides:
ComputeModule: Main class for creating and registering functionsSlsLogger: Structured logging in SLS formatType (from @sinclair/typebox): Runtime type validation and schema generationInstall the SDK using npm or yarn:
Copied!1npm install @palantir/compute-module
Copied!1yarn add @palantir/compute-module
Register functions using vanilla JavaScript:
Copied!1 2 3 4 5 6import { ComputeModule } from "@palantir/compute-module"; new ComputeModule() .register("addOne", async ({ value }) => ({ value: value + 1 })) .register("stringify", async ({ n }) => "" + n) .default(() => ({ error: "Unsupported query name" }));
Use TypeBox ↗ for type-safe function registration with automatic schema inference:
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16import { ComputeModule, SlsLogger } from "@palantir/compute-module"; import { Type } from "@sinclair/typebox"; const myModule = new ComputeModule({ logger: new SlsLogger(), definitions: { addOne: { input: Type.Object({ value: Type.Number(), }), output: Type.Object({ value: Type.Number() }), }, }, }); myModule.register("addOne", async ({ value }) => ({ value: value + 1 }));
Benefits of schema registration:
For large result sets, use streaming to send data progressively:
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18import { ComputeModule } from "@palantir/compute-module"; import { Type } from "@sinclair/typebox"; const computeModule = new ComputeModule({ definitions: { greet: { input: Type.Object({ name: Type.String() }), output: Type.Array(Type.String()), }, }, }); // Each write must produce valid JSON computeModule.registerStreaming("greet", async ({ name }, writeable) => { writeable.write(JSON.stringify("Hello, ")); writeable.write(JSON.stringify(name)); writeable.end(); });
Streaming with complex types:
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23const User = Type.Object({ name: Type.String(), role: Type.String(), active: Type.Boolean(), }); const computeModule = new ComputeModule({ definitions: { activeUsers: { input: Type.Object({ users: Type.Array(User) }), output: Type.Array(User), }, }, }); computeModule.registerStreaming("activeUsers", async ({ users }, writeable) => { for (const user of users) { if (user.active) { writeable.write(JSON.stringify(user)); } } writeable.end(); });
The output type must be declared as Type.Array(...) for streaming. Each write() call must produce valid JSON.
Use SlsLogger for structured logging in Standard Logging Specification (SLS) format:
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19import { ComputeModule, SlsLogger } from "@palantir/compute-module"; import { Type } from "@sinclair/typebox"; const logger = new SlsLogger(); const myModule = new ComputeModule({ logger, definitions: { addOne: { input: Type.Object({ value: Type.Number() }), output: Type.Object({ value: Type.Number() }), }, }, }); myModule.register("addOne", async ({ value }) => { logger.info("Processing addOne", { input_value: String(value) }); return { value: value + 1 }; });
Log methods:
logger.debug(message, params?) - Debug-level logslogger.info(message, params?) - Info-level logslogger.warn(message, params?) - Warning logslogger.error(message, params?) - Error logsCustom key-value pairs can be passed as the second argument and will be added to the log entry's parameters.
Alternatively, any object with log, info, warn, and error methods (for example, console) can be used as a logger.
Learn more about debugging and viewing logs.
In Pipeline mode, access configured inputs and outputs using resource aliases:
Copied!1 2 3 4import { ComputeModule } from "@palantir/compute-module"; const resourceId = ComputeModule.getResource("myResourceAlias"); const result = await someDataFetcherForId(resourceId);
Retrieve execution environment details:
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13import { ComputeModule } from "@palantir/compute-module"; const environment = ComputeModule.getEnvironment(); // Pipeline mode const buildToken = environment.type === "pipelines" ? environment.buildToken : undefined; // Functions mode const thirdPartyAppCredentials = environment.type === "functions" ? environment.thirdPartyApplication : undefined;
Learn more about execution modes.
Access source credentials for external system authentication:
Copied!1const myCredential = myModule.getCredential("MySourceApiName", "MyCredential");
Declare and validate sources in the module configuration:
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17const myModule = new ComputeModule({ sources: { MyApi: { credentials: ["MyCredential"] }, AnotherApi: {} // Validates source exists, but not specific credentials } }); // ✅ Passes type checking myModule.getCredential("MyApi", "MyCredential"); // ❌ Will throw a type error myModule.getCredential("YourApi", "YourCredential"); // ✅ Any credential name works for sources without declared credentials myModule.getCredential("AnotherApi", "AnyString");
Validation: If sources are declared, the module validates them at startup and provides compile-time type safety. Without declaration, no validation occurs.
Learn more about configuring sources.
Access Foundry service API endpoints:
Copied!1 2 3import { FoundryService } from "@palantir/compute-module"; const streamProxyApi = myModule.getServiceApi(FoundryService.STREAM_PROXY);
This allows calling Foundry endpoints without configuring a source for platform ingress.
Copied!1 2 3 4 5 6 7 8 9 10FROM node:18-alpine WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci --production COPY src . # USER is required to be non-root and numeric USER 5000 CMD ["node", "index.js"]
Learn more about container configuration.
The TypeScript SDK is open source and available on GitHub: