This guide sets up a local ClickHouse development environment that mirrors your production database and enables code-first schema management:
Local Development:
Production Deployment:
Define ClickHouse tables, materialized views, and schemas as TypeScript/Python code
TypeScript/Python classes generated from your existing ClickHouse tables
Local ClickHouse instance that mirrors your production schema
Build REST APIs with full type safety and autocomplete
Schema changes are automatically applied to your target database on deployment
Any ClickHouse instance (Cloud, self-hosted, or playground)
Required for TypeScript development
Download →For local development environment
Download →Any ClickHouse instance (Cloud, self-hosted, or playground)
Required for TypeScript development
Download →For local development environment
Download →Install the Moose CLI globally to your system:
bash -i <(curl -fsSL https://fiveonefour.com/install.sh) mooseAfter installation, you'll use moose init to create a new project that automatically connects to your ClickHouse and generates all the code you need.
Use the ClickHouse Playground tab to try it out!
# Option 1: Provide connection string directly
moose init my-project --from-remote <YOUR_CLICKHOUSE_CONNECTION_STRING> --language typescript
# Option 2: Run without connection string for interactive setup
moose init my-project --from-remote --language typescriptConnection String Format:
https://username:password@host:port/?database=database_name
If you don't provide a connection string, Moose will guide you through an interactive setup process where you'll be prompted to enter:
https://your-service-id.region.clickhouse.cloud:8443)default)default)This is perfect if you're not sure about your connection details or prefer a guided experience.
cd my-project
npm installYou should see: Successfully generated X models from ClickHouse tables
Check what Moose created from your tables in the app/index.ts file:
If your database includes CDC‑managed tables (e.g., PeerDB/ClickPipes tables) MooseStack will mark those as EXTERNALLY_MANAGED and write them into a dedicated external models file. Your root file will be updated to load these models automatically.
The introspection process will look for the fields _peerdb_synced_at, _peerdb_is_deleted, and _peerdb_version to determine if a table is CDC‑managed.
This separation is a best‑effort by the CLI to keep clearly CDC‑owned tables external. For other tables you don't want Moose to manage, set the lifecycle to external and move them into the external file. See:
Start your development server:
moose devWhat happens when you run moose dev:
Your production ClickHouse remains completely untouched. This is a separate, local development environment.
Copy real data from your production ClickHouse to your local development environment. This gives you realistic data to work with during development.
Why seed? Your local database starts empty. Seeding copies real data so you can:
moose seed clickhouse --connection-string <YOUR_CLICKHOUSE_CONNECTION_STRING> --limit 100000Connection String Format: The connection string must use ClickHouse native protocol:
# ClickHouse native protocol (secure connection)
clickhouse://username:password@host:9440/databaseNote: Data transfer uses ClickHouse's native TCP protocol via remoteSecure(). The remote server must have the native TCP port accessible. The command automatically handles table mismatches gracefully.
--limit and --all are mutually exclusive--all can be used to copy the entire table(s), use with caution as it can be very slow and computationally intensive.Expected Output:
✓ Database seeding completed
Seeded 'local_db' from 'remote_db'
✓ table1: copied from remote
⚠️ table2: skipped (not found on remote)
✓ table3: copied from remoteTroubleshooting:
--table <name> to seed a specific table that exists in both databasesmoose ls table to see your local tablesNow that you have your data models, let's build something useful! You can create APIs, materialized views, and applications with full type safety.
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 Api<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(); });What we're working on:
Ready to build more? Check out the APIs and OLAP documentation to learn how to build powerful features on top of your ClickHouse data.
Windows works via WSL2
Windows works via WSL2
Moose will create a complete project structure with: