# Celq

> Query, filter, transform, and inspect JSON5, YAML, TOML, XML, JSON, and NDJSON with celq and readable Common Expression Language (CEL) expressions. Use for multi-format configuration data, shell pipelines, typed external input, or when jq syntax would be harder for people to maintain.

- Skill: `get-celq/celq` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add get-celq/celq`
- Raw SKILL.md: https://api.skillmd.com/api/skills/get-celq/celq/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: get-celq (https://skillmd.com/u/get-celq)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/get-celq/celq

---


# celq

Use `celq` to process structured data with Common Expression Language (CEL). Favor it for JSON5, YAML, TOML, and XML, where jq does not parse the source format itself, and when an expression should stay readable to people familiar with C-like languages.

CEL is intentionally limited, portable, and non-Turing-complete. That makes it a useful expression boundary for externally supplied queries. It does not make arbitrary shell construction safe: keep data out of the expression string and pass scalar values with typed `--arg` options.

## Choose how to invoke celq

Use an existing `celq` executable first. If it is unavailable, choose an already-installed package runner in this order when practical:

1. `npx -y celq ...`
2. `uvx celq ...`
3. `mise x conda:celq -- celq ...`

Do not permanently install celq or modify the user's global tool configuration unless the user asks.

When permanent installation is requested:

- On macOS or Linux, if Homebrew is already available, use `brew install get-celq/tap/celq`.
- For a project managed by mise, add celq to `mise.toml`:

  ```toml
  [tools]
  "conda:celq" = "latest"
  ```

In the examples below, replace `celq` with the selected runner prefix when needed.

## Use the CEL mental model

- The input root is `this`, not jq's `.`.
- Select object fields with `this.field` and list items with `this[0]`.
- Use CEL macros such as `filter`, `map`, `exists`, and `all` for collections; celq also provides `slice(start, end)` as an optional extension.
- Construct output objects with CEL map literals such as `{"name": this.name}`.
- CEL produces one value for an evaluation. Do not assume jq's stream, pipe, or generator semantics.
- Shell-quote CEL expressions so the shell does not expand them.

For example:

```bash
celq --from-json5 'this.services.filter(s, s.enabled).map(s, s.name)' < config.json5
celq --from-yaml '{"name": this.metadata.name, "replicas": this.spec.replicas}' < deployment.yaml
celq --from-toml 'this.package.version' < Cargo.toml
celq --from-xml 'this.items.item.filter(x, x["$"].id == "2")[0].name' < items.xml
```

Read [references/formats.md](references/formats.md) before working with JSON5, YAML, TOML, XML, or NDJSON. It documents the input flags and format-specific data model.

Read [references/recipes.md](references/recipes.md) for filtering, projection, predicates, external arguments, output control, and reusable expression files.

Read [references/jq-to-cel.md](references/jq-to-cel.md) when translating jq knowledge or correcting an expression that accidentally uses jq syntax.

## Handle external values safely

Do not splice untrusted data into CEL source text. Pass supported scalar values as typed arguments:

```bash
celq --arg='environment:string=production' \
  'this.services.filter(s, s.environment == environment)' < services.json
```

The supported argument types are `int`, `uint`, `float`, `bool`, and `string`. When complex external data is needed, provide it as the structured input and use a named root with `--root-var` if that makes the expression clearer.

CEL's constrained expression model is easier to reason about than a general scripting language, but shell quoting, file access, package execution, and downstream commands still need normal care.

## Preserve output intent

celq emits JSON, including when the input is JSON5, YAML, TOML, or XML.

- Use `--raw-output` only when a string must be consumed without JSON quotes.
- Use `--pretty-print` for human-facing output.
- Use `--sort-keys` when deterministic object-key order matters.
- Use `--boolean --void` when the result should control a shell branch by exit status.
- Avoid pretty-printing in the middle of NDJSON pipelines.

## Respect current boundaries

- Treat YAML support as best-effort for YAML values that map cleanly to JSON. Do not promise preservation of comments, anchors, tags, styles, or exact scalar spelling.
- XML attributes appear under the `$` map (access it as `node["$"]`), and XML scalar content is not automatically converted to numbers or booleans.
- celq parses input eagerly; reconsider it for data too large to hold comfortably in memory.
- Do not mechanically translate a complex jq program. Re-express the desired result using CEL's value and collection model.

