Skip to content

Lexicons

How-to

Read first: getting-started/project-structure

This page adds a record lexicon to your project, so your instance starts indexing that collection, and shows the other ways a lexicon can reach an instance.

A lexicon is a schema, and HappyView reads three kinds:

  • A record lexicon describes a kind of record. HappyView indexes every record of that collection it sees.
  • A query lexicon or procedure lexicon describes an endpoint. HappyView serves it at /xrpc/<NSID>; Queries and procedures covers those.

The examples use Statusphere’s xyz.statusphere.status: a status emoji a user sets on their account.

A lexicon’s file path is its NSID: xyz.statusphere.status lives at src/lexicons/xyz/statusphere/status.json.

{
"lexicon": 1,
"id": "xyz.statusphere.status",
"defs": {
"main": {
"type": "record",
"key": "tid",
"record": {
"type": "object",
"required": ["status", "createdAt"],
"properties": {
"status": { "type": "string", "minLength": 1, "maxGraphemes": 1, "maxLength": 32 },
"createdAt": { "type": "string", "format": "datetime" }
}
}
}
}
}

Save it while hpy happyview dev runs. The instance rebuilds and starts listening to Jetstream for xyz.statusphere.status records. Each one that arrives is indexed: open Data > Records in the local dashboard to watch them come in.

If the id doesn’t match the path, the build fails and tells you where the file should be.

Indexing starts from now: records written before your instance started listening aren’t fetched unless you ask for a backfill. Turn it on for a lexicon in happyview.toml:

[lexicons."xyz.statusphere.status"]
backfill = true

A backfill finds every account with records in that collection and fetches them from each account’s PDS. It runs once per collection: when you deploy, or at an instance’s next start, and not again after that. Backfill covers watching one and running it again.

A local instance doesn’t backfill unless you also set backfill = true under [dev], so developing doesn’t crawl the network every time you start.

Many lexicons are already published by their authors, such as Bluesky’s app.bsky.feed.post. You don’t need a copy in your project: list it under [network_lexicons] and the instance fetches it from the network and keeps it up to date.

[network_lexicons]
include = ["app.bsky.feed.post"]

A network lexicon is indexed like your own, but it never backfills on its own; start one from Data > Backfill if you want history. Only lexicons in your project can have record scripts beside them, because a script’s path names its lexicon.

An operator can also add a lexicon to an instance in the dashboard, under Data > Lexicons, or through the admin API. Those uploaded lexicons live in that instance’s database, not in your project. When a project file and an uploaded lexicon have the same NSID, the project’s wins, and the dashboard refuses to change or delete it.

Delete the file and the instance stops indexing that collection. The records it already indexed stay; deleting them is a separate step under Data > Records.