> hypequery

Quick Start

Ship your first hypequery-powered endpoint in minutes

Prerequisites

Before you begin, ensure you have:

  • Node.js 18+ installed
  • Access to a ClickHouse instance with connection credentials

Install the runtime packages

Install the core packages required to run hypequery:

npm install @hypequery/clickhouse @hypequery/serve

# Optional: install the CLI locally
npm install -D @hypequery/cli
pnpm add @hypequery/clickhouse @hypequery/serve

# Optional: install the CLI locally
pnpm add -D @hypequery/cli
yarn add @hypequery/clickhouse @hypequery/serve

# Optional: install the CLI locally
yarn add -D @hypequery/cli
bun add @hypequery/clickhouse @hypequery/serve

# Optional: install the CLI locally
bun add -D @hypequery/cli

Scaffold analytics with hypequery init

From your project root, run the init command:

npx @hypequery/cli init
npx hypequery init

The CLI will prompt you to:

  1. Choose ClickHouse as your database
  2. Enter connection settings (host, port, username, password, database)
  3. Select a destination folder (defaults to analytics/)

What the CLI Generates

The init command creates:

schema.ts (Your database schema definitions)
client.ts (ClickHouse client instance)
queries.ts (Your query definitions)
.env (Your ClickHouse credentials)

It also scaffolds an example query to get you started.

Define your first query

Open analytics/queries.ts and replace the placeholder with a real query:

import { initServe } from '@hypequery/serve';
import { z } from 'zod';
import { db } from './client';

const { define, queries, query } = initServe({
  context: () => ({ db }),
});

export const api = define({
  queries: queries({
    activeUsers: query
      .describe('Most recent active users')
      .input(z.object({
        limit: z.number().min(1).max(500).default(50)
      }))
      .query(({ ctx, input }) =>
        ctx.db
          .table('users')
          .select(['id', 'email', 'created_at'])
          .where('status', 'eq', 'active')
          .orderBy('created_at', 'DESC')
          .limit(input.limit)
          .execute()
      ),
  }),
});

Running Your Query

You can run your query in three ways:

// Run directly in your code (jobs, SSR, scripts)
const latest = await api.run('activeUsers', { limit: 25 });
console.log(latest);
// Expose as an HTTP endpoint
api.route('/active-users', api.queries.activeUsers, {
  method: 'POST'
});
// In your React component
import { createHooks } from '@hypequery/react';

const { useQuery } = createHooks({
  baseUrl: '/api/analytics'
});

function ActiveUsers() {
  const { data, isLoading, error } = useQuery('activeUsers', {
    limit: 25
  });

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <ul>
      {data?.map(user => (
        <li key={user.id}>{user.email}</li>
      ))}
    </ul>
  );
}

Remember

  • Use ctx.db inside serve queries (it carries per-request context)
  • Return the promise; hypequery awaits it for you
  • Always finish query builder chains with .execute()

Preview docs with hypequery dev (Optional)

Start the dev server to view docs and logs:

npx @hypequery/cli dev
npx hypequery dev

The dev server provides:

  • Interactive docs at http://localhost:4000 - test your queries with live validation
  • OpenAPI spec at http://localhost:4000/openapi.json - for downstream tooling
  • Hot reload - changes to your queries are reflected immediately with logs

Keep this running while you develop or when teammates need to test the HTTP API locally.

On this page