gnata-sqlite
Tutorials

React Widget

Build a JSONata editor into your React app with hooks, components, and live evaluation

React Widget Tutorial

Build a JSONata editor into a React app with syntax highlighting, autocomplete, hover docs, and live evaluation.

This is what the finished editor looks like — try editing the expression:

Expression
Input
Result
Loading WASM...

Prerequisites

  • Node.js 18+
  • React 18+ project

Step 1: Install

npm install @gnata-sqlite/react

Step 2: Copy LSP WASM to public

The package ships pre-built WASM binaries for the editor LSP (autocomplete, diagnostics, hover). Copy them to your app's public directory:

npx @gnata-sqlite/react setup ./public

This copies gnata-lsp.wasm (380 KB, 145 KB gzipped) and lsp-wasm_exec.js (16 KB) into public/.

Step 3: Editor with full language support

The useJsonataLsp hook loads the LSP WASM automatically — no configuration needed:

import { JsonataEditor, useJsonataLsp, useJsonataSchema } from '@gnata-sqlite/react'
import { useState } from 'react'

export default function App() {
  const [expression, setExpression] = useState('Account.Name')
  const [inputJson] = useState('{"Account":{"Name":"Firefly"}}')

  const lsp = useJsonataLsp()
  const schema = useJsonataSchema(inputJson)

  return (
    <JsonataEditor
      value={expression}
      onChange={setExpression}
      schema={schema}
      gnataDiagnostics={lsp.gnataDiagnostics}
      gnataCompletions={lsp.gnataCompletions}
      gnataHover={lsp.gnataHover}
      theme="dark"
    />
  )
}

Step 4: Custom layout with individual components

import {
  JsonataEditor, JsonataInput, JsonataResult,
  useJsonataLsp, useJsonataSchema,
} from '@gnata-sqlite/react'
import { useState } from 'react'

export default function CustomEditor() {
  const [expression, setExpression] = useState('Account.Name')
  const [inputJson, setInputJson] = useState('{"Account":{"Name":"Firefly"}}')

  const lsp = useJsonataLsp()
  const schema = useJsonataSchema(inputJson)

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
      <JsonataEditor
        value={expression} onChange={setExpression}
        schema={schema}
        gnataDiagnostics={lsp.gnataDiagnostics}
        gnataCompletions={lsp.gnataCompletions}
        gnataHover={lsp.gnataHover}
        theme="dark"
        getInputJson={() => inputJson}
      />
      <JsonataInput value={inputJson} onChange={setInputJson} theme="dark" />
    </div>
  )
}

Step 5: Client-side evaluation (optional)

For the rare case where evaluation must run in the browser, load the full eval engine (~5.3MB). This is opt-in — most apps evaluate server-side.

import {
  JsonataPlayground,
  useJsonataWasm, useJsonataEval, useJsonataSchema,
} from '@gnata-sqlite/react'

// Evaluation engine must be built from source and served separately:
//   make wasm
//   cp gnata.wasm wasm_exec.js public/
const wasm = useJsonataWasm({
  evalWasmUrl: '/gnata.wasm',
  evalExecUrl: '/wasm_exec.js',
})
const { result, error, timing } = useJsonataEval(expr, inputJson, wasm.gnataEval)

Or use the all-in-one playground component:

<JsonataPlayground
  defaultExpression="$sum(Account.Order.Product.(Price * Quantity))"
  defaultInput={sampleData}
  wasmOptions={{
    evalWasmUrl: '/gnata.wasm',
    evalExecUrl: '/wasm_exec.js',
  }}
  theme="dark"
  height={400}
/>

Step 6: Syntax highlighting only (no WASM)

<JsonataEditor value={expression} onChange={setExpression} theme="dark" />

No WASM function props = no WASM loading. Highlighting works instantly with the tokenizer only.

Next Steps

On this page