Skip to main content
The Tinybird TypeScript SDK lets you define your datasources, pipes, and queries in TypeScript and sync them directly to Tinybird. With full type inference, you get autocomplete, type checking, and type-safe queries throughout your entire data pipeline.
This package is experimental. APIs may change between versions.

What is the Tinybird TypeScript SDK?

The SDK provides a code-first approach to building data pipelines with Tinybird. Instead of writing .datasource and .pipe files, you define your resources as TypeScript objects with full type safety.

Key Benefits

Full Type Safety

Get end-to-end type inference from schema definition to query results. TypeScript validates your queries at compile time.

Developer Experience

Enjoy autocomplete, inline documentation, and refactoring support in your IDE. Catch errors before deployment.

Version Control

Define your data infrastructure as code. Track changes, review diffs, and collaborate using familiar Git workflows.

Incremental Migration

Mix TypeScript definitions with existing .datasource and .pipe files. Migrate at your own pace.

How It Works

The SDK workflow follows these steps:
1

Define Resources in TypeScript

Create datasources with typed schemas, define query endpoints with parameters and output types, and configure connections.
2

Generate Typed Client

The SDK generates a fully-typed client that provides autocomplete for all your endpoints and datasources.
3

Sync to Tinybird

Use tinybird dev to automatically sync changes to Tinybird as you develop, or tinybird deploy for production.
4

Query with Type Safety

Use the generated client in your application with full type safety - from parameters to query results.

Example

Here’s a quick example of what code looks like with the SDK:
import { defineDatasource, defineEndpoint, t, p, engine, node } from "@tinybirdco/sdk";

// Define a datasource with typed schema
export const pageViews = defineDatasource("page_views", {
  schema: {
    timestamp: t.dateTime(),
    pathname: t.string(),
    session_id: t.string(),
    country: t.string().lowCardinality().nullable(),
  },
  engine: engine.mergeTree({
    sortingKey: ["pathname", "timestamp"],
  }),
});

// Define an endpoint with typed parameters and output
export const topPages = defineEndpoint("top_pages", {
  params: {
    start_date: p.dateTime(),
    end_date: p.dateTime(),
    limit: p.int32().optional(10),
  },
  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(),
  },
});
Then use it with full type safety:
import { tinybird } from "@tinybird/client";

// Type-safe ingestion
await tinybird.pageViews.ingest({
  timestamp: "2024-01-15 10:30:00",
  pathname: "/home",
  session_id: "abc123",
  country: "US",
});

// Type-safe queries with autocomplete
const result = await tinybird.topPages.query({
  start_date: "2024-01-01 00:00:00",
  end_date: "2024-01-31 23:59:59",
  limit: 5,
});

// result.data is fully typed: { pathname: string, views: bigint }[]
console.log(result.data);

What’s Next?

Installation

Install the SDK and set up your development environment

Quickstart

Build your first typed data pipeline in minutes

Build docs developers (and LLMs) love