logo

qbjs

Getting Started

Client Quick Start

Build type-safe API queries on the client with @qbjs/client

@qbjs/client is a lightweight, zero-dependency query builder for constructing API queries on the client side. It pairs perfectly with @qbjs/core on the server.

Installation

npm install @qbjs/client
pnpm add @qbjs/client
yarn add @qbjs/client

Quick Example

import { query, filter } from "@qbjs/client";

// Build a query with fluent API
const queryString = query()
  .page(1)
  .limit(20)
  .fields("id", "name", "email")
  .sortDesc("createdAt")
  .where("status", "eq", "active")
  .toQueryString();

// Result: page=1&limit=20&fields=id,name,email&sort=createdAt:desc&filter={"status":{"eq":"active"}}

Step-by-Step Guide

Create a Query Builder

Use the query() function to start building:

import { query } from "@qbjs/client";

const builder = query();

Add Pagination

// Set page and limit separately
const q1 = query().page(2).limit(25);

// Or use paginate() for both at once
const q2 = query().paginate(2, 25);

Select Fields

// Select specific fields to return
const q = query().fields("id", "name", "email", "status");

// Or use the alias select()
const q2 = query().select("id", "name");

Add Sorting

// Sort ascending
const q1 = query().sortAsc("name");

// Sort descending
const q2 = query().sortDesc("createdAt");

// Multiple sorts
const q3 = query()
  .sort("status", "asc")
  .sort("createdAt", "desc");

Add Filters

import { query, filter } from "@qbjs/client";

// Using where() for simple conditions
const q1 = query()
  .where("status", "eq", "active")
  .where("role", "in", ["admin", "moderator"]);

// Using filter helpers for complex conditions
const q2 = query().filter({
  status: filter.eq("active"),
  age: filter.gte(18),
  name: filter.contains("john"),
});

Build the Query

// Get as query string for fetch/axios
const queryString = query()
  .page(1)
  .limit(10)
  .toQueryString();

// Get as object for URLSearchParams
const queryObject = query()
  .page(1)
  .limit(10)
  .build();

// Get raw params for inspection
const params = query()
  .page(1)
  .limit(10)
  .toParams();

Using with Fetch

import { query, filter } from "@qbjs/client";

async function fetchUsers() {
  const q = query()
    .fields("id", "name", "email")
    .where("status", "eq", "active")
    .sortDesc("createdAt")
    .paginate(1, 20)
    .toQueryString();

  const response = await fetch(`/api/users?${q}`);
  return response.json();
}

Using with React Query

import { useQuery } from "@tanstack/react-query";
import { query, filter } from "@qbjs/client";

function useUsers(page: number, status: string) {
  const q = query()
    .page(page)
    .limit(20)
    .where("status", "eq", status)
    .sortDesc("createdAt");

  return useQuery({
    // Stable query key from builder
    queryKey: q.toQueryKey(["users"]),
    queryFn: () => fetch(`/api/users?${q.toQueryString()}`).then(r => r.json()),
  });
}

The toQueryKey() method generates a stable, deterministic key perfect for React Query caching.

Next Steps

On this page