5-Minute Quickstart
Viewing:
Prerequisites
Before you start
Node.js 20+
Required for TypeScript development
Download →Docker Desktop
For local development environment
Download →macOS/Linux
Windows works via WSL2
Before you start
Python 3.12+
Required for Python development
Download →Docker Desktop
For local development environment
Download →macOS/Linux
Windows works via WSL2
Already have ClickHouse running?
Skip the tutorial and add Moose as a layer on top of your existing database
Step 1: Install Moose (30 seconds)
bash -i <(curl -fsSL http://fiveonefour.com/install.sh) moose
You should see:
Moose vX.X.X installed successfully!
After installation, restart your terminal (or run source ~/.bashrc
/ source ~/.zshrc
) to ensure the moose
command is available in your PATH.
Step 2: Create Your Project (1 minute)
Initialize your project
moose init my-analytics-app typescript
cd my-analytics-app
npm install
moose init my-analytics-app python
cd my-analytics-app
# Create virtual environment (recommended)
python3 -m venv .venv
source .venv/bin/activate
# Install dependencies
pip install -r requirements.txt
Verify Docker is running
Moose uses Docker to run ClickHouse, Redpanda, and Temporal locally.
docker ps # you should see an empty list or existing containers. If you see an error, start Docker Desktop.
Start your development environment
moose dev # This will spin up the Moose, ClickHouse, Redpanda, and Temporal containers. It will take a few minutes to start up.
Created docker compose file
⡗ Starting local infrastructure
Successfully started containers
Validated clickhousedb-1 docker container
Validated redpanda-1 docker container
Successfully validated red panda cluster
Validated temporal docker container
Successfully ran local infrastructure
Node Id: my-analytics-app::b15efaca-0c23-42b2-9b0c-642105f9c437
Starting development mode
Watching "/path/to/my-analytics-app/app"
Started Webserver.
Next Steps
💻 Run the moose 👉 `ls` 👈 command for a bird's eye view of your application and infrastructure
📥 Send Data to Moose
Your local development server is running at: http://localhost:4000/ingest
You can now send data to Moose and query it. See step 4 for more details.
Step 3: Understand Your Project (1 minute)
Your project includes a complete example pipeline:
- models.py
- transform.py
- main.py
- models.ts
- transform.ts
- index.ts
Important: While your pipeline objects are defined in the child folders, they must be imported into the root index.ts
main.py
file for the Moose CLI to discover and use them.
export * from "./ingest/models"; // Data models & pipelines
export * from "./ingest/transforms"; // Transformation logic
export * from "./apis/bar"; // API endpoints
export * from "./views/barAggregated"; // Materialized views
export * from "./workflows/generator"; // Background workflows
from app.ingest.models import * # Data models & pipelines
from app.ingest.transform import * # Transformation logic
from app.apis.bar import * # API endpoints
from app.views.bar_aggregated import * # Materialized views
from app.workflows.generator import * # Background workflows
Step 4: Test Your Pipeline (2 minutes)
Send test data
Your project comes with a pre-built Workflow called generator
that acts as a data simulator. Trigger the workflow with:
moose workflow run generator
moose workflow run generator
You should see logs like:
POST ingest/Foo
[POST] Data received at ingest API sink for Foo
Received Foo_0_0 -> Bar_0_0 1 message(s)
[DB] 17 row(s) successfully written to DB table (Bar)
The workflow runs in the background and is powered by Temporal. When you run the moose workflow run
command, you’ll see a message showing the workflow has been triggered and a link to the Temporal UI at http://localhost:8080
.
Query your data
You application has a pre-built API that reads from your database. The API is running on a webserver running on localhost:4000
. Call the API with curl
:
curl "http://localhost:4000/api/bar"
You should see JSON data like:
[
{
"dayOfMonth": 15,
"totalRows": 67,
"rowsWithText": 34,
"maxTextLength": 142,
"totalTextLength": 2847
},
{
"dayOfMonth": 14,
"totalRows": 43,
"rowsWithText": 21,
"maxTextLength": 98,
"totalTextLength": 1923
}
]
Try query parameters:
curl "http://localhost:4000/api/bar?limit=5&orderBy=totalRows"
- Port 4000: Your Moose application webserver (all APIs are running on this port)
- Port 8080: Temporal UI dashboard (workflow management)
- Port 18123: ClickHouse HTTP interface (direct database access)
Step 5: Hot Reload Schema Changes (1 minute)
- Open
app/ingest/models.ts
app/ingest/models.py
- Add a new field to your data model:
export interface Foo {
id: Key<string>;
timestamp: Date;
data: string;
newField?: string; // Add this new optional field
}
from typing import Optional
class Foo(BaseModel):
id: Key[str]
timestamp: datetime
data: str
new_field: Optional[str] # Add this new optional field
- Save the file and watch your terminal
You should see Moose automatically update your infrastructure:
⠋ Processing Infrastructure changes from file watcher
~ Table Foo:
Column changes:
+ newField: String
⠋ Processing Infrastructure changes from file watcher
~ Table Foo:
Column changes:
+ new_field: String
Schema changes are automatically applied across your stack.
Your API, database schema, and streaming topic all updated automatically. Try adding another field with a different data type.
Recap
You’ve built a complete analytical backend with: