writing-hashql-jexpr
Reference and syntax guide for HashQL J-Expr to define paths, function calls, and data structures in .jsonc query files.
Install
mkdir -p .claude/skills/writing-hashql-jexpr && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/2726" && unzip -o skill.zip -d .claude/skills/writing-hashql-jexpr && rm skill.zipInstalls to .claude/skills/writing-hashql-jexpr
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
HashQL J-Expr syntax for writing queries. Use when writing J-Expr code, using #literal/#struct/#list constructs, understanding function call syntax, or working with HashQL query files (.jsonc).Key capabilities
- →Represent typed expressions using JSON primitives
- →Construct data using #literal, #struct, #list, #tuple, #dict
- →Define function calls as arrays
- →Map strings to paths or identifiers
- →Apply type annotations with #type
How it works
J-Expr uses JSON structures where strings represent paths, arrays represent function calls, and objects with specific # keys act as data constructors. It enforces strict typing by requiring primitives to be wrapped in #literal objects.
Inputs & outputs
When to use writing-hashql-jexpr
- →Writing HashQL query expressions
- →Parsing J-Expr syntax
- →Constructing JSONC query files
About this skill
Writing HashQL J-Expr
J-Expr is a JSON-based expression syntax for HashQL. It represents typed expressions using JSON primitives.
Expression Types
J-Expr has three expression types:
| JSON Type | J-Expr Meaning |
|---|---|
| String | Path/identifier/symbol |
| Array | Function call |
| Object | Data constructor (with # keys) |
Paths (Strings)
Strings are parsed as paths or identifiers:
"x" // Simple variable
"vertex.id.entity_id" // Dotted path access
"::core::types::String" // Namespaced/rooted path
"::graph::head::entities" // Graph function path
Function Calls (Arrays)
Arrays represent function calls: [function, arg1, arg2, ...]
// Basic function call
["add", {"#literal": 1}, {"#literal": 2}]
// Namespaced function
["::graph::head::entities", ["::graph::tmp::decision_time_now"]]
// Labeled argument with :prefix in object
["greet", {":name": {"#literal": "Alice"}}]
// Shorthand labeled argument (string with :prefix)
["func", ":name"]
Data Constructors (Objects with # Keys)
Objects with special # keys construct data:
| Key | Purpose | Example |
|---|---|---|
#literal | Primitive values | {"#literal": 42} |
#struct | Named fields | {"#struct": {"x": ...}} |
#list | Variable-size ordered | {"#list": [...]} |
#tuple | Fixed-size ordered | {"#tuple": [...]} |
#dict | Key-value map | {"#dict": {"k": ...}} |
#type | Type annotation | Used with other keys |
Literals
{"#literal": 42}
{"#literal": "hello"}
{"#literal": true}
{"#literal": null}
{"#literal": 3.14, "#type": "Float"}
Struct
{"#struct": {"name": {"#literal": "Alice"}, "age": {"#literal": 30}}}
{"#struct": {"x": {"#literal": 1}}, "#type": "Point"}
List and Tuple
{"#list": [{"#literal": 1}, {"#literal": 2}]}
{"#tuple": [{"#literal": 1}, {"#literal": "text"}]}
Dict
{ "#dict": { "key": { "#literal": "value" } } }
Common Patterns
Let Binding
["let", "varName", { "#literal": 10 }, ["add", "varName", { "#literal": 5 }]]
Function Definition
["fn", {"#tuple": []}, {"#struct": {"vertex": "_"}}, "_", body_expr]
Conditionals
["if", condition_expr, then_expr, else_expr]
Comparison
["==", "left", "right"]
[">", {"#literal": 5}, {"#literal": 3}]
Do
- Use
#literalfor all primitive values (numbers, strings, booleans, null) - Use
::prefix for namespaced paths - Use
:prefix for labeled arguments - Combine
#typewith other constructors for type annotations
Don't
- Don't use bare JSON numbers/booleans - wrap in
{"#literal": ...} - Don't confuse
#list(variable-size) with#tuple(fixed-size) - Don't use
#prefix for labeled arguments (use:) - Don't nest
#keys incorrectly - each object should have one primary#key
Examples
Entity query:
["::graph::head::entities", ["::graph::tmp::decision_time_now"]]
Filtering with comparison:
[
"filter",
"entities",
[
"fn",
{ "#tuple": [] },
{ "#struct": { "entity": "_" } },
"_",
["==", "entity.draft_id", { "#literal": null }],
],
]
Struct with type:
{ "#struct": { "value": { "#literal": 100 } }, "#type": "Amount" }
References
- Syntax Reference - Paths, function calls, operators
- Special Forms - Language constructs (
if,let,fn,type,use, etc.) - Data Constructors - Typed data (
#literal,#struct,#tuple,#list,#dict,#type) - Type DSL - Embedded type annotation syntax
- Parser:
libs/@local/hashql/syntax-jexpr/src/parser/ - Object forms:
libs/@local/hashql/syntax-jexpr/src/parser/object/ - Type DSL:
libs/@local/hashql/syntax-jexpr/src/parser/string/type.rs
When not to use it
- →When writing standard JSON without HashQL requirements
- →When using bare JSON numbers or booleans
Limitations
- →Requires wrapping all primitives in #literal
- →Strict distinction between #list and #tuple
How it compares
It provides a structured, typed expression syntax for JSON-based queries compared to writing raw, untyped JSON objects.
Compared to similar skills
writing-hashql-jexpr side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| writing-hashql-jexpr (this skill) | 2 | 2mo | No flags | Advanced |
| backend-development | 17 | 4mo | No flags | Intermediate |
| laravel-specialist | 12 | 3mo | No flags | Intermediate |
| supabase-python | 0 | 4mo | Review | Advanced |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by hashintel
View all by hashintel →You might also like
backend-development
skillcreatorai
Backend API design, database architecture, microservices patterns, and test-driven development. Use for designing APIs, database schemas, or backend system architecture.
laravel-specialist
Jeffallan
Use when building Laravel 10+ applications requiring Eloquent ORM, API resources, or queue systems. Invoke for Laravel models, Livewire components, Sanctum authentication, Horizon queues.
supabase-python
alinaqi
FastAPI with Supabase and SQLAlchemy/SQLModel
pagination
dadbodgeoff
Implement cursor-based and offset pagination for APIs. Covers efficient database queries, stable sorting, and pagination metadata.
evernote-data-handling
jeremylongshore
Best practices for handling Evernote data. Use when implementing data storage, processing notes, handling attachments, or ensuring data integrity. Trigger with phrases like "evernote data", "handle evernote notes", "evernote storage", "process evernote content".
using-neon
davila7
Guides and best practices for working with Neon Serverless Postgres. Covers getting started, local development with Neon, choosing a connection method, Neon features, authentication (@neondatabase/auth), PostgREST-style data API (@neondatabase/neon-js), Neon CLI, and Neon's Platform API/SDKs. Use for any Neon-related questions.