Moose

Getting Started

Use with Existing ClickHouse

Use Moose with Existing ClickHouse

5 min setup
Zero disruption to prod
Code-first, local dev

Viewing:

Why Use Moose with Your Existing ClickHouse?

Moose augments your existing ClickHouse to build apps on top of your data and manage your table schemas in code.

Moose Adds to ClickHouse

Code-first schema management

Manage ClickHouse schemas in code, with Git versioning

Hot-reload dev environment

Iterate instantly without touching production

Build APIs and user-facing apps

Surface your analytics to your users with type-safe APIs

Streaming & ETL without config

Add streaming ingestion and custom workflows, no YAML

Prerequisites

Before you start

Existing ClickHouse Database

Any ClickHouse instance (Cloud, self-hosted, or playground)

Node.js 20+

Required for TypeScript development

Download →

Docker Desktop

For local development environment

Download →

macOS/Linux

Windows works via WSL2


Step 1: Install Moose

Install the Moose CLI globally to your system:

Terminal
bash -i <(curl -fsSL https://fiveonefour.com/install.sh) moose

Step 2: Set Up Your Project

Don't have ClickHouse?

Use the ClickHouse Playground tab to try it out!

Initialize new project
# Generate code models from your existing ClickHouse tables
moose init my-project --from-remote <YOUR_CLICKHOUSE_CONNECTION_STRING> --language typescript

YOUR_CLICKHOUSE_CONNECTION_STRING is your ClickHouse connection URL in this format:

https://username:password@host:port/?database=database_name

Install dependencies
cd my-project
npm install

You should see: Successfully generated X models from ClickHouse tables

Explore Your Generated Models

Check what Moose created from your tables in the app/index.ts file:

    • index.ts

Step 3: Start Development

Start your dev server to spin up a local ClickHouse instance with all your production tables automatically reproduced from your code definitions.

Start your dev server
moose dev

Your production ClickHouse will remain untouched.

Seed Your Local Database

You can seed your data into your local ClickHouse instance by running the following command:

Terminal
moose seed --connection-string <YOUR_CLICKHOUSE_CONNECTION_STRING> --limit 100

Step 4: Adopt Moose Gradually

Now that you have your Tables defined in code, you get the same benefits as ORM data models in web apps - type safety and autocomplete when building APIs and Materialized Views on top of your analytical data.

Add APIs

Build REST APIs on top of your existing tables to expose your data to your user-facing apps. This is a great way to get started with Moose without changing any of your existing pipelines.

import { TargetSchema, materializedView } from "./myMaterializedView";
 
 
export interface QueryParams {
  date: Date;
  limit?: number;
}
 
const api = new ConsumptionApi<QueryParams, TargetSchema>("get-aggregated-data",
  async ({ date, limit = 10 }: QueryParams, { client, sql }) => {
    const query = sql`
        SELECT * FROM ${materializedView.targetTable} 
        WHERE date = ${date} 
        LIMIT ${limit}`;
 
    const result = await client.query.execute<TargetSchema>(query); // Type-safe query execution
    return result.json();
  }
);

Learn more:

Build Materialized Views

Build materialized views on top of your existing tables to improve query performance. If you have Materialized Views in your ClickHouse, you can use Moose to build new Materialized Views on top of your existing tables, or to migrate your existing Materialized Views to Moose.

// Data Model for your Materialized View- use type throughout your codebase
export interface TargetSchema {
  date: Date;
  count: number;
}
// Creates both the target table and the materialized view
export const materializedView = new MaterializedView<TargetSchema>({
  // Raw SQL with type-safe table references
  selectStatement: sql`SELECT count(*) as count, date FROM ${myTable} GROUP BY date`,
  selectTables: [myTable], // Automatic dependency resolution for cascading materialized views
  engine: ClickHouseEngines.MergeTree, // Can use which ever engine you want
  orderByFields: ["date"],
  tableName: "myAggregation",
  materializedViewName: "myAggregation_MV",
});

Learn more:

Add New Data Sources

For new data sources, use Moose’s IngestPipelines to stream new data into your ClickHouse—while your legacy flows keep running. You can also use Workflows to run custom ETL pipelines if you have batch workloads.


Known Limitations

Early Access Feature

Some advanced ClickHouse features may not be fully supported yet. Join the Moose Slack and let us know if you have any issues, feedback, or requests.

Currently Unsupported Types:

  • Geo types (Point, Ring, Polygon, etc.)
  • Enum types with empty string keys

Partial Support:

  • LowCardinality(T) - Maps to base type T (optimization annotations available)

What we’re working on:

  • Selective table import (currently imports all tables)
  • Default value annotations

What’s Next?