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(); });
Important: 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.
Alternative: 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: