customerio-upgrade-migration
Plan and execute Customer.io SDK upgrades and migrations. Use when upgrading customerio-node versions, migrating from legacy APIs, or updating to new SDK patterns. Trigger: "upgrade customer.io", "customer.io migration", "update customer.io sdk", "customer.io breaking changes".
Best use case
customerio-upgrade-migration is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Plan and execute Customer.io SDK upgrades and migrations. Use when upgrading customerio-node versions, migrating from legacy APIs, or updating to new SDK patterns. Trigger: "upgrade customer.io", "customer.io migration", "update customer.io sdk", "customer.io breaking changes".
Teams using customerio-upgrade-migration should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/customerio-upgrade-migration/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How customerio-upgrade-migration Compares
| Feature / Agent | customerio-upgrade-migration | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Plan and execute Customer.io SDK upgrades and migrations. Use when upgrading customerio-node versions, migrating from legacy APIs, or updating to new SDK patterns. Trigger: "upgrade customer.io", "customer.io migration", "update customer.io sdk", "customer.io breaking changes".
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Customer.io Upgrade & Migration
## Current State
!`npm list customerio-node 2>/dev/null | grep customerio || echo 'customerio-node: not installed'`
!`npm view customerio-node version 2>/dev/null || echo 'Cannot check latest version'`
## Overview
Plan and execute `customerio-node` SDK upgrades safely: assess current version, review breaking changes, apply code migrations, and validate with staged rollout.
## Prerequisites
- Current SDK version identified (`npm list customerio-node`)
- Test environment available
- Version control for rollback
## Major Version Migration Reference
### Legacy `CustomerIO` to Modern `TrackClient` + `APIClient`
Older versions of `customerio-node` used a single `CustomerIO` class. Modern versions split into `TrackClient` (tracking) and `APIClient` (transactional/broadcasts).
```typescript
// BEFORE — Legacy pattern (customerio-node < 2.x)
const CustomerIO = require("customerio-node");
const cio = new CustomerIO(siteId, apiKey);
cio.identify("user-1", { email: "user@example.com" });
cio.track("user-1", { name: "event_name" });
// AFTER — Modern pattern (customerio-node >= 2.x)
import { TrackClient, APIClient, RegionUS } from "customerio-node";
const cio = new TrackClient(siteId, apiKey, { region: RegionUS });
await cio.identify("user-1", { email: "user@example.com" });
await cio.track("user-1", { name: "event_name", data: {} });
const api = new APIClient(appApiKey, { region: RegionUS });
await api.sendEmail(request);
```
**Key changes:**
- `TrackClient` replaces `CustomerIO` for identify/track
- `APIClient` is new — handles transactional + broadcasts
- Region is now explicit (`RegionUS` or `RegionEU`)
- Methods return Promises (must `await`)
- Event tracking uses `{ name, data }` object instead of positional args
## Instructions
### Step 1: Assess Current Version
```typescript
// scripts/cio-version-check.ts
import { readFileSync, existsSync } from "fs";
function assessVersion() {
// Check installed version
const lockPath = "package-lock.json";
if (existsSync(lockPath)) {
const lock = JSON.parse(readFileSync(lockPath, "utf-8"));
const installed =
lock.packages?.["node_modules/customerio-node"]?.version ??
lock.dependencies?.["customerio-node"]?.version ??
"not found in lockfile";
console.log(`Installed: customerio-node@${installed}`);
}
// Check package.json declared version
const pkg = JSON.parse(readFileSync("package.json", "utf-8"));
const declared = pkg.dependencies?.["customerio-node"] ?? "not declared";
console.log(`Declared: ${declared}`);
// Search for usage patterns
console.log("\nUsage pattern check:");
console.log("- Look for 'new CustomerIO(' → legacy pattern, needs migration");
console.log("- Look for 'new TrackClient(' → modern pattern");
console.log("- Look for 'RegionUS/RegionEU' → region-aware (good)");
}
assessVersion();
```
### Step 2: Review Breaking Changes
```typescript
// Common breaking changes between major versions:
// v1.x → v2.x:
// - CustomerIO class → TrackClient + APIClient
// - Callbacks → Promises (async/await)
// - Region parameter added (defaults to US)
// - SendEmailRequest constructor changed
// v2.x → v3.x:
// - Import path may change
// - TypeScript types improved
// - Error object structure may change
// Always check the official changelog:
// https://github.com/customerio/customerio-node/blob/main/CHANGELOG.md
```
### Step 3: Create Migration Wrapper
```typescript
// lib/customerio-migration.ts
// Adapter that supports both old and new patterns during migration
import { TrackClient, APIClient, RegionUS } from "customerio-node";
export class CioMigrationClient {
private trackClient: TrackClient;
private apiClient: APIClient | null;
constructor(config: {
siteId: string;
trackApiKey: string;
appApiKey?: string;
region?: "us" | "eu";
}) {
const region = config.region === "eu"
? (await import("customerio-node")).RegionEU
: RegionUS;
this.trackClient = new TrackClient(config.siteId, config.trackApiKey, {
region,
});
this.apiClient = config.appApiKey
? new APIClient(config.appApiKey, { region })
: null;
}
// Legacy-compatible identify (accepts both old and new signatures)
async identify(userId: string, attrs: Record<string, any>): Promise<void> {
// Ensure timestamps are in seconds, not milliseconds
if (attrs.created_at && attrs.created_at > 1e12) {
attrs.created_at = Math.floor(attrs.created_at / 1000);
}
await this.trackClient.identify(userId, attrs);
}
// Legacy-compatible track (normalizes data format)
async track(
userId: string,
eventOrOpts: string | { name: string; data?: Record<string, any> },
data?: Record<string, any>
): Promise<void> {
if (typeof eventOrOpts === "string") {
// Legacy: track("user", "event_name", { key: "value" })
await this.trackClient.track(userId, {
name: eventOrOpts,
data: data ?? {},
});
} else {
// Modern: track("user", { name: "event_name", data: {} })
await this.trackClient.track(userId, eventOrOpts);
}
}
get app(): APIClient {
if (!this.apiClient) {
throw new Error("App API key not configured");
}
return this.apiClient;
}
}
```
### Step 4: Update and Test
```bash
# Update to latest version
npm install customerio-node@latest
# Run your test suite
npm test
# Run integration tests against dev workspace
npx dotenv -e .env.development -- npx vitest run tests/customerio
```
### Step 5: Migration Test Suite
```typescript
// tests/cio-migration.test.ts
import { describe, it, expect } from "vitest";
import { TrackClient, APIClient, RegionUS } from "customerio-node";
const cio = new TrackClient(
process.env.CUSTOMERIO_SITE_ID!,
process.env.CUSTOMERIO_TRACK_API_KEY!,
{ region: RegionUS }
);
describe("Post-migration validation", () => {
const testId = `migration-test-${Date.now()}`;
it("identify works with new client", async () => {
await expect(
cio.identify(testId, {
email: `${testId}@test.example.com`,
created_at: Math.floor(Date.now() / 1000),
})
).resolves.not.toThrow();
});
it("track works with object format", async () => {
await expect(
cio.track(testId, { name: "migration_test", data: { version: "new" } })
).resolves.not.toThrow();
});
it("suppress and destroy work", async () => {
await cio.suppress(testId);
await expect(cio.destroy(testId)).resolves.not.toThrow();
});
});
```
### Step 6: Staged Rollout with Feature Flag
```typescript
// Use feature flag to gradually migrate traffic
import { createHash } from "crypto";
function useNewSdk(userId: string, rolloutPercent: number): boolean {
const hash = createHash("md5").update(`cio-migration-${userId}`).digest("hex");
return parseInt(hash.substring(0, 8), 16) % 100 < rolloutPercent;
}
// In your application code:
if (useNewSdk(userId, 10)) {
// New SDK path
await newClient.identify(userId, attrs);
} else {
// Legacy SDK path (until migration complete)
await legacyClient.identify(userId, attrs);
}
```
## Migration Checklist
- [ ] Current version documented
- [ ] Target version identified
- [ ] Breaking changes reviewed (CHANGELOG.md)
- [ ] Code changes implemented (TrackClient, region, async/await)
- [ ] Unit tests passing
- [ ] Integration tests passing against dev workspace
- [ ] Staging deployment successful
- [ ] Feature flag for staged rollout ready
- [ ] Rollback plan documented (pin old version in package.json)
- [ ] Team notified of migration timeline
## Error Handling
| Issue | Solution |
|-------|----------|
| `TrackClient is not a constructor` | Old import style — use `import { TrackClient } from "customerio-node"` |
| `region is not defined` | Import `RegionUS` or `RegionEU` from `customerio-node` |
| Methods not returning Promises | Upgrade to latest — old versions used callbacks |
| `TypeError: cio.track is not a function` | Using `APIClient` instead of `TrackClient` for tracking |
## Resources
- [customerio-node CHANGELOG](https://github.com/customerio/customerio-node/blob/main/CHANGELOG.md)
- [customerio-node Releases](https://github.com/customerio/customerio-node/releases)
- [npm customerio-node](https://www.npmjs.com/package/customerio-node)
## Next Steps
After successful migration, proceed to `customerio-ci-integration` for CI/CD setup.Related Skills
sql-migration-generator
Sql Migration Generator - Auto-activating skill for Backend Development. Triggers on: sql migration generator, sql migration generator Part of the Backend Development skill category.
managing-database-migrations
Process use when you need to work with database migrations. This skill provides schema migration management with comprehensive guidance and automation. Trigger with phrases like "create migration", "run migrations", or "manage schema versions".
exa-upgrade-migration
Upgrade exa-js SDK versions and handle breaking changes safely. Use when upgrading the Exa SDK, detecting deprecations, or migrating between exa-js versions. Trigger with phrases like "upgrade exa", "exa update", "exa breaking changes", "update exa-js", "exa new version".
exa-migration-deep-dive
Migrate from other search APIs (Google, Bing, Tavily, Serper) to Exa neural search. Use when switching to Exa from another search provider, migrating search pipelines, or evaluating Exa as a replacement for traditional search APIs. Trigger with phrases like "migrate to exa", "switch to exa", "replace google search with exa", "exa vs tavily", "exa migration", "move to exa".
evernote-upgrade-migration
Upgrade Evernote SDK versions and migrate between API versions. Use when upgrading SDK, handling breaking changes, or migrating to newer API patterns. Trigger with phrases like "upgrade evernote sdk", "evernote migration", "update evernote", "evernote breaking changes".
evernote-migration-deep-dive
Deep dive into Evernote data migration strategies. Use when migrating to/from Evernote, bulk data transfers, or complex migration scenarios. Trigger with phrases like "migrate to evernote", "migrate from evernote", "evernote data transfer", "bulk evernote migration".
elevenlabs-upgrade-migration
Upgrade ElevenLabs SDK versions and migrate between API model generations. Use when upgrading the elevenlabs-js or elevenlabs Python SDK, migrating from v1 to v2 models, or handling deprecations. Trigger: "upgrade elevenlabs", "elevenlabs migration", "elevenlabs breaking changes", "update elevenlabs SDK", "migrate elevenlabs model", "eleven_v3 migration".
documenso-upgrade-migration
Manage Documenso API version upgrades and SDK migrations. Use when upgrading from v1 to v2 API, updating SDK versions, or migrating between Documenso versions. Trigger with phrases like "documenso upgrade", "documenso v2 migration", "update documenso SDK", "documenso API version".
documenso-migration-deep-dive
Execute comprehensive Documenso migration strategies for platform switches. Use when migrating from other signing platforms, re-platforming to Documenso, or performing major infrastructure changes. Trigger with phrases like "migrate to documenso", "documenso migration", "switch to documenso", "documenso replatform", "replace docusign".
deepgram-upgrade-migration
Plan and execute Deepgram SDK upgrades and model migrations. Use when upgrading SDK versions (v3->v4->v5), migrating models (Nova-2 to Nova-3), or planning API version transitions. Trigger: "upgrade deepgram", "deepgram migration", "update deepgram SDK", "deepgram version upgrade", "nova-3 migration".
deepgram-migration-deep-dive
Deep dive into migrating to Deepgram from other transcription providers. Use when migrating from AWS Transcribe, Google Cloud STT, Azure Speech, OpenAI Whisper, AssemblyAI, or Rev.ai to Deepgram. Trigger: "deepgram migration", "switch to deepgram", "migrate transcription", "deepgram from AWS", "deepgram from Google", "replace whisper with deepgram".
databricks-upgrade-migration
Upgrade Databricks runtime versions and migrate between features. Use when upgrading DBR versions, migrating to Unity Catalog, or updating deprecated APIs and features. Trigger with phrases like "databricks upgrade", "DBR upgrade", "databricks migration", "unity catalog migration", "hive to unity".