zero-query
v0.9.8
Published
Lightweight modern frontend library — jQuery-like selectors, reactive components, SPA router, and state management with zero dependencies.
Maintainers
Readme
Lightweight, zero-dependency frontend library that combines jQuery-style DOM manipulation with a modern reactive component system, SPA router, global state management, HTTP client, and utility toolkit — all in a single ~100 KB minified browser bundle. Works out of the box with ES modules. An optional CLI bundler is available for single-file production builds.
Features
| Module | Highlights |
| --- | --- |
| Components | Reactive state, template literals, @event delegation (22 modifiers — key filters, system keys, .outside, timing, and more), z-model two-way binding (with z-trim, z-number, z-lazy, z-debounce, z-uppercase, z-lowercase), computed properties, watch callbacks, slot-based content projection, directives (z-if/z-else-if/z-else, z-for, z-show, z-bind/:attr, z-class, z-style, z-text, z-html, z-ref, z-cloak, z-pre, z-key, z-skip), DOM morphing engine with LIS-based keyed reconciliation (no innerHTML rebuild), CSP-safe expression evaluation with AST caching, scoped styles, external templates (templateUrl / styleUrl), lifecycle hooks, auto-injected base styles |
| Router | History & hash mode, route params (:id), wildcards, guards (beforeEach/afterEach), lazy loading, z-link navigation, z-to-top scroll modifier (instant/smooth), sub-route history substates (pushSubstate/onSubstate) |
| Directives | z-if, z-for, z-model, z-show, z-bind, z-class, z-style, z-text, z-html, z-ref, z-cloak, z-pre, z-key, z-skip — 17 built-in template directives |
| Reactive | Deep proxy reactivity, Signals (.value, .peek()), computed values, effects (auto-tracked with dispose) |
| Store | Reactive global state, named actions, computed getters, middleware, subscriptions, action history, snapshots |
| Selectors & DOM | jQuery-like chainable selectors, traversal, DOM manipulation, events, animation |
| HTTP | Fetch wrapper with auto-JSON, interceptors (with unsubscribe & clear), HEAD requests, parallel requests (http.all), config inspection (getConfig), timeout/abort, base URL |
| Utils | debounce, throttle, pipe, once, sleep, memoize, escapeHtml, stripHtml, uuid, capitalize, truncate, range, chunk, groupBy, unique, pick, omit, getPath/setPath, isEmpty, clamp, retry, timeout, deepClone, deepMerge, storage/session wrappers, event bus |
| Dev Tools | CLI dev server with live-reload, CSS hot-swap, full-screen error overlay, floating toolbar, dark-themed inspector panel (Router view, DOM tree, network log, component viewer, performance dashboard), fetch interceptor, render instrumentation, CLI bundler for single-file production builds |
Quick Start
Recommended: CLI Dev Server
The fastest way to develop with zQuery is via the built-in CLI dev server with live-reload. It serves your ES modules as-is and automatically resolves the library — no manual downloads required.
# Install (per-project or globally)
npm install zero-query --save-dev # or: npm install zero-query -gScaffold a new project and start the server:
npx zquery create my-app
npx zquery dev my-appTip: Stay in the project root (where
node_moduleslives) instead ofcd-ing intomy-app. This keepsindex.d.tsaccessible to your IDE for full type/intellisense support.
The create command generates a ready-to-run project with a sidebar layout, router, multiple components (including folder components with external templates and styles), and responsive styles. Use --minimal (or -m) to scaffold a lightweight 3-page starter instead. The dev server watches for file changes, hot-swaps CSS in-place, full-reloads on other changes, and handles SPA fallback routing.
Error Overlay
The dev server includes a full-screen error overlay that surfaces errors directly in the browser — similar to Vite or Angular:
- Syntax errors — JS files are validated on every save before the reload is triggered. If a syntax error is found the page stays intact and a dark overlay appears with the error message, file path, line:column, and a code frame pointing to the exact location.
- Runtime errors — uncaught exceptions and unhandled promise rejections are captured and displayed in the same overlay with a cleaned-up stack trace.
- The overlay auto-clears when you fix the error and save. Press
Escor click×to dismiss manually.
Floating Toolbar & Inspector
A compact expandable toolbar appears in the bottom-right corner. In its collapsed state it shows live render and request counters. Click the chevron to expand and reveal the route indicator (color-coded by the last navigation event — navigate, pop, replace, hashchange, substate), registered component count, and DOM element count. Click any stat to open a dark-themed DevTools inspector as a popup — or visit http://localhost:<port>/_devtools for a standalone split-view panel with five tabs: Router (live route state, guards, history timeline), Components (live state cards), Performance (render timeline with timing metrics), Network (fetch log with JSON viewer), and Elements (live DOM tree with component badges, source viewer, expand/collapse).
Alternative: Manual Setup (No npm)
If you prefer zero tooling, download dist/zquery.min.js from the dist/ folder and drop it into your project root or assets/scripts/. Then open index.html directly in a browser — no Node.js required.
git clone https://github.com/tonywied17/zero-query.git
cd zero-query
npx zquery build
# → dist/zquery.min.js (~100 KB)Include in HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My App</title>
<link rel="stylesheet" href="global.css">
<script src="zquery.min.js"></script>
<script type="module" src="app/app.js"></script>
</head>
<body>
<nav>
<a z-link="/">Home</a>
<a z-link="/about">About</a>
</nav>
<div id="app"></div>
</body>
</html>Boot Your App
// app/app.js
import './components/home.js';
import './components/about.js';
import './components/contacts/contacts.js';
import { routes } from './routes.js';
$.router({ el: '#app', routes, fallback: 'not-found' });Define a Component
// app/components/home.js
$.component('home-page', {
state: () => ({ count: 0 }),
increment() { this.state.count++; },
render() {
return `
<h1>Home</h1>
<p>Count: ${this.state.count}</p>
<button @click="increment">+1</button>
`;
}
});That's it — a fully working SPA with the dev server's live-reload.
Recommended Project Structure
my-app/ ← default scaffold (npx zquery create my-app)
index.html
global.css
app/
app.js
routes.js
store.js
components/
home.js
counter.js
todos.js
api-demo.js
about.js
not-found.js
contact-card.js
contacts/ ← folder component (templateUrl + styleUrl)
contacts.js
contacts.html
contacts.css
playground/ ← folder component
playground.js
playground.html
playground.css
toolkit/ ← folder component
toolkit.js
toolkit.html
toolkit.css
assets/
scripts/ ← third-party JS (e.g. zquery.min.js for manual setup)
styles/ ← additional stylesheets, fonts, etc.Use --minimal for a lighter starting point (3 pages + 404 fallback):
my-app/ ← minimal scaffold (npx zquery create my-app --minimal)
index.html
global.css
app/
app.js
routes.js
store.js
components/
home.js
counter.js
about.js
not-found.js ← 404 fallback
assets/- One component per file inside
components/. - Names must contain a hyphen (Web Component convention):
home-page,app-counter, etc. - Components with external templates or styles can use a subfolder (e.g.
contacts/contacts.js+contacts.html+contacts.css). app.jsis the single entry point — import components, create the store, and boot the router.global.csslives next toindex.htmlfor easy access; the bundler hashes it intoglobal.<hash>.min.cssfor production.assets/holds static files that get copied todist/as-is.
CLI Bundler
The CLI compiles your entire app — ES modules, the library, external templates, and assets — into a single production-ready bundle. It outputs two builds in one step: a server/ build for deploying to any web server, and a local/ build that works straight from disk. No config, no flags — just point it at your app.
# Auto-detect entry from any .html with a module script
npx zquery bundle
# Or point to an app directory from anywhere
npx zquery bundle my-app/
# Or pass a direct entry file (skips auto-detection)
npx zquery bundle my-app/app/main.jsOutput goes to dist/ next to your index.html:
dist/
server/ ← deploy to your web server (<base href="/"> for SPA routes)
index.html
z-app.<hash>.min.js
global.<hash>.min.css
assets/
local/ ← open from disk (file://) — no server needed
index.html
z-app.<hash>.min.js
...Flags
| Flag | Short | Description |
| --- | --- | --- |
| --out <path> | -o | Custom output directory |
| --index <file> | -i | Index HTML file (default: auto-detected) |
| --minimal | -m | Only output HTML, bundled JS, and global CSS (skip static assets) |
| --global-css <path> | | Override global CSS input file (default: first <link> in HTML) |
What the Bundler Does
- Entry detection — a strict precedence order ensures the correct file is chosen:
- HTML files —
index.htmlis checked first, then other.htmlfiles (root + one level deep). - Module scripts within HTML — within each HTML file, a
<script type="module">whosesrcresolves toapp.jswins; otherwise the first module script tag is used. - JS file scan — if no HTML match, JS files (up to 2 levels deep) are scanned in two passes: first for
$.router((the canonical app entry point), then for$.mount(,$.store(, ormountAll(. - Convention fallbacks —
app/app.js,scripts/app.js,src/app.js,js/app.js,app.js,main.js.
- HTML files —
- Resolves all
importstatements and topologically sorts dependencies - Strips
import/exportsyntax, wraps in an IIFE - Embeds zQuery library and inlines
templateUrl/styleUrlfiles - Rewrites HTML, copies assets, produces hashed filenames
Production Deployment
Deploy the dist/server/ output. Configure your web server to rewrite non-file requests to index.html:
Apache (.htaccess):
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.html [L]Nginx:
location / {
try_files $uri $uri/ /index.html;
}Sub-path deployment (e.g. /my-app/): set <base href="/my-app/"> in your HTML — the router auto-detects it.
Complete API at a Glance
| Namespace | Methods |
| --- | --- |
| $() | Chainable selector → ZQueryCollection (CSS selectors, elements, NodeLists, HTML strings) |
| $.all() | Alias for $() — identical behavior |
| $.id $.class $.classes $.tag $.name $.children $.qs $.qsa | Quick DOM refs |
| $.create | Element factory |
| $.ready $.on $.off | DOM ready, global event delegation & direct listeners |
| $.fn | Collection prototype (extend it) |
| $.component $.mount $.mountAll $.getInstance $.destroy $.components $.prefetch | Component system |
| $.morph $.morphElement | DOM morphing engine — LIS-based keyed reconciliation, isEqualNode() bail-outs, z-skip opt-out. Patches existing DOM to match new HTML without destroying unchanged nodes. Auto-key detection (id, data-id, data-key) — no z-key required. $().html() and $().replaceWith() auto-morph existing content; $().morph() for explicit morph |
| $.safeEval | CSP-safe expression evaluator (replaces eval / new Function) |
| $.style | Dynamically load global stylesheet file(s) at runtime |
| $.router $.getRouter | SPA router |
| $.store $.getStore | State management |
| $.http $.get $.post $.put $.patch $.delete $.head | HTTP client |
| $.reactive $.Signal $.signal $.computed $.effect | Reactive primitives |
| $.debounce $.throttle $.pipe $.once $.sleep $.memoize | Function utils |
| $.escapeHtml $.stripHtml $.html $.trust $.TrustedHTML $.uuid $.camelCase $.kebabCase $.capitalize $.truncate | String utils |
| $.deepClone $.deepMerge $.isEqual $.pick $.omit $.getPath $.setPath $.isEmpty | Object utils |
| $.range $.unique $.chunk $.groupBy | Array utils |
| $.clamp | Number utils |
| $.retry $.timeout | Async utils |
| $.param $.parseQuery | URL utils |
| $.storage $.session | Storage wrappers |
| $.EventBus $.bus | Event bus || $.onError $.ZQueryError $.ErrorCode $.guardCallback $.validate | Error handling || $.version | Library version |\n| $.libSize | Minified bundle size string (e.g. \"~100 KB\") |
| $.unitTests | Build-time test results { passed, failed, total, suites, duration, ok } |
| $.meta | Build metadata (populated by CLI bundler) |
| $.noConflict | Release $ global |
| CLI Command | Description |
| --- | --- |
| zquery create [dir] | Scaffold a new project. Default: full-featured app. --minimal / -m: lightweight 3-page starter with 404 fallback. |
| zquery dev [root] | Dev server with live-reload, CSS hot-swap, error overlay, expandable floating toolbar & five-tab inspector panel (port 3100). Visit /_devtools for the standalone panel. --index for custom HTML, --bundle for bundled mode, --no-intercept to skip CDN intercept. |
| zquery bundle [dir\|file] | Bundle app into a single IIFE file. Accepts dir or direct entry file. |
| zquery build | Build the zQuery library (dist/zquery.min.js) |
| zquery --help | Show CLI usage |
For full method signatures, options, and examples, see API.md.
Editor Support
The official zQuery for VS Code extension provides autocomplete, hover docs, HTML directive support, and 185+ code snippets for every API method and directive. Install it from the VS Code Marketplace or search "zQuery for VS Code" in Extensions.
License
MIT — Anthony Wiedman / Molex
