{"id":22394090,"url":"https://github.com/flant/libjq-go","last_synced_at":"2025-07-31T10:32:27.303Z","repository":{"id":56079453,"uuid":"222965212","full_name":"flant/libjq-go","owner":"flant","description":"CGO bindings for jq with cache for compiled programs","archived":false,"fork":false,"pushed_at":"2020-11-26T17:16:29.000Z","size":68,"stargazers_count":15,"open_issues_count":5,"forks_count":8,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-07T00:41:32.044Z","etag":null,"topics":["cgo-bindings","golang","jq"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flant.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-11-20T15:12:37.000Z","updated_at":"2024-02-19T18:00:12.000Z","dependencies_parsed_at":"2022-08-15T12:41:05.514Z","dependency_job_id":null,"html_url":"https://github.com/flant/libjq-go","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/flant/libjq-go","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flant%2Flibjq-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flant%2Flibjq-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flant%2Flibjq-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flant%2Flibjq-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flant","download_url":"https://codeload.github.com/flant/libjq-go/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flant%2Flibjq-go/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268024583,"owners_count":24183149,"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","status":"online","status_checked_at":"2025-07-31T02:00:08.723Z","response_time":66,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["cgo-bindings","golang","jq"],"created_at":"2024-12-05T05:08:58.494Z","updated_at":"2025-07-31T10:32:27.062Z","avatar_url":"https://github.com/flant.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\u003ca href=\"https://hub.docker.com/r/flant/jq\"\u003e\u003cimg src=\"https://img.shields.io/docker/pulls/flant/jq.svg?logo=docker\" alt=\"docker pull flant/jq\"/\u003e\u003c/a\u003e\n\u003ca href=\"https://community.flant.com/c/shell-operator/7\"\u003e\u003cimg src=\"https://img.shields.io/discourse/status?server=https%3A%2F%2Fcommunity.flant.com\" alt=\"Discourse forum for discussions\"/\u003e\u003c/a\u003e\n\u003ca href=\"https://t.me/kubeoperator\"\u003e\u003cimg src=\"https://img.shields.io/badge/telegram-RU%20chat-179cde.svg?logo=telegram\" alt=\"Telegram chat RU\"/\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n# libjq-go\n\nCGO bindings for jq with cache for compiled programs and ready-to-use static builds of libjq.\n\nNo dependencies in go.mod! :+1:\n\n## Usage\n\n```\nimport (\n  \"fmt\"\n  . \"github.com/flant/libjq-go\" // import Jq() shortcut\n)\n\nfunc main() {\n\t// 1. Run one jq program with one input.\n\tres, err = Jq().Program(\".foo\").Run(`{\"foo\":\"bar\"}`)\n\n\t// 2. Use directory with jq modules.\n\tres, err = Jq().WithLibPath(\"./jq_lib\").\n\t\tProgram(`....`).\n\t\tRun(`...`)\n\t\n\t// 3. Use program text as a key for a cache.\n\tfor _, data := range inputJsons {\n\t\tres, err = Jq().Program(\".foo\").Cached().Run(data)\n\t\t// Do something with result ...\n\t}\n\t\n\t// 4. Explicitly precompile jq expression to speed up processing of multiple inputs.\n\tprg, err := Jq().Program(\".foo\").Precompile()\n\tfor _, data := range inputJsons {\n\t\tres, err = prg.Run(data)\n\t\t// Do something with result ...\n\t}\n\t\n\t// 5. It is safe to use Jq() from multiple go-routines.\n\t//    Note however that programs are executed synchronously.\n\tgo func() {\n\t\tres, err = Jq().Program(\".foo\").Run(`{\"foo\":\"bar\"}`)\n\t}()\n\tgo func() {\n\t\tres, err = Jq().Program(\".foo\").Cached().Run(`{\"foo\":\"bar\"}`)\n\t}()\n}\n```\n\nThe full code is available in [example.go](./examples/simple/example.go).\n\n\n# Build\n\n## 1. Local build\n\nThe recommended and fastest way to build your program with libjq-go is to use prebuilt libjq static libraries, available in [Releases](https://github.com/flant/libjq-go/releases). See [local-build](./examples/local-build) example for inspiration.\n\n```\nwget https://github.com/flant/libjq-go/releases/download/jq-b6be13d5-0/libjq-glibc-amd64.tgz\ntar zxf libjq-glibc-amd64.tgz\nCGO_ENABLED=1 \\\nCGO_CFLAGS=\"-I./libjq/include\" \\\nCGO_LDFLAGS=\"-L./libjq/lib\" \\\ngo build example.go\n```\n\nAlso, you can use libjq in a form of dynamic library available in your OS or build static library from jq sources. Either way, read below about jq sources and performance issues.\n\n### MacOS with brewed jq\n\n```\nbrew install jq\nCGO_ENABLED=1 go build example.go\n```\n\n## 2. Docker build\n\nThe recommended way for docker build is to use static libjq from [flant/jq](https://hub.docker.com/repository/docker/flant/jq) image available on hub.docker.com.\n\n```\nFROM flant/jq:b6be13d5-musl as libjq\n\nFROM golang:1.15-alpine as builder\n...\nCOPY --from=libjq /libjq /app/libjq/\n...\nRUN ... go build example.go\n\n# Final image\nFROM alpine:3.12\nCOPY --from=builder ...\n```\n\nFull source is available in [simple](./examples/simple) example.\n\nIf prebuilt libjq is not an option, you can build static libjq in a separate image and then copy libjq to 'go builder' image. See this approach in a [Dockerfile](https://github.com/flant/shell-operator/blob/v1.0.0-beta.13/Dockerfile) of `flant/shell-operator` project.\n\n## 3. Static build\n\nGo can produce static binaries with CGO enabled. You should use static build of libjq and add -ldflags to `go build` command.\n\n```\nFROM flant/jq:b6be13d5-musl as libjq\n\nFROM golang:1.15-alpine as builder\n...\nCOPY --from=libjq /libjq /app/libjq/\n...\nRUN CGO_ENABLED=1 ... \\\n    go build \\\n    -ldflags=\"-linkmode external -extldflags '-static' -s -w\" \\\n    example.go\n\n# Final image\nFROM alpine:3.12\nCOPY --from=builder ...\n```\n\nSee [docker-static-build](./examples/docker-static-build) example.\n\n# Notes\n\n## jq source compatibility and jq 1.6 performance\n\nTL;DR\n\n- If your program works as a cli filter for one jq expression (like `jq` command itself) you can use any commit from `stedolan/jq`.\n- If your program works as a server and process many jq expressions, consider use b6be13d5 commit and prebuilt libjq assets.\n\nLong story:\n\nThis library was tested with jq-1.5, jq-1.6 and with some commits from master branch. The submodule `jq` in this repository points to unreleased commit [stedolan/jq@b6be13d5](https://github.com/stedolan/jq/commit/b6be13d5de6dd7d8aad5fd871eb6b0b30fc7d7f6).\n\nWhich commit should you choose? Take these considerations into account:\n\n- jq-1.5 works good, but it lucks new features.\n- jq-1.6 turns out to be slow, see: [stedolan/jq#2069](https://github.com/stedolan/jq/issues/2069) and [flant/libjq-go#10](https://github.com/flant/libjq-go/issues/10).\n- latest master have problem with `fromjson` and `tonumber` [stedolan/jq#2091](https://github.com/stedolan/jq/issues/2091).\n- [stedolan/jq@b6be13d5](https://github.com/stedolan/jq/commit/b6be13d5de6dd7d8aad5fd871eb6b0b30fc7d7f6) is a commit that has features of v1.6 and a good performance and correctly handles errors in `fromjson`.\n\n\n## Go compatibility\n\nlibjq-go is known to work with Go 1.11 and later versions.\n\n## prebuilt libjq\n\nFor faster builds we publish prebuilt libjq static libraries (and jq command) in [flant/jq](https://hub.docker.com/repository/docker/flant/jq) repository on hub.docker.com. Also, there are assets in jq-* [releases](https://github.com/flant/libjq-go/releases) in this repo on github.\n\n`glibc` build is known to work in debian:stretch, debian:buster, ubuntu:18.04, ubuntu:20.04 (and seems to work in alpine).\n\n`musl` build is known to work in alpine:3.7+ (You can even compile your program using `golang:1.11-alpine3.7`!)\n\n## Inspired projects\n\nThere are other `jq` bindings in Go:\n\n- https://github.com/aki017/gq\n- https://github.com/bongole/go-jq\n- https://github.com/mgood/go-jq\n- https://github.com/threatgrid/jq-go\n- https://github.com/mattatcha/jq\n- https://github.com/jzelinskie/faq\n\nAlso these projects was very helpful in understanding jq sources:\n\n- https://github.com/robertaboukhalil/jqkungfu\n- https://github.com/doloopwhile/pyjq\n\n\n## License\n\nApache License 2.0, see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflant%2Flibjq-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflant%2Flibjq-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflant%2Flibjq-go/lists"}