---
name: terset
description: Read or write Terset, a terse table format for JSON records in LLM prompts. Use when a prompt holds lists of objects that share keys (users, orders, rows, logs) and tokens matter, when text has tab-separated header and row lines, or when someone mentions Terset or terset.dev. Not for config with no lists, tiny payloads, or model output.
---

# Terset

Terset writes a set of JSON records as one terse table. A model reads the same data with fewer tokens. Decoding gives the same JSON back.

This is a skill file. Any agent harness that loads skill files can use it.

## Install

The package is `@stackdeck/terset` 0.1.1 on npm, MIT. Source: https://github.com/TrueWear/terset. Node 20 or later.

`pnpm add @stackdeck/terset` (or npm, yarn, bun). The only real package is `@stackdeck/terset`. Do not install a similar name.

## Encode

The package exports `encode`, `decode` and `RULES`.

```js
import { encode, decode, RULES } from "@stackdeck/terset";
const system = RULES; // once, in the system prompt
const text = encode(data); // in the user message
```

Never write Terset by hand. Always use `encode`. Put the rules sentence in the system prompt once:

```text
Tables use tab-separated headers and rows. Empty cells mean absent. JSON quotes distinguish numeric, boolean or null text from scalars. Nested cells use JSON. A leading bare id header marks string IDs.
```

## How to read it

Each table has one tab-separated header and one row per record. An empty cell means absent. A bare `id` header means plain text ids. A quoted `"id"` header means typed cells. Text that looks like a number, boolean or null is JSON-quoted. Nested values are JSON cells.

```terset
team: core
users:
id	name	role	tags
u1	Ada	null	
u2		ops	
u3	"42"		["new"]
```

The same data as JSON:

```json
{"team":"core","users":[{"id":"u1","name":"Ada","role":null},{"id":"u2","role":"ops"},{"id":"u3","name":"42","tags":["new"]}]}
```

## Answers

Ask the model to answer in JSON, not Terset.

## Short handles

When ids are long, your code can swap them for 1, 2, 3 before the prompt and map them back after. Flag any handle the input never had. This is a technique, not a package feature. It helped JSON as much as Terset in one small measured task.

## Limits

- The root must be an object or an array.
- A numeric `-0` and nesting deeper than 500 levels are explicit errors.
- Lists nested inside a record stay JSON inside their cell.
- Compact JSON can be smaller for config with no lists and for tiny data.

Full guide: https://terset.dev/agents.md
