A declarative approach to managing the DOM.
DOMQL is a JavaScript library for querying the DOM, allowing you to read information from a document once or observe it as it changes. Its queries are written in Nexo.
Preview. No breaking redesign is planned, and a version that breaks what the one before it allowed says how to migrate. The runtime,
1.0.0-preview.2, implements DOMQL's specification1.0.0-preview.1on Nexo's language1.0.0-preview.1, definition version 38. DOMQL declares the DOM as types of its own. It is published to npm and NuGet, as installing it sets out, and you can also build and try it locally. See the status overview, and what 1.0 requires.
- Queries that shape DOM and browser state into plain data
- Projections, filters and summaries of collections
- Watches that keep a result current, as snapshots or live state
- Optional access, fallbacks and conditionals
- Locals, functions and calculations
- Strings, interpolation, conversions and casts
- Shadow trees crossed explicitly
- Event subscriptions projected into data
- Built-in executions that focus, scroll, show popovers and dialogs, write what they own and reach the browser's facilities, each answering what it did
- Typed extension modules: members, observations, event sources and executions
- Validation before anything is evaluated
- Definitions as JSON
- ES modules with TypeScript declarations, from npm or NuGet
From npm, as ES modules that import Nexo from its own package, @formaui-net/nexo, and that a module imports as import { domql } from '@formaui-net/domql':
npm install @formaui-net/domql@previewFrom NuGet, as one bundle with Nexo inside it, which a .NET web application serves at _content/domql/domql.js, as the library guide sets out:
dotnet add package formaui-net.DOMQL --prereleaseSuppose a panel contains three items:
<div id="panel">
<div data-key="a1"></div>
<div data-key="a2" aria-selected="true"></div>
<div data-key="a3"></div>
</div>This query reads the item count and each item's key and selection state:
import { domql } from './src/domql.js';
const panel = document.getElementById('panel');
const query = domql.query(`
panel {
count = it.children.count,
items = it.all("[data-key]") {
key = it["data-key"],
selected = it.aria["selected"] == "true"
}
}
`, { panel });
const snapshot = query.evaluate();The result is plain data:
{
"count": 3,
"items": [
{ "key": "a1", "selected": false },
{ "key": "a2", "selected": true },
{ "key": "a3", "selected": false }
]
}Inside each object expression, it is the current element, and the field names you write become the result's. A snapshot is immutable and holds no live DOM reference, so evaluating again gives a new one and leaves the old one as it was:
// Your app, a UI library or the user changes the page; DOMQL only reads it.
panel.children[0].setAttribute('aria-selected', 'true');
const next = query.evaluate();
console.log(next.items[0].selected); // true
console.log(snapshot.items[0].selected); // falseThe source import above works when serving the repository; the library guide loads the packaged bundle, and goes on to watching, events, the language and extensions.
| jQuery | DOMQL | |
|---|---|---|
| Main abstraction | Element collections with methods | Typed requests |
| Reading data | JavaScript assembles the result | A query describes the result |
| Keeping data current | Application code repeats its reads | A watch tracks declared observations |
| Events | Handlers work with events | Subscriptions project events into data |
| Changing the page | DOM manipulation methods | Built-in and module-defined executions, once or continuous, each answering what it did |
| Extension | Plugins | Typed vocabulary modules |
| Document | What it holds |
|---|---|
| Library guide | Install DOMQL, learn the language by example and use the API |
| DOMQL specification | Queries, the DOM's vocabulary, evaluating and watching a query, its results, events, executions, and the API |
| Nexo specification | The language DOMQL is written in, and its runtime, at the release DOMQL builds against |
| Version history | Each version of DOMQL, with the features it added and what it changed |
| Changelog | Each release of the packages and what it changed |
| Design | How DOMQL is built, and the decisions it did not take |
| Status | What is implemented, what is being built, and what remains |
| Contributing | Report a bug, develop a change and run the checks |
| Security | Report a vulnerability privately |
Clone the repository. You'll need Node.js with npm, PowerShell and the .NET SDK pinned in nuget/global.json; CONTRIBUTING.md has the details.
./build.ps1 # The build and the checks
./build.ps1 -Browser # With the real-browser tests
./build.ps1 -Full # The npm and NuGet packages, in artifacts/, verified as installedThe NuGet package supplies the bundle at _content/domql/domql.js, and the npm package the sources, each with its TypeScript declarations.