Skip to content

TypeScript SDK

The TypeScript SDK wraps the REST API. It’s typed end-to-end, supports both Node.js and modern runtimes (Bun, Deno, Cloudflare Workers, Vercel Edge), and ships ESM + CommonJS builds.

Install

Terminal window
npm install datamaker
# or
pnpm add datamaker
yarn add datamaker
bun add datamaker

Requires Node.js 18+ for native fetch.

Auth

import { DataMaker } from "datamaker";
// Reads DM_API_KEY from process.env
const dm = new DataMaker();
// Or explicit
const dm = new DataMaker({
apiKey: process.env.DM_API_KEY,
projectId: "proj_xxx",
});

Templates

// List
for await (const t of dm.templates.list()) {
console.log(t.id, t.name);
}
// Generate
const rows = await dm.generate({
templateId: "tmpl_customer",
count: 100,
});
// Or by name
const rows = await dm.template("Customer").generate({ count: 100 });

For large generations, stream:

for await (const row of dm.template("Customer").stream({ count: 100_000 })) {
await db.insert(row);
}

Connections

const pg = dm.connection("Postgres dev");
const sap = dm.connection("conn_s4_sandbox");
await pg.insert({ table: "customers", rows, onConflict: "update", key: "id" });
await sap.post({
entity: "A_BusinessPartner",
rows,
mode: "batch",
});
const existing = await sap.fetch({
entity: "A_BusinessPartner",
filter: "Country eq 'DE'",
select: ["BusinessPartner", "BusinessPartnerName"],
top: 100,
});

Scenarios

const run = await dm.scenarios.run({
name: "seed_orders",
params: { size: "500" },
wait: true,
});
console.log(run.status, run.durationMs);
// Stream logs
for await (const line of dm.scenarios.streamLogs({ scenarioId, runId: run.id })) {
console.log(line);
}

Errors

import {
DataMakerError, AuthError, RateLimitError, NotFoundError, ValidationError,
} from "datamaker";
try {
const rows = await dm.generate({ templateId: "tmpl_missing", count: 100 });
} catch (e) {
if (e instanceof NotFoundError) console.log("template gone:", e.code);
else if (e instanceof RateLimitError) console.log("retry in", e.retryAfter);
else throw e;
}

Retries

Same defaults as Python — transient errors retry with exponential backoff. Override:

const dm = new DataMaker({
retry: { maxAttempts: 5, backoff: "linear", factor: 2 },
});

Disable per-call:

await dm.generate({ templateId, count: 100, retry: false });

Edge runtimes

Cloudflare Workers, Vercel Edge, Deno Deploy, Bun:

import { DataMaker } from "datamaker/edge";
export default {
async fetch(req: Request, env: Env) {
const dm = new DataMaker({ apiKey: env.DM_API_KEY });
const rows = await dm.generate({ templateId: env.TEMPLATE_ID, count: 100 });
return Response.json(rows);
},
};

The /edge entrypoint omits Node-only deps (fs, streams/web polyfills).

React Server Components

Works directly in a server component:

app/customers/page.tsx
import { DataMaker } from "datamaker";
export default async function Page() {
const dm = new DataMaker();
const rows = await dm.generate({ templateId: "tmpl_customer", count: 10 });
return <CustomerTable rows={rows} />;
}

Don’t import the SDK in a client component — your API key would leak to the browser.

TypeScript niceties

The SDK is typed against the REST API:

import type { Template, Field, ConnectionType } from "datamaker";
function dumpTemplate(t: Template) {
for (const f of t.fields) {
console.log(f.name, f.type, f.options);
}
}

Field types are exhaustive — f.type is a string-literal union of every built-in type plus "template" | "python" | "regex" | "ai" | "derived" | ....

Source