{"id":20407562,"url":"https://github.com/sirixdb/brackit","last_synced_at":"2026-04-12T03:04:08.230Z","repository":{"id":5057068,"uuid":"6218643","full_name":"sirixdb/brackit","owner":"sirixdb","description":"Query processor with proven optimizations, ready to use for your JSON store to query semi-structured data with JSONiq. Can also be used as an ad-hoc in-memory query processor.","archived":false,"fork":false,"pushed_at":"2024-02-05T20:33:17.000Z","size":9707,"stargazers_count":48,"open_issues_count":9,"forks_count":10,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-05T09:32:40.798Z","etag":null,"topics":["clauses","hacktoberfest","java","json","json-data","json-query-engine","json-query-language","jsoniq","statement-syntax","xdm","xpath","xquery"],"latest_commit_sha":null,"homepage":"http://brackit.io","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"hassox/warden","license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sirixdb.png","metadata":{"files":{"readme":"README.MD","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2012-10-14T22:03:05.000Z","updated_at":"2024-10-05T17:26:24.000Z","dependencies_parsed_at":"2023-07-05T19:01:04.286Z","dependency_job_id":"de3b9abe-b352-45d6-bf6c-f486e2111b75","html_url":"https://github.com/sirixdb/brackit","commit_stats":{"total_commits":745,"total_committers":16,"mean_commits":46.5625,"dds":0.5100671140939597,"last_synced_commit":"e966c2f41a82ccc5cb296355f9a96c88103fb40c"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sirixdb%2Fbrackit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sirixdb%2Fbrackit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sirixdb%2Fbrackit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sirixdb%2Fbrackit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sirixdb","download_url":"https://codeload.github.com/sirixdb/brackit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248233935,"owners_count":21069493,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clauses","hacktoberfest","java","json","json-data","json-query-engine","json-query-language","jsoniq","statement-syntax","xdm","xpath","xquery"],"created_at":"2024-11-15T05:24:52.888Z","updated_at":"2026-04-12T03:04:08.224Z","avatar_url":"https://github.com/sirixdb.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build \u0026 test](https://github.com/sirixdb/brackit/actions/workflows/build.yml/badge.svg)](https://github.com/sirixdb/brackit/actions/workflows/build.yml)\r\n\r\n\u003cp align=\"center\"\u003e\r\n  \u003ch1 align=\"center\"\u003eBrackit\u003c/h1\u003e\r\n  \u003cp align=\"center\"\u003e\u003cstrong\u003eA powerful JSONiq engine for querying JSON and XML\u003c/strong\u003e\u003c/p\u003e\r\n  \u003cp align=\"center\"\u003eUse it standalone like \u003ccode\u003ejq\u003c/code\u003e, or embed it in your data store\u003c/p\u003e\r\n\u003c/p\u003e\r\n\r\n---\r\n\r\n## Why Brackit?\r\n\r\n**Two ways to use it:**\r\n\r\n1. **Command-line tool** (`bjq`) - Like `jq`, but with FLWOR expressions, joins, and user-defined functions\r\n2. **Embeddable query engine** - Add JSONiq queries to your data store with automatic optimizations\r\n\r\n```bash\r\n# Query JSON from the command line\r\necho '{\"users\": [{\"name\": \"Alice\", \"age\": 30}, {\"name\": \"Bob\", \"age\": 25}]}' | \\\r\n  bjq 'for $u in $$.users[] where $u.age \u003e 26 return $u.name'\r\n\r\n\"Alice\"\r\n```\r\n\r\n## Performance\r\n\r\nbjq native binary vs jq (wall-clock, median of 3 runs):\r\n\r\n| Query | Records | jq | bjq | Speedup |\r\n|---|---|---|---|---|\r\n| Filter (`age \u003e 30`) | 100k | 142ms | **69ms** | **2.1x** |\r\n| Group by city | 100k | 282ms | **77ms** | **3.7x** |\r\n| Filter (`age \u003e 30`) | 1M | 1.49s | **0.61s** | **2.4x** |\r\n| Group by city | 1M | 3.61s | **0.73s** | **4.9x** |\r\n\r\nMeasured on Linux x86-64. bjq native binary built with Oracle GraalVM, PGO, G1 GC, and `-O3`.\r\n\r\n## Quick Start\r\n\r\n### Option 1: Native Binary (fastest)\r\n\r\nDownload the pre-built binary for your platform:\r\n\r\n```bash\r\n# Linux (x86-64)\r\ncurl -L https://github.com/sirixdb/brackit/releases/latest/download/bjq-linux-amd64 -o bjq\r\nchmod +x bjq\r\nsudo mv bjq /usr/local/bin/\r\n\r\n# Linux (ARM64)\r\ncurl -L https://github.com/sirixdb/brackit/releases/latest/download/bjq-linux-arm64 -o bjq\r\nchmod +x bjq\r\nsudo mv bjq /usr/local/bin/\r\n\r\n# macOS (Apple Silicon)\r\ncurl -L https://github.com/sirixdb/brackit/releases/latest/download/bjq-macos-arm64 -o bjq\r\nchmod +x bjq\r\nsudo mv bjq /usr/local/bin/\r\n\r\n# macOS (Intel)\r\ncurl -L https://github.com/sirixdb/brackit/releases/latest/download/bjq-macos-amd64 -o bjq\r\nchmod +x bjq\r\nsudo mv bjq /usr/local/bin/\r\n\r\n# Windows (x86-64) - download bjq-windows-amd64.exe from GitHub Releases\r\n```\r\n\r\nThen use it:\r\n\r\n```bash\r\necho '{\"name\": \"Alice\"}' | bjq '$$.name'\r\n\r\n# FLWOR expressions - the killer feature!\r\nbjq 'for $u in $$.users[] where $u.age \u003e 21 order by $u.name return $u' data.json\r\n```\r\n\r\n### Option 2: Java Jar\r\n\r\nRequires **Java 25** or later. Download the jar from [GitHub Releases](https://github.com/sirixdb/brackit/releases), then:\r\n\r\n```bash\r\nalias bjq='java --enable-preview --add-modules=jdk.incubator.vector -jar /path/to/bjq-jar-with-dependencies.jar'\r\nbjq 'for $u in $$.users[] where $u.age \u003e 21 return $u' data.json\r\n```\r\n\r\n### Option 3: Build from Source\r\n\r\nRequires **Java 25** or later.\r\n\r\n```bash\r\ngit clone https://github.com/sirixdb/brackit.git\r\ncd brackit\r\nmvn package\r\n\r\n# Set up bjq alias\r\nalias bjq='java --enable-preview --add-modules=jdk.incubator.vector -jar '$(pwd)'/target/bjq-jar-with-dependencies.jar'\r\n\r\n# Try it out - FLWOR with grouping!\r\necho '[{\"cat\":\"A\",\"v\":1},{\"cat\":\"B\",\"v\":2},{\"cat\":\"A\",\"v\":3}]' | \\\r\n  bjq 'for $x in $$[] group by $c := $x.cat return {$c: sum($x.v)}'\r\n```\r\n\r\n## Features at a Glance\r\n\r\n| Feature | Example |\r\n|---------|---------|\r\n| **Field access** | `$$.users[0].name` |\r\n| **Array iteration** | `$$.items[].price` |\r\n| **Python-style slices** | `$$[0:5]`, `$$[-1]`, `$$[::2]` |\r\n| **Object projection** | `$${name, email}` |\r\n| **Predicates** | `$$.users[][?$$.active]` |\r\n| **FLWOR expressions** | `for $x in $$ where $x.age \u003e 21 return $x` |\r\n| **User-defined functions** | `declare function local:double($x) { $x * 2 }` |\r\n| **Automatic join optimization** | Hash-joins for FLWOR with multiple `for` clauses |\r\n| **JSON updates** | `insert`, `delete`, `replace`, `rename` |\r\n\r\n## Mutable JSON with Update Expressions\r\n\r\nBrackit supports the full JSONiq Update Facility - modify JSON data with declarative expressions:\r\n\r\n```xquery\r\n(: Insert fields into an object :)\r\ninsert json {\"status\": \"active\", \"updated\": current-dateTime()} into $user\r\n\r\n(: Append to an array :)\r\nappend json $newItem into $order.items\r\n\r\n(: Update a value :)\r\nreplace json value of $product.price with $product.price * 0.9\r\n\r\n(: Remove a field :)\r\ndelete json $user.temporaryToken\r\n\r\n(: Rename a field :)\r\nrename json $record.oldFieldName as \"newFieldName\"\r\n```\r\n\r\nThis makes Brackit ideal for data stores that need to expose update capabilities through a query language.\r\n\r\n## The Power of FLWOR\r\n\r\nUnlike simple path-based query languages, Brackit supports full **FLWOR expressions** (for, let, where, order by, return) - the SQL of JSON:\r\n\r\n```xquery\r\n(: Group sales by category and compute totals :)\r\nfor $sale in $$.sales[]\r\nlet $cat := $sale.category\r\ngroup by $cat\r\norder by sum($sale.amount) descending\r\nreturn {\r\n  \"category\": $cat,\r\n  \"total\": sum($sale.amount),\r\n  \"count\": count($sale)\r\n}\r\n```\r\n\r\n```xquery\r\n(: Join orders with customers - automatically optimized! :)\r\nfor $order in $$.orders[], $customer in $$.customers[]\r\nwhere $order.customer_id eq $customer.id\r\nreturn {\r\n  \"order\": $order.id,\r\n  \"customer\": $customer.name,\r\n  \"total\": $order.total\r\n}\r\n```\r\n\r\n## bjq: The jq Alternative\r\n\r\n`bjq` provides a familiar jq-like interface with JSONiq power:\r\n\r\n```bash\r\n# Basic field access\r\nbjq '$$.name' data.json\r\n\r\n# Array operations\r\nbjq '$$.users[].email' data.json\r\nbjq '$$[0:5]' data.json              # First 5 elements\r\nbjq '$$[-1]' data.json               # Last element\r\n\r\n# Filtering\r\nbjq 'for $u in $$.users[] where $u.active return $u' data.json\r\n\r\n# Aggregation\r\nbjq 'sum($$.prices[])' data.json\r\n\r\n# Raw output (no quotes)\r\nbjq -r '$$.name' data.json\r\n\r\n# Compact output\r\nbjq -c '$$' data.json\r\n```\r\n\r\n## Embed in Your Data Store\r\n\r\nBrackit is designed as a **retargetable query compiler**. Data stores can plug in their own:\r\n\r\n- **Physical optimizations** (index scans, specialized operators)\r\n- **Storage backends** (your custom Node/Item implementations)\r\n- **Rewrite rules** (index matching, predicate pushdown)\r\n\r\n```java\r\n// Minimal example: run a query in Java\r\nQueryContext ctx = new BrackitQueryContext();\r\nQuery query = new Query(\"for $i in 1 to 10 return $i * $i\");\r\nquery.serialize(ctx, System.out);\r\n```\r\n\r\nThe optimizer automatically applies:\r\n- Hash-joins for multi-variable FLWOR expressions\r\n- Predicate pushdown\r\n- Constant folding\r\n- And more...\r\n\r\n## Installation\r\n\r\n### Maven\r\n\r\n```xml\r\n\u003cdependency\u003e\r\n  \u003cgroupId\u003eio.sirix\u003c/groupId\u003e\r\n  \u003cartifactId\u003ebrackit\u003c/artifactId\u003e\r\n  \u003cversion\u003e0.7\u003c/version\u003e\r\n\u003c/dependency\u003e\r\n```\r\n\r\n### Gradle\r\n\r\n```groovy\r\ndependencies {\r\n    implementation 'io.sirix:brackit:0.7'\r\n}\r\n```\r\n\r\n## JSONiq Syntax\r\n\r\n### Arrays\r\n\r\n```xquery\r\n[ 1, 2, 3 ]                          (: literal array :)\r\n[ =(1 to 5) ]                        (: spread: [1, 2, 3, 4, 5] :)\r\n$arr[0]                              (: index access (0-based!) :)\r\n$arr[-1]                             (: last element :)\r\n$arr[1:3]                            (: slice :)\r\n$arr[]                               (: unbox to sequence :)\r\n```\r\n\r\n### Objects\r\n\r\n```xquery\r\n{ \"name\": \"Alice\", \"age\": 30 }       (: literal object :)\r\n$obj.name                            (: field access :)\r\n$obj{name, age}                      (: projection :)\r\n{ $obj1, $obj2 }                     (: merge objects :)\r\n```\r\n\r\n### Updates (for mutable stores)\r\n\r\n```xquery\r\ninsert json {\"new\": \"field\"} into $obj\r\ndelete json $obj.field\r\nreplace json value of $obj.name with \"Bob\"\r\nrename json $obj.old as \"new\"\r\n```\r\n\r\n## Differences from Standard JSONiq\r\n\r\n- Array indexes start at **0** (not 1)\r\n- Object projection: `$obj{field1, field2}` instead of `jn:project()`\r\n- Python-style array slices: `$arr[start:end:step]`\r\n- Statement syntax with semicolons (syntactic sugar for let-bindings)\r\n\r\n## Community\r\n\r\nJoin us on [Discord](https://discord.gg/AstddxGxjP) to ask questions, share ideas, or contribute!\r\n\r\n## Used By\r\n\r\n- [SirixDB](https://github.com/sirixdb/sirix) - A bitemporal, append-only database storing JSON and XML with full version history at the node level\r\n\r\n## Origins \u0026 Publications\r\n\r\nBrackit was created by [Sebastian Bächle](http://wwwlgis.informatik.uni-kl.de/cms/index.php?id=team) during his PhD at TU Kaiserslautern, researching query processing for semi-structured data. It's now maintained as part of the SirixDB project.\r\n\r\n- [Separating Key Concerns in Query Processing](http://wwwlgis.informatik.uni-kl.de/cms/fileadmin/publications/2013/Dissertation-Baechle.pdf) - Ph.D thesis by Dr. Sebastian Bächle\r\n- [Unleashing XQuery for Data-independent Programming](http://wwwlgis.informatik.uni-kl.de/cms/fileadmin/publications/2014/Unleash.2014.pdf)\r\n- [XQuery Processing over NoSQL Stores](http://wwwlgis.informatik.uni-kl.de/cms/fileadmin/publications/2013/ValerGvD2013.pdf)\r\n\r\n## License\r\n\r\n[New BSD License](LICENSE)\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsirixdb%2Fbrackit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsirixdb%2Fbrackit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsirixdb%2Fbrackit/lists"}