SHLS Editor online

Code

Export

My documents

Click a document to open it. They are stored only in this browser - nothing is uploaded. Clearing the browser's site data removes them, so download the ones you want to keep.

AI Assistant

Any AI can work with you - ChatGPT, Claude, Gemini, Copilot. The prompt explains SHLS, so the AI writes valid SHLS.

  1. Click Copy prompt.
  2. Paste it into your AI and say what it should change.
The AI should

The document travels in the link after the “#”, which no server sees. What you paste into your AI is handled by its provider.

Save to your server

The editor can send each saved version to your own server (a webhook), so your work is kept where you want it. Nothing is sent until you enter an address here.

What your server receives

A POST request with JSON (your server must allow CORS from https://shls.giit.ch); content is the document as a string:

{ "editor": "shls", "event": "save", "id": "…", "name": "Products",
  "content": "Product\n Name\n Price\n\n Lamp\n 19.90\n",
  "updated": "2026-01-15T09:30:00.000Z" }
Embed the editor in your website
<iframe src="https://shls.giit.ch/?embed=1" style="width:100%;height:80vh;border:0"></iframe>
<script>
const frame = document.querySelector('iframe');
addEventListener('message', e => {
  if (e.origin !== 'https://shls.giit.ch' || e.source !== frame.contentWindow) return;
  if (e.data.type === 'shlseditor:ready')
    frame.contentWindow.postMessage({ type: 'shlseditor:load', name: 'Products',
      content: shlsText }, 'https://shls.giit.ch');
  if (e.data.type === 'shlseditor:save') saveOnYourServer(e.data.content);
});
</script>

Also possible: ?src=<URL of a .shls file> opens a file, &webhook=<URL> saves this document there. The editor can also open in a window of its own (?embed=window), and your page can hand it its own AI prompt and a session key so the AI sends its result to your server (shlseditor:ai, shlseditor:key-request) - see "Use the editor on your own website" below the editor. Details are in llms.txt.

Help

How it works

  1. Write SHLS on the left - or start with New and one of the templates. A section is its name, then its keys (indented by one space, the keys of a nested list one level deeper), exactly one blank line, then the records: one value per line in the order of the keys.
  2. The middle shows each section with its key block and its records, the keys as labels; nested lists fold. It reads the code exactly as the reference SHLSDecoder does.
  3. Click a value, a key or a section name to change it right there. Enter or a click elsewhere writes the change into the code (one step for Undo), Escape cancels. The buttons above add, duplicate, move and remove records and keys - a key added or removed is added to or removed from every record.
  4. A click in the middle puts the code's cursor on that line; the cursor in the code marks its record, key or value. Problems (a record with a value too few, indentation that is not a whole level, a missing blank line) are listed above the code with their line - click one to go there.
  5. Record on the right shows the selected record as a form; Insert adds records, keys and sections; Convert counts the tokens against JSON and converts to JSON, YAML, CSV and JSON Lines; Outline lists the sections.
  6. My documents (the folder button at the top left) lists every document kept in this browser. Export saves it as SHLS, JSON, YAML, CSV or text.

Keyboard shortcuts

↑ ↓ ← →
In the records: go up and down, fold and unfold
Enter
In the records: change the value, key or section name
Delete
In the records: remove the record or key
Alt + ↑ / ↓
In the records: move the record or key up / down
Ctrl + F
Search keys and values
Tab / Shift + Tab
Indent / outdent in the code by one level
Ctrl + Z / Y
Undo / redo
Ctrl + S / E
Save (download, or to your server) / export
Ctrl + O
My documents

Enter keeps the indentation of the line; after a section name it starts the key block.

Edit SHLS online - the data format that saves tokens

SHLS (Sebis Hierarchical List Structure) writes structured data without quotes, brackets, colons or repeated keys: each section names its keys once, and the records below list only the values. The SHLS Editor shows the code and, next to it, each section's key block and records. Change values, keys and records right there, see problems by line, convert to and from JSON, YAML and CSV, and see how many tokens SHLS saves against JSON.

Everything runs in your browser. Documents are not uploaded, there is no sign-up and no advertising.

SHLS in one minute

A section starts with its name. Its key block lists the keys, indented by one space; the keys of a nested list one level deeper. After exactly one blank line follow the records: one value per line, in the order of the keys. A nested list has a line of its own (its key, or PH as a placeholder) with its records one level deeper. All values are text - converting them to numbers or dates is up to the program that reads them.

Product
 Name
 Price

 Smartphone A1
 599.99

 Laptop B2
 1299.99

Company
 Name
 Location
  Country
  City

 TechCorp
 PH
  USA
  San Francisco

The same data as JSON repeats every key in every record and needs quotes, brackets and colons. SHLS was made for local and cloud AI models, where every token counts. SHLS by Sebastian Grünwald - the format, its rules and the reference SHLSDecoder and SHLSEncoder (Python) are in the SHLS repository on GitHub.

What the editor can do

Code and records

Highlighted SHLS on the left - sections, keys, values, nesting levels and PH placeholders. In the middle each section's key block and its records, the keys as labels. A click jumps to the code, the code cursor marks its record.

Edit in place

Change values, keys and section names; add, duplicate, move and remove records and keys. Records follow their key block: a new key gets "-" in every record. One step for Undo each.

Read like the reference

The editor reads SHLS exactly as SHLSDecoder does and lists what it would read differently than it looks: a record with a value too few or too many, indentation, blank lines after the key block, a key twice.

Tokens

The Convert tab counts the approximate tokens of your SHLS and of the same data as JSON, so you see the saving at a glance.

Convert

To and from JSON exactly as SHLSDecoder and SHLSEncoder, YAML, CSV (one section as a table) and JSON Lines. JSON, YAML, CSV and JSON Lines files open as SHLS.

Many documents

Keep any number of documents in your browser, with their own undo history, and download them all as a ZIP.

How it works

  1. Start - choose a template under "New", open a .shls file, or open a JSON, YAML or CSV file to get it as SHLS.
  2. Edit - in the code or in the records; both always show the same data.
  3. Check and convert - fix the listed problems, compare the tokens, and download SHLS, JSON, YAML, CSV or text.

Use the editor on your own website

Any https page (and localhost) can embed the editor with an <iframe> and ?embed=1 - no sign-up, no key. Embedded, the editor hides this text and shows a Save button. There are two ways to get the document in and out.

1. Open a file from a link, save to your server

src= opens a file (your server must allow CORS), webhook= makes "Save" (Ctrl+S) send the document to that address. Add &token=… for an Authorization: Bearer … header and &auto to save after every change.

<iframe src="https://shls.giit.ch/?embed=1&src=https://your-site.com/data/products.shls&webhook=https://your-site.com/save.php"
        allow="clipboard-write" style="width:100%;height:800px;border:0"></iframe>

The webhook gets a POST with JSON { editor: "shls", event: "save", id, name, content, updated }; content is the document as a string. A small PHP script that stores it:

<?php
header('Access-Control-Allow-Origin: https://shls.giit.ch');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
header('Access-Control-Allow-Methods: POST, OPTIONS');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') exit;
if (($_SERVER['HTTP_AUTHORIZATION'] ?? '') !== 'Bearer SECRET') { http_response_code(403); exit; }
$d = json_decode(file_get_contents('php://input'), true);
$name = preg_replace('/[^\w\- ]/u', '_', $d['name']);
file_put_contents(__DIR__ . "/data/$name.shls", $d['content']);
echo '{"ok":true}';

2. Your page holds the document (postMessage)

The editor says shlseditor:ready, your page answers with shlseditor:load, the editor reports shlseditor:loaded, shlseditor:change on real edits and shlseditor:save when the user saves. Your page may send shlseditor:get (the current state) or shlseditor:save (press Save). Saving then goes through your own login and session.

<iframe id="ed" src="https://shls.giit.ch/?embed=1" allow="clipboard-write" style="width:100%;height:800px;border:0"></iframe>
<script>
const ed = document.getElementById('ed');
const ORIGIN = 'https://shls.giit.ch';

addEventListener('message', async e => {
  if (e.source !== ed.contentWindow || e.origin !== ORIGIN) return;
  const m = e.data;
  if (m.type === 'shlseditor:ready') {              // the editor is ready: hand it the document
    ed.contentWindow.postMessage({
      type: 'shlseditor:load',
      name: 'Products',
      content: await (await fetch('/data/products.shls')).text()
    }, ORIGIN);
  }
  if (m.type === 'shlseditor:change') document.title = '● not saved';   // a real edit
  if (m.type === 'shlseditor:save') {               // the user clicked "Save"
    await fetch('/api/save', { method: 'POST', headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ name: m.name, content: m.content }) });
    document.title = 'Saved';
  }
});

// A save button on your own page: the answer comes as shlseditor:save
function saveNow() { ed.contentWindow.postMessage({ type: 'shlseditor:get' }, ORIGIN); }
</script>

AI Assistant inside your page: it works in the frame too. With allow="clipboard-write" on the iframe, "Copy prompt" uses the clipboard directly (otherwise the editor falls back to the old copy command, or shows the prompt to copy by hand). A link the AI sends cannot reach an editor inside another website, so the editor tells the AI and the user to paste the AI's whole answer into the editor instead - or open the editor in a window of its own.

3. In a window of its own

window.open("https://shls.giit.ch/?embed=window", "shlseditor-17") opens the full editor in its own window and speaks the same messages with window.opener. Links from an AI reach it there. shlseditor:load may also carry context: { host, title, rules } - the AI prompt then says where the document belongs and follows your rules - and hook: { url, token }, a webhook for this document only that is never stored. Closing the window with unsaved changes sends shlseditor:closing.

4. AI through your own server

Hand the editor your own prompt, an address on your site and a key for this editor session. The AI dialog then shows "Connected to" your site, what you tell the AI, and the choice change the current document or make a new one; Copy prompt puts it all together. The AI posts its result with the key to your server, and your page opens it in the editor - a new document opens separately and stays in the user's browser. One key per editor session: it stays valid while the editor is open, and only while it has none the editor asks for it with shlseditor:key-request. The editor never sends the key itself and never stores it; the address must be https on your own host or a subdomain of it.

const key = async () => (await fetch('/api/ai-key.php?doc=17')).json();   // one key per editor session
const k = await key();
ed.contentWindow.postMessage({ type: 'shlseditor:load', name: 'Products', content, ai: {
  label: 'My Site', prompt: 'Keep every key. Only add records.',
  endpoint: 'https://your-site.com/api/ai-result.php', key: k.key } }, ORIGIN);
// remember the id from shlseditor:loaded and ignore change/save/closing with another id
// only while the editor has no key:
if (m.type === 'shlseditor:key-request') { const k = await key(); ed.contentWindow.postMessage({ type: 'shlseditor:ai', key: k.key }, ORIGIN); }
// while the editor is open, tell your server every minute; closing the editor or the page voids the key
setInterval(() => fetch('/api/ai-key.php?alive=' + k.key.slice(0, 8)), 60000);
// your server has a result (polling, SSE …): target is "current" or "new"
ed.contentWindow.postMessage({ type: 'shlseditor:load', name: 'Products', content: draft, from: 'ai', target }, ORIGIN);

Make keys with at least 128 random bits, store only their hash, bind each to the logged-in user, the document and this editor session, make one per session, keep it valid only while your page reports the session as open, and void it when the editor or the page closes.

The whole protocol is in llms.txt - give it to an AI and it builds the connection for your system. The JSON Editor works the same way with the prefix jsoneditor: - json.giit.ch.

Frequently asked questions

What is SHLS?

SHLS (Sebis Hierarchical List Structure) is a text format for structured data by Sebastian Grünwald. Each section names its keys once in a key block; the records below list only the values, one per line, and indentation shows the nesting. Without quotes, brackets, colons or repeated keys, the same data needs far fewer tokens than JSON - which makes it a good format for AI models.

Is my data uploaded?

No. The editor runs entirely in your browser. Your documents are never sent to a server, unless you set up a webhook to your own server yourself.

Does the editor read SHLS exactly like the reference code?

Yes. The editor reads and writes SHLS exactly as SHLSDecoder and SHLSEncoder of the SHLS repository do - the JSON in the Convert tab is the data the Python classes give. Where they read a document differently than it looks (a record with a value too few, a blank line with spaces), the editor lists it as a problem with its line.

Can I edit the records without touching the code?

Yes. Click a value, a key or a section name in the middle, type, and press Enter. The buttons above the records add, duplicate, move and remove records and keys; when you add or remove a key, every record of the section gets or loses its value. Each change is one step for Undo.

How many tokens does SHLS save?

The Convert tab counts the approximate tokens of your document as SHLS and of the same data as JSON. For tables of records SHLS often needs less than half of the tokens of indented JSON, because the keys are written only once.

Can it convert JSON, YAML or CSV to SHLS?

Yes. Open a .json, .yaml, .csv or .jsonl file and it becomes SHLS, written as SHLSEncoder writes it; the editor says what SHLS cannot keep (empty values, values with line breaks). The Convert tab and Export write JSON, YAML, CSV, JSON Lines and plain text.

Can an AI write in the SHLS Editor?

Yes, any AI - ChatGPT, Claude, Gemini, Copilot or the AI in your coding tool. Click "AI Assistant", then "Copy prompt": the prompt explains SHLS, so any AI writes valid SHLS. The AI answers with a link; click it and the document appears in your editor. "Undo" takes every change back.

Does the SHLS Editor cost anything?

No. The editor is free, without ads and without sign-up.