Saving & sharing programs

kitengi programs are stored as plain text .kti files. The editor lets you copy, paste, and load them at any time.

Auto-save

The editor automatically saves your programs in your browser's local storage as you work. Your programs are available the next time you open the app in the same browser.

Browser storage. Programs are stored locally in your browser. Clearing browser data or using a different browser or device will not show your programs — always export important programs to a file or clipboard.

Copy source to clipboard

Click Copy source in the toolbar to copy the current program's .kti text to the clipboard. You can then paste it into any text editor, a GitHub Gist, a Slack message, or anywhere else.

Load from text

Click Load from text in the toolbar. Paste a .kti program into the text area and click Load. The program is parsed and displayed on the canvas. If there are any syntax errors they are shown inline.

Load from file

You can also drag a .kti file directly onto the canvas or use the Load from file option to open a file picker.

Program types

A program's type determines which node kinds are available. The type is shown in the right panel when nothing is selected and can be changed there for General programs.

TypeAvailable nodes
GeneralAll core nodes. No environment-specific nodes.
ServerCore nodes plus tcp-listen, tcp-write, tcp-close, stream-split. Requires kitengi-bridge.
BrowserReserved — no additional nodes yet.
DesktopReserved — no additional nodes yet.
MobileReserved — no additional nodes yet.

Sharing a program

To share a program with someone else:

  1. Click Copy source to copy the .kti text.
  2. Send the text to the other person (message, email, Gist, etc.).
  3. They open app.kitengi.dev, click Load from text, paste the text, and click Load.

The .kti format

The .kti format is plain text and human-readable. Here is a minimal example:

program:Counter
| Counts from 1 to 5

-> start -> loop:initial

value:one = 1
<- trigger[null]
-> value[number] -> loop:initial

loop:loop
<- initial[number]
<- next[number]
-> step[number] -> print:value
                -> compare:a

value:limit = 5
<- trigger[null]
-> value[number] -> compare:b

compare:compare
<- a[number]
<- b[number]
-> result[boolean] -> branch:condition

branch:branch
<- condition[boolean]
<- value[any]
-> false[any] -> loop:next

print:print
<- value[any]

See the FAQ for a complete reference of keywords, node types, and port syntax.