Quick start: TypeScript SDK

This quickstart walks through creating a Tinybird project using the TypeScript SDK. You define datasources and endpoints in TypeScript, sync them to Tinybird, and use a typed client for ingest and queries.

Looking for other ways to start? See Quick starts.

Before you begin

To get started, you need the following:

  • Node.js 20 LTS or later
  • TypeScript 4.9 or later

Install the SDK

We recommend installing the SDK globally so you can run the tinybird CLI directly.

pnpm add -g @tinybirdco/sdk

You can also add it just to your repository:

pnpm add @tinybirdco/sdk

Initialize a Tinybird TypeScript project

Run the Tinybird SDK CLI to scaffold the project:

npx tinybird init

During initialization, the CLI authenticates you against Tinybird Cloud and can optionally add CI/CD workflow files.

This creates:

  • tinybird.config.mjs configuration file
  • lib/tinybird.ts for Data Sources, Pipes, Connectors, and Client definitions
  • .env.local for authentication against Tinybird Cloud Workspace

Check your Tinybird token

Create a .env.local file with your Tinybird token if not exists yet:

TINYBIRD_TOKEN=p.your_token_here
TINYBIRD_URL=https://api.tinybird.co

The CLI reads .env.local automatically.

Inspect resources definition

Data sources

Check Data Source definition in lib/tinybird.ts:

import { defineDatasource, engine, t, type InferRow } from "@tinybirdco/sdk";

export const pageViews = defineDatasource("page_views", {
  description: "Page view tracking data",
  schema: {
    timestamp: t.dateTime(),
    session_id: t.string(),
    pathname: t.string(),
    referrer: t.string().nullable(),
  },
  engine: engine.mergeTree({
    sortingKey: ["pathname", "timestamp"],
  }),
});

export type PageViewsRow = InferRow<typeof pageViews>;

API Endpoints

Check API Endpoint definition in lib/tinybird.ts:

import {
  defineEndpoint,
  node,
  p,
  t,
  type InferParams,
  type InferOutputRow,
} from "@tinybirdco/sdk";

export const topPages = defineEndpoint("top_pages", {
  description: "Get the most visited pages",
  params: {
    start_date: p.dateTime().describe("Start of date range"),
    end_date: p.dateTime().describe("End of date range"),
    limit: p.int32().optional(10).describe("Number of results"),
  },
  nodes: [
    node({
      name: "aggregated",
      sql: `
        SELECT
          pathname,
          count() AS views
        FROM page_views
        WHERE timestamp >= {{DateTime(start_date)}}
          AND timestamp <= {{DateTime(end_date)}}
        GROUP BY pathname
        ORDER BY views DESC
        LIMIT {{Int32(limit, 10)}}
      `,
    }),
  ],
  output: {
    pathname: t.string(),
    views: t.uint64(),
  },
});

export type TopPagesParams = InferParams<typeof topPages>;
export type TopPagesOutput = InferOutputRow<typeof topPages>;

Typed client

Check the client in lib/tinybird.ts:

import { Tinybird } from "@tinybirdco/sdk";

export const tinybird = new Tinybird({
  datasources: { pageViews },
  pipes: { topPages },
});

Build the project

Run a build to push your current resources to Tinybird:

tinybird build

If you want your changes to sync automatically while you work, run dev mode instead:

tinybird dev

Choose a development flow

Your default target (local or branch) is set in tinybird.config.mjs. You can override it with flags on the command line.

By default, tinybird dev syncs to a Tinybird feature branch. You can also work against Tinybird Local for isolated development.

tinybird dev --local

If you haven't installed Tinybird Local yet, follow Install Tinybird Local.

When you're ready to promote changes:

  • Use tinybird build to push to a branch (good for review or CI).
  • To deploy to Tinybird Cloud main workspace (production) we strongly recommend CD, but you can use tinybird deploy directly.

Ingest data and query

Use the typed client in your application code:

import { tinybird, type PageViewsRow } from "@tinybird/client";

await tinybird.ingest.pageViews({
  timestamp: new Date(),
  pathname: "/home",
  session_id: "abc123",
  country: "US",
});

const result = await tinybird.query.topPages({
  start_date: new Date("2026-01-01"),
  end_date: new Date(),
  limit: 5,
});

result.data.forEach((row) => {
  console.log(row.pathname, row.views);
});

Migrate an existing project

If you already have .datasource, .pipe, or .connection files, use the CLI to generate TypeScript definitions and keep working in the same repo.

tinybird migrate "tinybird/**/*.datasource" "tinybird/**/*.pipe" "tinybird/**/*.connection"

Next steps

Updated