Migrating from MooseStack to hypequery

MooseStack is end of life. This guide maps its typed ClickHouse query and API layer to hypequery while keeping schema, streaming, and workflow migrations separate.

MooseStack’s maintainers have announced that MooseStack has reached end of life and is no longer actively maintained. The repository is archived and read-only. Read the official EOL statement on GitHub.

If you run MooseStack today, the important first move is not swapping one npm package for another. Moose covered several jobs—ClickHouse schema, streaming, workflows, query APIs, and a development harness—while hypequery deliberately focuses on the application-facing analytics layer.

Use hypequery to replace typed ClickHouse queries, semantic metrics, APIs, React consumers, and MCP tools. Give DDL migrations, ingestion, and workflow orchestration an explicit home of their own.

Map the responsibilities first

MooseStack responsibilityMigration destination
ClickHouse tables, materialized views, and DDLYour existing SQL migration system, ClickHouse tooling, or infrastructure workflow
Kafka/Redpanda ingestionKeep the pipeline or move it independently
Temporal workflowsKeep Temporal or choose another scheduler independently
Typed read queries@hypequery/clickhouse
Data models, dimensions, and metrics@hypequery/datasets
Query APIs@hypequery/serve
Frontend analytics@hypequery/react
Agent access@hypequery/mcp

This separation prevents a query-layer migration from turning into an infrastructure rewrite.

1. Freeze the current physical schema

Before changing application code, capture what Moose actually created in ClickHouse:

  • tables and engines;
  • partition and ordering keys;
  • materialized views and target tables;
  • dictionaries and projections;
  • ingestion topics and consumers;
  • scheduled workflows;
  • query and ingest endpoints still receiving traffic.

Move the DDL into the migration system that will own it after Moose. hypequery introspects ClickHouse; it does not push physical schema into the database.

2. Generate TypeScript types from live ClickHouse

The generated schema reflects what ClickHouse currently returns over HTTP, including large integers as strings, DateTime values as strings, arrays, and nullable columns. This is the new physical source of truth for application queries.

Create the client beside the Moose code so both can run during migration:

3. Port read queries one at a time

Start with read-only endpoints. Preserve their filters, grouping, ordering, limits, and response shape, then compare generated SQL and results against the existing endpoint.

The builder supports ClickHouse-native final(), limitBy(), PREWHERE, array joins, CTEs, percentiles, argMax, and analytical statistics. Window functions use selectExpr inside the typed selection. Check the current capability matrix instead of relying on older comparison posts.

4. Promote shared meaning into datasets

Once a query matches, extract the business fields and metrics that multiple endpoints use:

Do not mirror every table mechanically. Publish the dimensions and measures your product should expose.

5. Preserve tenant isolation at the model boundary

If Moose queries applied an organisation or account filter, declare the physical tenant column with tenantKey and pass the authenticated tenant through trusted runtime context:

An unscoped query against a tenant-keyed dataset is rejected. Do not accept the tenant ID as ordinary request or agent input.

6. Replace query endpoints

Expose migrated metrics and datasets through Serve:

Mount the Node or Fetch adapter inside the application you already deploy. Run old and new routes in parallel, compare production-shaped requests, and move consumers endpoint by endpoint.

7. Move React and agent consumers

Generate a route manifest for typed React hooks:

For agents, publish the same datasets through @hypequery/mcp. The agent gets dataset discovery and bounded metric queries rather than raw ClickHouse credentials.

8. Remove Moose only after the dependency audit

Before shutting down the Moose runtime, confirm that:

  • no read or ingest endpoint still receives traffic;
  • DDL changes have a new owner;
  • streaming consumers run independently;
  • Temporal or scheduled jobs have moved;
  • deployment and environment secrets no longer depend on Moose;
  • dashboards and agents use the new contracts;
  • alerting covers the replacement services.

The architectural change

MooseStack treated the analytical backend as one framework. The post-migration stack has a narrower boundary:

  • ClickHouse remains the data engine;
  • dedicated systems own ingestion, DDL, and workflows;
  • hypequery owns the TypeScript query and semantic contract used by the product.

That smaller surface is easier to adopt incrementally and easier to replace later because it does not own the whole data plane.

Read the MooseStack EOL comparison, verify the current hypequery capabilities, then run the quick start against one table before planning the full cutover.

Related content

Continue with the most relevant next reads