```{asciicast, load}

| include: FALSE

library(tsitter)

In this document I show examples with the `tsjsonc` package.

### Create a tree-sitter tree

Create a ts_tree (ts_tree_jsonc) object from a string:

```{asciicast, data}
#| results: "hide"
txt <- r"(
// this is a comment
{
  "a": {
    "a1": [1, 2, 3],
    // comment
    "a2": "string"
  },
  "b": [
    {
      "b11": true,
      "b12": false
    },
    {
      "b21": false,
      "b22": false
    }
  ]
}
)"

json <- tsjsonc::ts_parse_jsonc(txt)

Pretty print a ts_tree object:

#| label: print-json
json

Select nodes of a tree

Selecting nodes is the basis of editing and querying tree-sitter trees.

Select element by objects key:

#| label: select-key
ts_tree_select(json, "a")

Select element inside element:

#| label: select-select
ts_tree_select(json, "a", "a1")

Select element(s) of an array:

#| label: select-array
ts_tree_select(json, "a", "a1", 1:2)

Select multiple keys from an object:

#| label: select-multiple
ts_tree_select(json, "a", c("a1", "a2"))

Select nodes that match a tree-sitter query:

#| label: select-query
json |> ts_tree_select(query = "((pair value: (false) @val))")

Delete elements

Delete selected elements:

#| label: delete
ts_tree_select(json, "a", "a1") |> ts_tree_delete()

Insert elements

Insert element into an array:

#| label: insert-array
ts_tree_select(json, "a", "a1") |> ts_tree_insert(at = 2, "new")

Inserting into an array reformats the array.

Insert element into an object, at the specified key:

#| label: insert-object
ts_tree_select(json, "a") |>
  ts_tree_insert(key = "a0", at = 0, list("new", "element"))

Update elements

Update existing element:

#| label: update
ts_tree_select(json, "a", c("a1", "a2")) |> ts_tree_update("new value")

Inserts the element if some parents are missing:

#| label: update-insert
json <- ts_parse_jsonc(text = "{ \"a\": { \"b\": true } }")
json
#| label: update-insert-2
ts_tree_select(json, "a", "x", "y") |> ts_tree_update(list(1,2,3))

Write out a document

Use stdout() to write it to the screen instread of a file:

#| label: write
json |> ts_tree_write(stdout())

Formatting

Format the whole document:

#| label: format
json |> ts_tree_format()

Format part of the document:

#| label: format-part
json |> ts_tree_select("a") |>
  ts_tree_format(options = list(format = "compact"))

Unserializing

Unserialize a whole document:

#| label: unserialize
json |> ts_tree_unserialize()

Note that ts_tree_unserialize() always returns a list, the first element of the list is the unserialized document.

Unserialize part(s) of the document:

#| label: unserialize-part
json |> ts_tree_select("b") |> ts_tree_unserialize()

Again, ts_tree_unserialize() returns a list, with one element for each selected node.

Exploring a tree-sitter tree

It is often useful to explore the structure of a (JSONC) tree-sitter tree, to help writing the right selection or tree-sitter queries.

Print the annotated syntax tree:

#| label: syntax-tree
ts_tree_ast(json)

Print the document object model:

#| label: document-model
ts_tree_dom(json)

Print the structural summary of a tree:

#| label: structure
#| asciicast_rows: 7
ts_tree_sexpr(json)


Try the pak package in your browser

Any scripts or data that you put into this service are public.

pak documentation built on June 7, 2026, 9:06 a.m.