{"id":44852918,"url":"https://github.com/ikidnapmyself/react-query-builder","last_synced_at":"2026-02-17T06:33:59.755Z","repository":{"id":338120149,"uuid":"1156660891","full_name":"ikidnapmyself/react-query-builder","owner":"ikidnapmyself","description":"A composable, headless React 19 query builder component for conditional logic UIs.","archived":false,"fork":false,"pushed_at":"2026-02-12T23:15:34.000Z","size":94,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-13T07:52:37.998Z","etag":null,"topics":["bootstrap","query-builder","react","tailwindcss"],"latest_commit_sha":null,"homepage":"https://ikidnapmyself.github.io/react-query-builder/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ikidnapmyself.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-12T22:46:58.000Z","updated_at":"2026-02-12T23:15:38.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ikidnapmyself/react-query-builder","commit_stats":null,"previous_names":["ikidnapmyself/react-query-builder"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/ikidnapmyself/react-query-builder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikidnapmyself%2Freact-query-builder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikidnapmyself%2Freact-query-builder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikidnapmyself%2Freact-query-builder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikidnapmyself%2Freact-query-builder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ikidnapmyself","download_url":"https://codeload.github.com/ikidnapmyself/react-query-builder/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikidnapmyself%2Freact-query-builder/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29535987,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-17T05:00:25.817Z","status":"ssl_error","status_checked_at":"2026-02-17T04:57:16.126Z","response_time":100,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["bootstrap","query-builder","react","tailwindcss"],"created_at":"2026-02-17T06:33:59.678Z","updated_at":"2026-02-17T06:33:59.744Z","avatar_url":"https://github.com/ikidnapmyself.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# headless-react-query-builder\n\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/ikidnapmyself/react-query-builder/badges/quality-score.png?b=main)](https://scrutinizer-ci.com/g/ikidnapmyself/react-query-builder/?branch=main)\n[![Build Status](https://scrutinizer-ci.com/g/ikidnapmyself/react-query-builder/badges/build.png?b=main)](https://scrutinizer-ci.com/g/ikidnapmyself/react-query-builder/build-status/main)\n[![codecov](https://codecov.io/gh/ikidnapmyself/react-query-builder/graph/badge.svg)](https://codecov.io/gh/ikidnapmyself/react-query-builder)\n\n\nA composable, headless React 19 query builder component for conditional logic UIs.\n\nBuild complex nested conditions with AND, OR, and GROUP operations. The output is a structured JSON tree — plug it into alert managers, trading bots, IFTTT-style automations, pipeline managers, or anything that needs user-defined rules.\n\n[**Live Storybook Demo**](https://ikidnapmyself.github.io/react-query-builder/)\n\n\u003cimg width=\"923\" height=\"565\" alt=\"image\" src=\"https://github.com/user-attachments/assets/8e9ea65e-1a4c-482c-9ce4-6b7e953c6679\" /\u003e\n\u003cimg width=\"923\" height=\"238\" alt=\"image\" src=\"https://github.com/user-attachments/assets/588660a2-c223-4bda-9e8f-52faf49ca42e\" /\u003e\n\u003cimg width=\"923\" height=\"238\" alt=\"image\" src=\"https://github.com/user-attachments/assets/116700aa-3495-4eea-8226-95b644f1cc08\" /\u003e\n\n\n## Features\n\n- **Composition-first API** — hooks as the primary interface, compound components for convenience, pre-built templates for zero setup\n- **Headless by default** — bring your own markup, or use a template preset\n- **Tailwind CSS** default styling with Bootstrap and unstyled alternatives\n- **Controlled \u0026 uncontrolled** — works both ways, just like a native input\n- **TypeScript** — fully typed, all types exported\n- **Recursive nesting** — groups within groups, unlimited depth\n- **Framework-agnostic output** — plain JSON, no vendor lock-in\n\n## Installation\n\n```bash\nnpm install headless-react-query-builder\n```\n\nPeer dependencies:\n\n```bash\nnpm install react@^19.0.0 react-dom@^19.0.0\n```\n\n## Quick Start\n\n### Hooks (full control)\n\nThe primary API. You call hooks, you render whatever you want.\n\n```tsx\nimport { useQueryBuilder } from 'headless-react-query-builder';\n\nfunction MyQueryBuilder() {\n  const { query, addRule, addGroup, removeRule, updateRule, setCombinator } =\n    useQueryBuilder();\n\n  return (\n    \u003cdiv\u003e\n      \u003cselect\n        value={query.combinator}\n        onChange={(e) =\u003e setCombinator(query.id, e.target.value as 'AND' | 'OR')}\n      \u003e\n        \u003coption value=\"AND\"\u003eAND\u003c/option\u003e\n        \u003coption value=\"OR\"\u003eOR\u003c/option\u003e\n      \u003c/select\u003e\n\n      {query.rules.map((rule) =\u003e {\n        if ('combinator' in rule) {\n          return \u003cdiv key={rule.id}\u003eNested group: {rule.combinator}\u003c/div\u003e;\n        }\n        return (\n          \u003cdiv key={rule.id}\u003e\n            \u003cinput\n              value={rule.field}\n              onChange={(e) =\u003e updateRule(rule.id, { field: e.target.value })}\n              placeholder=\"Field\"\n            /\u003e\n            \u003cinput\n              value={String(rule.value)}\n              onChange={(e) =\u003e updateRule(rule.id, { value: e.target.value })}\n              placeholder=\"Value\"\n            /\u003e\n            \u003cbutton onClick={() =\u003e removeRule(rule.id)}\u003eRemove\u003c/button\u003e\n          \u003c/div\u003e\n        );\n      })}\n\n      \u003cbutton onClick={() =\u003e addRule(query.id)}\u003e+ Rule\u003c/button\u003e\n      \u003cbutton onClick={() =\u003e addGroup(query.id)}\u003e+ Group\u003c/button\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n### Component wrapper (with context)\n\nWraps `useQueryBuilder` in a provider so child components can access the query state via context.\n\n```tsx\nimport { useState } from 'react';\nimport { QueryBuilder, createEmptyGroup } from 'headless-react-query-builder';\nimport type { Group } from 'headless-react-query-builder';\n\nfunction App() {\n  const [query, setQuery] = useState\u003cGroup\u003e(createEmptyGroup);\n\n  return (\n    \u003cQueryBuilder value={query} onChange={setQuery}\u003e\n      {/* Child components can use useQueryBuilderContext() */}\n      \u003cpre\u003e{JSON.stringify(query, null, 2)}\u003c/pre\u003e\n    \u003c/QueryBuilder\u003e\n  );\n}\n```\n\n### Form submission\n\nPass a `name` prop to render a hidden input with the serialized JSON:\n\n```tsx\n\u003cform onSubmit={handleSubmit}\u003e\n  \u003cQueryBuilder name=\"query\" defaultValue={initialQuery}\u003e\n    {/* ... */}\n  \u003c/QueryBuilder\u003e\n  \u003cbutton type=\"submit\"\u003eSave\u003c/button\u003e\n\u003c/form\u003e\n```\n\nThe hidden input value will be the JSON string of the current query state.\n\n## Data Model\n\nThe query is a recursive tree of rules and groups:\n\n```typescript\ntype Rule = {\n  id: string;\n  field: string;\n  operator: string;\n  value: unknown;\n};\n\ntype Group = {\n  id: string;\n  combinator: 'AND' | 'OR';\n  rules: (Rule | Group)[];\n};\n```\n\nExample output:\n\n```json\n{\n  \"id\": \"qb-1\",\n  \"combinator\": \"AND\",\n  \"rules\": [\n    { \"id\": \"qb-2\", \"field\": \"temperature\", \"operator\": \"gt\", \"value\": 100 },\n    { \"id\": \"qb-3\", \"field\": \"status\", \"operator\": \"eq\", \"value\": \"critical\" },\n    {\n      \"id\": \"qb-4\",\n      \"combinator\": \"OR\",\n      \"rules\": [\n        { \"id\": \"qb-5\", \"field\": \"region\", \"operator\": \"eq\", \"value\": \"us-east\" },\n        { \"id\": \"qb-6\", \"field\": \"region\", \"operator\": \"eq\", \"value\": \"eu-west\" }\n      ]\n    }\n  ]\n}\n```\n\n## API Reference\n\n### `useQueryBuilder(options?)`\n\nThe primary hook. Returns the query state and all mutation functions.\n\n**Options:**\n\n| Option | Type | Description |\n|---|---|---|\n| `value` | `Group` | Controlled query value |\n| `defaultValue` | `Group` | Initial value for uncontrolled usage |\n| `onChange` | `(query: Group) =\u003e void` | Called on every change |\n| `fields` | `FieldDefinition[]` | Available fields for rules |\n| `operators` | `OperatorDefinition[]` | Available operators (defaults provided) |\n\n**Returns:**\n\n| Property | Type | Description |\n|---|---|---|\n| `query` | `Group` | Current query state |\n| `fields` | `FieldDefinition[]` | Available fields |\n| `operators` | `OperatorDefinition[]` | Available operators |\n| `addRule` | `(groupId: string) =\u003e void` | Add a rule to a group |\n| `addGroup` | `(groupId: string) =\u003e void` | Add a nested group |\n| `removeRule` | `(ruleId: string) =\u003e void` | Remove a rule |\n| `removeGroup` | `(groupId: string) =\u003e void` | Remove a group |\n| `updateRule` | `(ruleId: string, updates: Partial\u003cRule\u003e) =\u003e void` | Update a rule's field, operator, or value |\n| `setCombinator` | `(groupId: string, combinator: 'AND' \\| 'OR') =\u003e void` | Change a group's combinator |\n\n### `\u003cQueryBuilder\u003e`\n\nComponent wrapper that creates a context provider.\n\n| Prop | Type | Description |\n|---|---|---|\n| `value` | `Group` | Controlled value |\n| `defaultValue` | `Group` | Initial value (uncontrolled) |\n| `onChange` | `(query: Group) =\u003e void` | Change callback |\n| `name` | `string` | Hidden input name for form submission |\n| `fields` | `FieldDefinition[]` | Available fields |\n| `operators` | `OperatorDefinition[]` | Available operators |\n| `className` | `string` | CSS class for the root element |\n| `children` | `ReactNode` | Child components |\n\n### `useQueryBuilderContext()`\n\nAccess the query builder state from any child of `\u003cQueryBuilder\u003e`. Returns the same shape as `useQueryBuilder`.\n\n### Utilities\n\n| Export | Description |\n|---|---|\n| `createEmptyRule()` | Create a new rule with a generated ID |\n| `createEmptyGroup(combinator?)` | Create a new group (defaults to `'AND'`) |\n| `generateId()` | Generate a unique ID |\n| `isGroup(item)` | Type guard — check if a rule-or-group is a `Group` |\n| `DEFAULT_OPERATORS` | Built-in operator list (`=`, `!=`, `\u003e`, `\u003e=`, `\u003c`, `\u003c=`, `contains`, `not contains`, `between`, `in`, `not in`) |\n\n## Defining Fields\n\n```typescript\nimport type { FieldDefinition } from 'headless-react-query-builder';\n\nconst fields: FieldDefinition[] = [\n  { name: 'temperature', label: 'Temperature', type: 'number' },\n  { name: 'status', label: 'Status', type: 'select', options: [\n    { label: 'Active', value: 'active' },\n    { label: 'Inactive', value: 'inactive' },\n  ]},\n  { name: 'created_at', label: 'Created At', type: 'date' },\n  { name: 'name', label: 'Name', type: 'text' },\n];\n```\n\nSupported field types: `text`, `number`, `date`, `boolean`, `select`.\n\n## Custom Operators\n\n```typescript\nimport type { OperatorDefinition } from 'headless-react-query-builder';\n\nconst operators: OperatorDefinition[] = [\n  { name: 'eq', label: 'equals' },\n  { name: 'gt', label: 'greater than' },\n  { name: 'lt', label: 'less than' },\n  { name: 'crosses_above', label: 'crosses above' },\n  { name: 'crosses_below', label: 'crosses below' },\n];\n```\n\n## Templates\n\nThe library ships with template presets for common CSS frameworks:\n\n```tsx\n// Tailwind (default)\nimport { TailwindQueryBuilder } from 'headless-react-query-builder/templates/tailwind';\n\n// Bootstrap\nimport { BootstrapQueryBuilder } from 'headless-react-query-builder/templates/bootstrap';\n\n// Unstyled (headless, no classes)\nimport { UnstyledQueryBuilder } from 'headless-react-query-builder/templates/unstyled';\n```\n\nTemplates are built on top of the same hooks and context — they're just pre-styled component trees. You can use them as-is or as a reference for building your own.\n\n### Custom Button Labels\n\nAll templates accept a `labels` prop via the `TemplateLabels` type to customize button and combinator text:\n\n```tsx\nimport type { TemplateLabels } from 'headless-react-query-builder';\n\nconst labels: TemplateLabels = {\n  addRule: '+ Condition',\n  addGroup: '+ Sub-group',\n  removeRule: 'Delete',\n  removeGroup: 'Delete Group',\n  and: 'ALL',\n  or: 'ANY',\n};\n\n\u003cTailwindQueryBuilder fields={fields} labels={labels} onChange={handleChange} /\u003e\n```\n\nAll label fields are optional and fall back to sensible defaults (`+ Rule`, `+ Group`, `Remove`, `AND`, `OR`).\n\n## Use Cases\n\nAll use cases are available as interactive Storybook stories across all three templates (Tailwind, Bootstrap, Unstyled). Each includes a complex preset showing a realistic initial query.\n\n### Alert Manager\n\nDefine when alerts fire based on metric thresholds.\n\n```tsx\nimport { TailwindQueryBuilder } from 'headless-react-query-builder/templates/tailwind';\n\nconst fields = [\n  { name: 'cpu_usage', label: 'CPU Usage (%)', type: 'number' as const },\n  { name: 'memory_usage', label: 'Memory Usage (%)', type: 'number' as const },\n  { name: 'error_rate', label: 'Error Rate', type: 'number' as const },\n  { name: 'response_time', label: 'Response Time (ms)', type: 'number' as const },\n  { name: 'service', label: 'Service', type: 'select' as const, options: [\n    { label: 'API', value: 'api' },\n    { label: 'Worker', value: 'worker' },\n    { label: 'Database', value: 'db' },\n    { label: 'Cache', value: 'cache' },\n  ]},\n  { name: 'region', label: 'Region', type: 'select' as const, options: [\n    { label: 'US East', value: 'us-east' },\n    { label: 'US West', value: 'us-west' },\n    { label: 'EU West', value: 'eu-west' },\n  ]},\n  { name: 'is_production', label: 'Is Production', type: 'boolean' as const },\n];\n\n\u003cTailwindQueryBuilder fields={fields} onChange={saveAlertCondition} /\u003e\n```\n\n### Algorithmic Trading\n\nBuild entry/exit conditions for trading strategies.\n\n```tsx\nimport { TailwindQueryBuilder } from 'headless-react-query-builder/templates/tailwind';\n\nconst fields = [\n  { name: 'price', label: 'Price', type: 'number' as const },\n  { name: 'rsi', label: 'RSI (14)', type: 'number' as const },\n  { name: 'volume', label: 'Volume', type: 'number' as const },\n  { name: 'sma_20', label: 'SMA (20)', type: 'number' as const },\n  { name: 'ema_50', label: 'EMA (50)', type: 'number' as const },\n  { name: 'macd', label: 'MACD', type: 'number' as const },\n  { name: 'market', label: 'Market', type: 'select' as const, options: [\n    { label: 'BTC/USD', value: 'btc-usd' },\n    { label: 'ETH/USD', value: 'eth-usd' },\n    { label: 'SOL/USD', value: 'sol-usd' },\n    { label: 'AAPL', value: 'aapl' },\n  ]},\n];\n\nconst operators = [\n  { name: 'gt', label: '\u003e' },\n  { name: 'lt', label: '\u003c' },\n  { name: 'gte', label: '\u003e=' },\n  { name: 'lte', label: '\u003c=' },\n  { name: 'eq', label: '=' },\n  { name: 'crosses_above', label: 'crosses above' },\n  { name: 'crosses_below', label: 'crosses below' },\n];\n\n\u003cTailwindQueryBuilder fields={fields} operators={operators} onChange={updateStrategy} /\u003e\n```\n\n### IFTTT / Automation\n\nCompose \"if this then that\" trigger conditions.\n\n```tsx\nconst fields = [\n  { name: 'trigger', label: 'Trigger', type: 'select' as const, options: [\n    { label: 'Email received', value: 'email_received' },\n    { label: 'File uploaded', value: 'file_uploaded' },\n    { label: 'Webhook fired', value: 'webhook' },\n    { label: 'Schedule', value: 'schedule' },\n  ]},\n  { name: 'sender', label: 'Sender', type: 'text' as const },\n  { name: 'file_type', label: 'File Type', type: 'text' as const },\n  { name: 'priority', label: 'Priority', type: 'select' as const, options: [\n    { label: 'High', value: 'high' },\n    { label: 'Medium', value: 'medium' },\n    { label: 'Low', value: 'low' },\n  ]},\n  { name: 'is_recurring', label: 'Is Recurring', type: 'boolean' as const },\n];\n```\n\n### Pipeline Manager\n\nDefine branching logic and conditional steps in CI/CD pipelines.\n\n```tsx\nconst fields = [\n  { name: 'branch', label: 'Branch', type: 'text' as const },\n  { name: 'env', label: 'Environment', type: 'select' as const, options: [\n    { label: 'Production', value: 'prod' },\n    { label: 'Staging', value: 'staging' },\n    { label: 'Development', value: 'dev' },\n  ]},\n  { name: 'test_coverage', label: 'Test Coverage (%)', type: 'number' as const },\n  { name: 'has_migrations', label: 'Has Migrations', type: 'boolean' as const },\n  { name: 'label', label: 'PR Label', type: 'select' as const, options: [\n    { label: 'hotfix', value: 'hotfix' },\n    { label: 'feature', value: 'feature' },\n    { label: 'chore', value: 'chore' },\n  ]},\n];\n```\n\n### Email Filtering\n\nBuild rules for sorting, labeling, or forwarding emails.\n\n```tsx\nconst fields = [\n  { name: 'from', label: 'From', type: 'text' as const },\n  { name: 'to', label: 'To', type: 'text' as const },\n  { name: 'subject', label: 'Subject', type: 'text' as const },\n  { name: 'has_attachment', label: 'Has Attachment', type: 'boolean' as const },\n  { name: 'category', label: 'Category', type: 'select' as const, options: [\n    { label: 'Primary', value: 'primary' },\n    { label: 'Social', value: 'social' },\n    { label: 'Promotions', value: 'promotions' },\n    { label: 'Spam', value: 'spam' },\n  ]},\n  { name: 'size_kb', label: 'Size (KB)', type: 'number' as const },\n];\n```\n\n### Data Validation\n\nDefine validation rules for form fields or data imports.\n\n```tsx\nconst fields = [\n  { name: 'field_name', label: 'Field Name', type: 'select' as const, options: [\n    { label: 'Email', value: 'email' },\n    { label: 'Phone', value: 'phone' },\n    { label: 'Age', value: 'age' },\n    { label: 'Username', value: 'username' },\n  ]},\n  { name: 'value_length', label: 'Value Length', type: 'number' as const },\n  { name: 'is_required', label: 'Is Required', type: 'boolean' as const },\n  { name: 'format', label: 'Format', type: 'select' as const, options: [\n    { label: 'Email', value: 'email' },\n    { label: 'URL', value: 'url' },\n    { label: 'Phone', value: 'phone' },\n    { label: 'Numeric', value: 'numeric' },\n  ]},\n  { name: 'min_value', label: 'Min Value', type: 'number' as const },\n  { name: 'max_value', label: 'Max Value', type: 'number' as const },\n];\n```\n\n### Access Control\n\nDefine permission rules for role-based access.\n\n```tsx\nconst fields = [\n  { name: 'role', label: 'Role', type: 'select' as const, options: [\n    { label: 'Admin', value: 'admin' },\n    { label: 'Editor', value: 'editor' },\n    { label: 'Viewer', value: 'viewer' },\n    { label: 'Guest', value: 'guest' },\n  ]},\n  { name: 'resource', label: 'Resource', type: 'select' as const, options: [\n    { label: 'Dashboard', value: 'dashboard' },\n    { label: 'Users', value: 'users' },\n    { label: 'Settings', value: 'settings' },\n    { label: 'Billing', value: 'billing' },\n  ]},\n  { name: 'action', label: 'Action', type: 'select' as const, options: [\n    { label: 'Read', value: 'read' },\n    { label: 'Write', value: 'write' },\n    { label: 'Delete', value: 'delete' },\n  ]},\n  { name: 'is_2fa_enabled', label: '2FA Enabled', type: 'boolean' as const },\n];\n```\n\n### Search / Content Filtering\n\nBuild advanced search queries for content or products.\n\n```tsx\nconst fields = [\n  { name: 'title', label: 'Title', type: 'text' as const },\n  { name: 'author', label: 'Author', type: 'text' as const },\n  { name: 'category', label: 'Category', type: 'select' as const, options: [\n    { label: 'Technology', value: 'tech' },\n    { label: 'Science', value: 'science' },\n    { label: 'Business', value: 'business' },\n    { label: 'Design', value: 'design' },\n  ]},\n  { name: 'published_date', label: 'Published Date', type: 'date' as const },\n  { name: 'rating', label: 'Rating', type: 'number' as const },\n  { name: 'is_featured', label: 'Is Featured', type: 'boolean' as const },\n  { name: 'price', label: 'Price', type: 'number' as const },\n];\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Start Storybook dev server\nnpm run dev\n\n# Build the library\nnpm run build\n\n# Run tests\nnpm test\n\n# Run tests in watch mode\nnpm run test:watch\n\n# Lint\nnpm run lint\n\n# Build Storybook for deployment\nnpm run build-storybook\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fikidnapmyself%2Freact-query-builder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fikidnapmyself%2Freact-query-builder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fikidnapmyself%2Freact-query-builder/lists"}