A small, independent filter query language shared by search boxes, saved views and smart lists across every Hollow app, and by the routing rules that file incoming work on the Tasks API. HollowScript embeds it as the Filter type, written between backticks, but HEL has no knowledge of HollowScript and works anywhere Hollow needs a query someone can type and get right first time.
Syntax
status:todo priority>=high -tag:chore
due<today+7 OR (assignee:none AND starred)
Open, high-priority-or-above, and not tagged chore, on line one.
Due within a week, or unassigned and starred, on line two.
Reads left to right. No query builder, no separate mode to learn.
The grammar is: an OR of AND terms; a space between terms is implicit AND; a leading - or NOT negates; parentheses group. Parsing never throws: a half-finished query still returns a best-effort result, so a search box can filter live on every keystroke.
Operators and values
Operators
: equals, contains (for text fields) or is a member of (for multi-value fields); = and != exact; < > <= >= for dates, numbers and ranked fields such as priority.
Values
Words, "quoted phrases", numbers, dates as 2026-07-01, inclusive date ranges as a..b, and relative dates as today, tomorrow, yesterday, today+7, today-3.
Combining
A space is AND. OR and AND are case-insensitive keywords; AND is optional and never required. A leading - or NOT excludes. Parentheses group, so precedence is never ambiguous.
Bare terms
A word with no field name is a free-text search across whatever fields the app exposes for full-text matching. A bare word that names a boolean field (such as starred) tests that field directly.
Quoting
"a phrase with spaces" is a single term. Quoted values skip date and number classification and are matched as literal strings. There is no escape character inside a quoted value.
Dates, ranges and sentinels
HEL has no function-call syntax and is not Turing-complete: that is deliberate. A handful of built-in tokens cover the cases a filter actually needs.
today
Resolves to the current date at query time. today+7 and today-1 offset by days. tomorrow and yesterday are equivalent to today+1 and today-1. Offsets beyond ±5000 days fall through to a plain string match.
a..b
An inclusive date range. Both ends may be absolute dates or relative dates.
none
Matches a field that has no value set: due:none means no due date.
any
Matches a field that has any value set: tag:any means at least one tag is present. Equivalent to -tag:none.
What each field name means and which values rank like priority is defined once per app; HEL itself has no idea what a task or a bill is. An unknown field in a predicate does not cause an error: it falls back to a free-text match on the raw token. A query with nesting deeper than 1000 parenthesis levels or negation chains stops descending and records an error rather than overflowing the parser's own call stack.