Getting Started
bQuery.js is designed for zero-build usage and modern build setups alike. You can start with plain HTML or use Vite for a fast dev server. Since 1.8.0, the Reactive module also covers HTTP clients, polling, pagination, realtime transports, REST helpers, and request coordination utilities. Since 1.10.0, the Concurrency module also covers explicit RPC workers, bounded pools, opt-in reactive worker state wrappers, and high-level collection helpers.
Installation
Zero-build via CDN
The quickest way to use bQuery is directly in the browser without any build step:
<!DOCTYPE html>
<html>
<head>
<title>bQuery Demo</title>
</head>
<body>
<button id="counter">Count: 0</button>
<script type="module">
import { $, signal, effect } from 'https://unpkg.com/@bquery/bquery@1/dist/full.es.mjs';
const count = signal(0);
effect(() => {
$('#counter').text(`Count: ${count.value}`);
});
$('#counter').on('click', () => {
count.value++;
});
</script>
</body>
</html>Package Manager
Install with your favorite package manager:
# npm
npm install @bquery/bquery
# bun
bun add @bquery/bquery
# pnpm
pnpm add @bquery/bqueryVite + TypeScript
import { $, signal, effect } from '@bquery/bquery';
const count = signal(0);
effect(() => {
$('#counter').text(`Count: ${count.value}`);
});Module Imports
bQuery is modular by design. You can import everything from the main entry point or pick specific modules:
// Full import
import {
$,
signal,
component,
registerDefaultComponents,
transition,
sanitize,
defineBqueryConfig,
useCookie,
} from '@bquery/bquery';
// Core only (selectors, DOM, events)
import { $, $$, utils } from '@bquery/bquery/core';
// Core utilities as named exports
import { debounce, merge, uid } from '@bquery/bquery/core';
// Reactive only (signals, computed, effects, async, HTTP, realtime)
import {
signal,
computed,
effect,
batch,
useFetch,
createHttp,
useWebSocket,
useEventSource,
useResource,
} from '@bquery/bquery/reactive';
// Concurrency only (zero-build worker tasks, pools, and helpers)
import {
callWorkerMethod,
createReactiveTaskPool,
createRpcPool,
createRpcWorker,
createTaskPool,
createTaskWorker,
isConcurrencySupported,
parallel,
runTask,
} from '@bquery/bquery/concurrency';
// Components only (Web Components + default library)
import { bool, component, html, registerDefaultComponents } from '@bquery/bquery/component';
// Motion only (transitions, animations)
import { transition, spring, flip } from '@bquery/bquery/motion';
// Security only (sanitization)
import { sanitize, escapeHtml, sanitizeHtml, trusted } from '@bquery/bquery/security';
// Platform only (storage, cache, config, cookies, page meta, accessibility)
import {
storage,
cache,
notifications,
buckets,
defineBqueryConfig,
useCookie,
definePageMeta,
useAnnouncer,
} from '@bquery/bquery/platform';
// Storybook helpers
import { storyHtml, when } from '@bquery/bquery/storybook';
// Forms, i18n, accessibility, drag & drop, media
import { createForm, required } from '@bquery/bquery/forms';
import { createI18n } from '@bquery/bquery/i18n';
import { trapFocus, skipLink } from '@bquery/bquery/a11y';
import { draggable, sortable } from '@bquery/bquery/dnd';
import { mediaQuery, useViewport, clipboard } from '@bquery/bquery/media';
// Plugins, devtools, testing, SSR
import { use } from '@bquery/bquery/plugin';
import { enableDevtools } from '@bquery/bquery/devtools';
import { renderComponent, waitFor } from '@bquery/bquery/testing';
import { renderToString, hydrateMount } from '@bquery/bquery/ssr';Modules at a glance
| Module | Description |
|---|---|
| Core | Selectors, DOM manipulation, traversal, events, and typed utilities |
| Reactive | Signals, computed values, effects, batching, HTTP clients, polling, streaming, and REST composables |
| Concurrency | Zero-build worker tasks, explicit RPC helpers, bounded pools, reactive worker state wrappers, and high-level collection helpers |
| Component | Typed Web Components with scoped reactivity and Shadow DOM control |
| Storybook | Safe string-template helpers for stories and boolean attributes |
| Motion | Transitions, morphing, parallax, typewriter, FLIP, scroll, and springs |
| Security | Sanitization, Trusted Types, CSP helpers, and trusted fragments |
| Platform | Storage, cache, cookies, page metadata, announcers, and shared config |
| Router | SPA routing, redirects, constrained params, guards, and declarative links |
| Store | Signal-based state, persistence, migrations, and action lifecycle hooks |
| View | Declarative bindings, directives, and plugin-powered custom directives |
| Forms | Reactive form state, validation, and submit orchestration |
| i18n | Reactive locale state, translation, pluralization, and Intl formatting |
| A11y | Focus management, skip navigation, live regions, media preferences, and audits |
| DnD | Draggable elements, drop zones, and sortable lists |
| Media | Viewport, network, battery, geolocation, sensors, and clipboard wrappers |
| Plugin | Global plugin registration for custom directives and components |
| Devtools | Runtime inspection helpers for signals, stores, components, and timelines |
| Testing | Component mounts, mock signals/router, event helpers, and async assertions |
| SSR | HTML rendering, hydration, and serialized store-state handoff |
Quick Examples
DOM Manipulation
import { $ } from '@bquery/bquery/core';
// Select and chain operations
$('#myElement')
.addClass('active')
.css({ color: 'blue', 'font-size': '16px' })
.text('Hello, bQuery!');
// Event handling
$('#button').on('click', () => {
console.log('Button clicked!');
});Reactive State
import { signal, computed, effect } from '@bquery/bquery/reactive';
// Create reactive state
const firstName = signal('John');
const lastName = signal('Doe');
// Derive computed values
const fullName = computed(() => `${firstName.value} ${lastName.value}`);
// React to changes
effect(() => {
document.title = fullName.value;
});
// Update triggers reactivity
firstName.value = 'Jane'; // Title updates automaticallyAsync Data & Fetching
import { signal, useFetch } from '@bquery/bquery/reactive';
const userId = signal(1);
const user = useFetch<{ id: number; name: string }>(() => `/api/users/${userId.value}`, {
watch: [userId],
query: { include: 'profile' },
});
if (user.pending.value) {
console.log('Loading…');
}
console.log(user.data.value, user.error.value);HTTP, resources & streaming
import { createHttp, useEventSource, useResource } from '@bquery/bquery/reactive';
const api = createHttp({ baseUrl: 'https://api.example.com', retry: 2 });
const profile = useResource<{ id: number; name: string }>('/users/1', {
baseUrl: 'https://api.example.com',
});
const events = useEventSource<{ status: string }>('/events/profile');
const { data } = await api.get('/users');
console.log(data, profile.pending.value, events.status.value);Web Components
import { component, html } from '@bquery/bquery/component';
component('greeting-card', {
props: {
name: { type: String, required: true },
message: { type: String, default: 'Welcome!' },
},
styles: `
.card { padding: 1rem; border-radius: 8px; background: #f0f0f0; }
h2 { margin: 0 0 0.5rem 0; }
`,
render({ props }) {
return html`
<div class="card">
<h2>Hello, ${props.name}!</h2>
<p>${props.message}</p>
</div>
`;
},
});
// Usage: <greeting-card name="World" message="How are you?"></greeting-card>Default Components & Global Config
import { defineBqueryConfig, registerDefaultComponents, useCookie } from '@bquery/bquery';
defineBqueryConfig({
components: { prefix: 'ui' },
fetch: { baseUrl: 'https://api.example.com' },
transitions: { skipOnReducedMotion: true, classes: ['page-transition'] },
});
const tags = registerDefaultComponents();
const theme = useCookie<'light' | 'dark'>('theme', { defaultValue: 'light' });
console.log(tags.button); // ui-button
theme.value = 'dark';Storybook authoring
import { storyHtml, when } from '@bquery/bquery/storybook';
export const Playground = {
args: { disabled: false },
render: ({ disabled }: { disabled: boolean }) =>
storyHtml`
<ui-card>
<ui-button ?disabled=${disabled}>Save</ui-button>
${when(disabled, '<small>Currently disabled</small>', '<small>Ready</small>')}
</ui-card>
`,
};SSR and testing
import { renderComponent, fireEvent, waitFor } from '@bquery/bquery/testing';
import { renderToString } from '@bquery/bquery/ssr';
const mounted = renderComponent('ui-button', { props: { variant: 'primary' } });
fireEvent(mounted.el, 'click');
await waitFor(() => mounted.el.isConnected);
const { html } = renderToString('<div><p bq-text="title"></p></div>', {
title: 'Hello from the server',
});
console.log(html);
mounted.unmount();Local Development
If you're developing bQuery itself:
# Install dependencies
bun install
# Start documentation dev server
bun run dev
# Start Storybook
bun run storybook
# Run tests
bun test
# Build library bundle
bun run build
# Build documentation site
bun run build:docsBrowser Support
| Browser | Version | Support |
|---|---|---|
| Chrome | 90+ | ✅ Full |
| Firefox | 90+ | ✅ Full |
| Safari | 15+ | ✅ Full |
| Edge | 90+ | ✅ Full |
Note: Internet Explorer is not supported by design.
Next Steps
- Core API - Learn about selectors and DOM manipulation
- Agents - Build agent UIs with bQuery
- Reactive - Understand signals and reactivity
- Components - Build Web Components
- Storybook - Author safe Storybook stories
- Motion - Add animations and transitions
- Security - Sanitization and CSP
- Platform - Storage, cache, cookies, page meta, announcers, and config
- Forms - Build reactive forms with validators
- i18n - Localize messages and formatting
- Accessibility - Manage focus, announcements, and audits
- Drag & Drop - Add draggable and sortable interactions
- Media - Read browser and device state reactively
- Plugin System - Register custom directives and components
- Devtools - Inspect signals, stores, and timelines
- Testing - Mount components and assert async behavior
- SSR - Render templates on the server and hydrate on the client