Amazon EventBridge is a serverless event bus. You publish events to it and rules route them to targets like Lambda, SQS, or CloudWatch Logs. This article shows how to send a typed event to EventBridge using TypeScript and the AWS SDK V3.
- Node.js 18+
- An AWS account with an EventBridge event bus
Install the dependencies:
npm init -y
npm install @aws-sdk/client-eventbridge
npm install -D typescript @types/node tsxThe AWS SDK reads credentials from environment variables. Export these before running the script:
export AWS_ACCESS_KEY_ID=your-access-key-id
export AWS_SECRET_ACCESS_KEY=your-secret-access-key
export AWS_REGION=eu-west-1Add a tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"strict": true,
"outDir": "dist",
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src"]
}Define the shapes your application publishes. Create src/types.ts:
export type OrderPlaced = {
type: "order.placed";
orderId: string;
customer: string;
total: number;
};
export type OrderShipped = {
type: "order.shipped";
orderId: string;
trackingNumber: string;
};
export type AppEvent = OrderPlaced | OrderShipped;The type field acts as a discriminator. When you add a new event, you add a new member to the union and the compiler catches any gaps.
Create src/send.ts:
import {
EventBridgeClient,
PutEventsCommand,
} from "@aws-sdk/client-eventbridge";
import type { AppEvent } from "./types.js";
const client = new EventBridgeClient({});
const EVENT_BUS_NAME = process.env.EVENT_BUS_NAME ?? "default";
async function send(event: AppEvent): Promise<void> {
const command = new PutEventsCommand({
Entries: [
{
Source: "my.application",
DetailType: event.type,
Detail: JSON.stringify(event),
EventBusName: EVENT_BUS_NAME,
},
],
});
const result = await client.send(command);
if (result.FailedEntryCount && result.FailedEntryCount > 0) {
for (const entry of result.Entries ?? []) {
if (entry.ErrorCode) {
console.error(`Failed: ${entry.ErrorCode} — ${entry.ErrorMessage}`);
}
}
process.exit(1);
}
const eventId = result.Entries?.[0]?.EventId;
console.log(`Sent [${event.type}] — EventId: ${eventId}`);
}
const raw = process.argv[2];
if (!raw) {
console.error("Usage: npx tsx src/send.ts '<json>'");
console.error(
`Example: npx tsx src/send.ts '{"type":"order.placed","orderId":"abc-123","customer":"jane@example.com","total":49.99}'`
);
process.exit(1);
}
const body: AppEvent = JSON.parse(raw);
send(body);Each entry requires four fields. Source identifies who published it. DetailType describes the kind of event. Detail carries the JSON payload. EventBusName picks the bus — it defaults to default if not set.
If you are using a custom event bus, export its name first:
export EVENT_BUS_NAME=my-app-busThen send an event:
npx tsx src/send.ts '{"type":"order.placed","orderId":"abc-123","customer":"jane@example.com","total":49.99}'You should see:
Sent [order.placed] — EventId: a1b2c3d4-...
To confirm the event arrived, you need a rule that captures it. The simplest target is a CloudWatch Log Group.
If you have the Serverless Framework installed, deploy the included serverless.yml:
npx serverless deployThis creates a custom event bus (my-app-bus), a catch-all rule, and a CloudWatch Log Group at /aws/events/my-app-bus. After sending an event, check the logs:
aws logs tail /aws/events/my-app-bus --followYou should see the full event payload in the log stream.