writing-hashql-jexpr

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).

1,481 stars

Best use case

writing-hashql-jexpr is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

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).

Teams using writing-hashql-jexpr should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/writing-hashql-jexpr/SKILL.md --create-dirs "https://raw.githubusercontent.com/hashintel/hash/main/.claude/skills/writing-hashql-jexpr/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/writing-hashql-jexpr/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How writing-hashql-jexpr Compares

Feature / Agentwriting-hashql-jexprStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

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).

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# 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:

```jsonc
"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, ...]`

```jsonc
// 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

```jsonc
{"#literal": 42}
{"#literal": "hello"}
{"#literal": true}
{"#literal": null}
{"#literal": 3.14, "#type": "Float"}
```

### Struct

```jsonc
{"#struct": {"name": {"#literal": "Alice"}, "age": {"#literal": 30}}}
{"#struct": {"x": {"#literal": 1}}, "#type": "Point"}
```

### List and Tuple

```jsonc
{"#list": [{"#literal": 1}, {"#literal": 2}]}
{"#tuple": [{"#literal": 1}, {"#literal": "text"}]}
```

### Dict

```jsonc
{"#dict": {"key": {"#literal": "value"}}}
```

## Common Patterns

### Let Binding

```jsonc
["let", "varName", {"#literal": 10}, ["add", "varName", {"#literal": 5}]]
```

### Function Definition

```jsonc
["fn", {"#tuple": []}, {"#struct": {"vertex": "_"}}, "_", body_expr]
```

### Conditionals

```jsonc
["if", condition_expr, then_expr, else_expr]
```

### Comparison

```jsonc
["==", "left", "right"]
[">", {"#literal": 5}, {"#literal": 3}]
```

## Do

- Use `#literal` for all primitive values (numbers, strings, booleans, null)
- Use `::` prefix for namespaced paths
- Use `:` prefix for labeled arguments
- Combine `#type` with 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:**

```jsonc
["::graph::head::entities", ["::graph::tmp::decision_time_now"]]
```

**Filtering with comparison:**

```jsonc
["filter", "entities", 
  ["fn", {"#tuple": []}, {"#struct": {"entity": "_"}}, "_",
    ["==", "entity.draft_id", {"#literal": null}]]]
```

**Struct with type:**

```jsonc
{"#struct": {"value": {"#literal": 100}}, "#type": "Amount"}
```

## References

- [Syntax Reference](references/syntax-reference.md) - Paths, function calls, operators
- [Special Forms](references/special-forms.md) - Language constructs (`if`, `let`, `fn`, `type`, `use`, etc.)
- [Data Constructors](references/data-constructors.md) - Typed data (`#literal`, `#struct`, `#tuple`, `#list`, `#dict`, `#type`)
- [Type DSL](references/type-dsl.md) - 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`

Related Skills

writing-hashql-diagnostics

1481
from hashintel/hash

HashQL diagnostic writing patterns using hashql-diagnostics crate. Use when creating error messages, warnings, Labels, Messages, Severity levels, Patches, Suggestions, or improving diagnostic quality in HashQL code.

testing-hashql

1481
from hashintel/hash

HashQL testing strategies including compiletest (UI tests), unit tests, and snapshot tests. Use when writing tests for HashQL code, using //~ annotations, running --bless, debugging test failures, or choosing the right testing approach.

zod

1481
from hashintel/hash

Zod v4 TypeScript schema validation patterns and best practices. Use when writing or modifying Zod schemas, adding schema annotations/metadata, or validating data with Zod.

skill-creator

1481
from hashintel/hash

Guide for creating effective Agent Skills. Use when users want to create a new skill (or update an existing skill) that extends an AI agent's capabilities with specialized knowledge, workflows, or tool integrations. Covers skill structure, YAML frontmatter, trigger configuration, and the 500-line rule.

panda-css

1481
from hashintel/hash

Panda CSS styling framework guidance. Use when working with @pandacss packages, styled components, design tokens, or responsive/conditional styles.

mastra

1481
from hashintel/hash

Mastra TypeScript framework for AI agents with memory, tools, workflows, and RAG. Use when working with @mastra/* packages or building AI agents.

managing-git-workflow

1481
from hashintel/hash

Git workflow for HASH including branch naming, PR creation, and PR reviews. Use when creating branches, making commits, opening pull requests, or reviewing PRs.

managing-cargo-dependencies

1481
from hashintel/hash

Cargo.toml dependency management patterns for HASH workspace. Use when adding, updating, or removing dependencies, organizing Cargo.toml sections, configuring version pinning and default features, or managing public dependencies.

handling-rust-errors

1481
from hashintel/hash

HASH error handling patterns using error-stack crate. Use when working with Result types, Report types, defining custom errors, propagating errors with change_context, adding context with attach, implementing Error trait, or documenting error conditions in Rust code.

exploring-rust-crates

1481
from hashintel/hash

Generate Rust documentation to understand crate APIs, structure, and usage. Use when exploring Rust code, understanding crate organization, finding functions/types/traits, or needing context about a Rust package in the HASH workspace.

documenting-rust-code

1481
from hashintel/hash

Rust documentation practices for HASH codebase. Use when writing doc comments, documenting functions/types/traits/modules, creating error sections, using intra-doc links, or following rustdoc conventions.

ark-ui

1481
from hashintel/hash

Headless component library for React. Use when building UI components with @ark-ui/react, implementing accessible form inputs, overlays, navigation patterns, or needing guidance on Ark UI's data attributes, composition (asChild), and state management patterns.