Skip to main content

Migrate from node-bt

Use this guide to replace an existing node-bt Reactor or Proxy code transform with a Node.js runtime image. Migrate away from the node-bt runtime as soon as possible to avoid disruption.

We recommend creating a replacement Reactor or Proxy resource and moving traffic only after it passes your tests. Keeping the existing node-bt resource unchanged gives you a direct rollback path during the cutover.

1. Translate the Runtime Configuration

Choose a Node.js runtime image. The available images share the same runtime options, provisioning states, code contracts, and security controls. Match the image to the Node.js version used to develop and test your code.

Translate the legacy resource settings as follows:

node-bt settingNode.js runtime replacement
Missing runtime or runtime.image: "node-bt"Set runtime.image to a Node.js runtime image.
Packages from the node-bt whitelistAdd every package used by the code to runtime.dependencies with an exact pinned version. Use runtime.resolutions only when overriding a transitive dependency.
Linked application.id used for Basis Theory API accessAdd only the required permissions to runtime.permissions, then initialize your API client from event.applicationOptions.
Linked Application ID used as a value in your own logicStore the value in the resource configuration and read it from event.configuration. This does not grant the linked Application's permissions or reproduce its API key.
Fixed runtime behaviorConfigure timeout, resources, and warm concurrency for the workload.
Legacy asynchronous Reactor using callback_urlSet runtime.async: true, invoke the Reactor through /react-async, and retrieve the result with the returned request ID.

runtime.permissions grants direct permissions to the runtime. It does not copy Access Rules from a linked Application. If the legacy Application relies on Access Rules, contact support@basistheory.com to review the authorization design before cutting over.

If the legacy code uses the Basis Theory SDK, declare @basis-theory/node-sdk as a runtime dependency. Replace the legacy req.bt client with a client initialized from the runtime credentials:

const { BasisTheoryClient } = require("@basis-theory/node-sdk");

module.exports = async function (event) {
const { applicationOptions } = event;

const client = new BasisTheoryClient({
apiKey: applicationOptions.apiKey,
baseUrl: applicationOptions.baseUrl,
});

// Use client.tokens or another API client here.
return {
res: {
body: { ready: true }
}
};
};

2. Translate the Code Contract

The supported Node.js images use an event-based contract. Update each legacy input and output used by the code.

Reactor Code

node-bt contractNode.js runtime contract
req.argsevent.req
req.configurationevent.configuration
req.btInitialize @basis-theory/node-sdk from event.applicationOptions.apiKey and event.applicationOptions.baseUrl.
return { raw: value }return { res: { body: value } }
return { tokenize: value }Create the token explicitly with the Node.js SDK, then include the token result you need in res.body. Add token:create to runtime.permissions.
Application loggingUse event.logger.info(), event.logger.warn(), or event.logger.error().

See the complete Reactor code contract, including response headers and status codes.

module.exports = async function (event) {
const { req, configuration, logger } = event;

logger.info("Processing request");

return {
res: {
body: {
customer_id: req.customer_id,
service: configuration.SERVICE_NAME,
processed: true
},
statusCode: 200
}
};
};

Proxy Code Transforms

node-bt contractNode.js runtime contract
Request transform input at req.argsevent.req
Response transform input at req.argsevent.res
Request transform returns { body, headers }Return { req: { body, headers } }.
Response transform returns { body, headers }Return { res: { body, headers } }. You can also set res.statusCode.
Throw CustomHttpResponseError to skip the destinationReturn { res: { body, headers, statusCode } } from the request transform.

See the complete Proxy request transform contract, response transform contract, and skip request behavior.

module.exports = async function (event) {
const { body, headers } = event.req;

return {
req: {
body,
headers: {
...headers,
"X-Processed-By": "Basis Theory"
}
}
};
};

3. Create the Replacement Resource

Create the replacement with the translated code and runtime configuration:

  • For a Reactor, use the Create Reactor API and copy the existing name and configuration values that still apply.
  • For a Proxy, use the Create Proxy API. Copy the destination, authentication setting, configuration, and non-code transforms that still apply. Add the translated runtime options to each code transform.

The replacement receives a new Reactor ID or Proxy key. Save that identifier for the cutover.

Creating a resource with a Node.js runtime image provisions it asynchronously. Wait until its state is active before invoking it. If provisioning fails, inspect the resource's requested object for the deployment error.

4. Validate the Replacement

Exercise the replacement without changing production traffic:

  1. Test successful requests and the error paths expected by callers.
  2. Compare the body, headers, and status code with the legacy behavior.
  3. Confirm every Basis Theory API call succeeds with the configured runtime permissions.
  4. For a Proxy, confirm the destination receives the expected request and the caller receives the expected response.
  5. For an asynchronous Reactor, verify invocation, result retrieval, webhook handling, partial results, failures, and timeouts.

5. Cut Over with a Rollback Path

After validation:

  • For a Reactor, update callers to use the replacement Reactor ID.
  • For a Proxy, update callers to send the replacement value in the BT-PROXY-KEY header or corresponding SDK option.

Monitor the replacement after the cutover. Keep the node-bt resource unchanged until you are confident the migration is stable. If an issue occurs, restore the previous Reactor ID or Proxy key to move traffic back.

6. Delete the Legacy Resource

Delete the old resource only after all callers use the replacement and the rollback period is complete. Use the Delete Reactor or Delete Proxy API.

If you need help translating a legacy contract or authorization model, contact support@basistheory.com.