turbo-editors/turbo-jspublic Fork 0
v1.0.0
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-js.git
git clone ssh://git@rickub.com/turbo-editors/turbo-js.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

📦 Turbo JS 91999d1 · on v1.0.0 · k33g · 11h ago
getting-started.md · 225 lines · 8.6 KBmarkdown
Blame HistoryOpen raw

Tutorial: your first Node program in Turbo JS

By the end of this tutorial you will have written, run and broken a small Node program without leaving the editor — and seen the editor tell you where the mistake was.

No prior knowledge of Turbo JS is needed. You need Go 1.26 or later to build the editor, and Node to run the program.

Prerequisites

Check Go:

go version

You should see something like:

go version go1.26.5 linux/arm64

Check Node and npm:

node --version && npm --version
v24.19.0
11.17.0

If node is not found, install it first — a version manager or one installer does it.

Step 1 — Install the editor and the language server

git clone https://rickub.com/turbo-editors/turbo-js.git
cd turbo-js
make install
npm install -g typescript-language-server typescript@6

The installer builds, installs, and then checks what it installed. After the npm install, the last lines of a second make install read:

==> Checking the language server
  ✓ typescript-language-server at /usr/local/bin/typescript-language-server

==> Ready

We now have a turbo-js command. The @6 on the last line matters: TypeScript 7 ships no tsserver.js, and the server refuses to start beside it.

Step 2 — Make a project

mkdir /tmp/greeter
cd /tmp/greeter
npm init -y

You should see the package.json npm wrote, ending in:

  "type": "commonjs"
}

That file is what makes this directory a Node project. The directory you start the editor in is where the JavaScript menu's commands will run, and the nearest package.json above the file you open is where the language server is started — so start it here.

Step 3 — Open a file that does not exist yet

turbo-js main.js

The screen fills. Along the top:

 File  Edit  Search  Run  Code  Options  Window  Snippets  Agent  JavaScript  Help

Eleven menus, and the tenth is named after the language. In the middle, an empty window titled main.js. Along the bottom, at the right-hand end, you should see:

1:1  LSP: ready

LSP: ready means typescript-language-server started in this directory. We will use it in Step 8.

Step 4 — Write the program

Type this in. Type it exactly; we will look at the colours next.

// A greeting, several times over.
const { argv } = require("node:process");

/** Greets one person. */
class Greeter {
  #name;

  constructor(name) {
    this.#name = name;
  }

  greet(times = 1) {
    const pattern = /^[A-Z]/;
    for (let i = 1; i <= times; i++) {
      console.log(`Hello, ${this.#name}! (${i})`);
    }
    return pattern.test(this.#name);
  }
}

const who = argv[2] ?? "JavaScript";
new Greeter(who).greet(3);

Two things about typing it. The editor repeats the previous line's indentation when you press Enter, so type only the change: two more spaces after a line that ends in {, and Backspace twice before a closing }. And if a completion list drops down while you type — a . asks for one by itself, and this. is one — keep typing or press Escape; Enter would accept the first entry.

Press F2 to save. The status bar says Saved main.js.

Step 5 — Read the colours

Look at what you have typed. In the default turbo-classic theme:

What Colour
const, class, for, let, return, new bright white, bold — keywords
Greeter, where it is declared and where it is called bright cyan — a class
constructor, greet, log, test bright yellow, bold — functions and methods
console, require bright cyan, bold — the globals Node provides
argv, name, times, who, #name bright yellow — ordinary names
"node:process", `Hello, ${this.#name}! (${i})` green — strings
/^[A-Z]/ green — a regular expression, drawn with the string colour in this theme
1, 3, this magenta — numbers and constants
// A greeting…, /** Greets one person. */ grey — comments
=, <=, ++, ??, {, }, . white — operators and punctuation

Three of those rows are worth a second look.

Greeter is cyan and greet is yellow, and nothing in the editor was told which of them is a class. JavaScript's convention decides it: classes are the names people capitalise, so a capital letter is coloured as a class — even in new Greeter(who), where a parenthesis follows.

/^[A-Z]/ is a regular expression, not two divisions. The scanner reads the = before it and knows a slash there opens a literal. Change the line to const half = times / 2; and the slash goes white again.

#name is one name, the # included, and it is yellow where a comment would be grey — a deliberate rule, because # opens a comment in half the other languages this editor colours.

Step 6 — Give the project its tools

Press F10 to open the menu bar, then nine times to reach JavaScript — past Edit, Search, Run, Code, Options, Window, Snippets and Agent. Faster: press Alt-J.

The menu holds two items, and only one of them is available:

┌───────────────────┐
│ Create tools file │
│ Open tools file   │   ← greyed out; there is no file to open yet
└───────────────────┘

Choose Create tools file.

A second window opens on the file that was just written, .turbo-js/tools.toml. Read it if you like — it explains every key it uses — then press Ctrl-W to close it.

Look at the menu bar: a Tools menu has appeared between JavaScript and Help. The starter file's last entry names a menu of its own, and that one line is the whole mechanism.

Open the JavaScript menu again. It now holds six commands, and the two items have swapped: Create tools file is greyed out, and Open tools file is the one you can choose.

Step 7 — Run it

Press Alt-J and choose Run. A box asks for a value before the command runs, because a Node project has no single entry point the editor could know:

┌──────────────── Run ────────────────┐
│  script, e.g. main.js               │
│  [                               ]  │
└─────────────────────────────────────┘

Type main.js and press Enter. A terminal window opens and the program runs in it:

Hello, JavaScript! (1)
Hello, JavaScript! (2)
Hello, JavaScript! (3)

A terminal rather than a dialog, because a program that reads the keyboard has to be answerable. The program has finished, so the window has stopped behaving like a terminal and every key reaches the editor again: press Ctrl-W to close it.

Step 8 — Break it, and see where

Go to the last line, new Greeter(who).greet(3);, and delete its closing parenthesis, so it reads:

new Greeter(who).greet(3;

Press F2 to save.

Within a second, two things happen. A × appears in the gutter, just left of that line's number. And the status bar reads:

⚠ ')' expected.

Nothing asked for that. typescript-language-server publishes it by itself whenever the file changes — this is what the server does for a plain .js file: it finds the syntax errors. Put the parenthesis back and save again; both the mark and the message go away.

Now put the cursor on greet in that last line and press F1. A box titled Symbol opens with the method's signature, beginning (method) Greeter.greet(times?: number) — the server worked out the parameter's type from its default value and the return type from the return pattern.test(…) line, in a language that never declared either. Press Escape to close it, then F12 on the same word: the cursor jumps to the line where greet is declared.

Step 9 — Change the theme

F10, then five times to reach Options — past Edit, Search, Run and Code. Choose Theme….

A list opens on the theme you are in, turbo-classic. Press until cobalt is selected — five times — and Enter. The whole screen changes, keeping the same shape.

Press Alt-X to leave. The editor asks about unsaved files first, if there are any.

What now?

You have written a Node program in the editor, run it, broken it, and seen the editor say where. To go further:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# Tutorial: your first Node program in Turbo JS

By the end of this tutorial you will have written, run and broken a small Node program without leaving the editor — and seen the editor tell you where the mistake was.

No prior knowledge of Turbo JS is needed. You need Go 1.26 or later to build the editor, and Node to run the program.

## Prerequisites

Check Go:

```bash
go version
```

You should see something like:

```
go version go1.26.5 linux/arm64
```

Check Node and npm:

```bash
node --version && npm --version
```

```
v24.19.0
11.17.0
```

If `node` is not found, install it first — [a version manager or one installer does it](../how-to/install-node.md).

## Step 1 — Install the editor and the language server

```bash
git clone https://rickub.com/turbo-editors/turbo-js.git
cd turbo-js
make install
npm install -g typescript-language-server typescript@6
```

The installer builds, installs, and then checks what it installed. After the `npm install`, the last lines of a second `make install` read:

```
==> Checking the language server
  ✓ typescript-language-server at /usr/local/bin/typescript-language-server

==> Ready
```

We now have a `turbo-js` command. The `@6` on the last line matters: TypeScript 7 ships no `tsserver.js`, and the server refuses to start beside it.

## Step 2 — Make a project

```bash
mkdir /tmp/greeter
cd /tmp/greeter
npm init -y
```

You should see the `package.json` npm wrote, ending in:

```
  "type": "commonjs"
}
```

That file is what makes this directory a Node project. **The directory you start the editor in** is where the JavaScript menu's commands will run, and the nearest `package.json` above the file you open is where the language server is started — so start it here.

## Step 3 — Open a file that does not exist yet

```bash
turbo-js main.js
```

The screen fills. Along the top:

```
 File  Edit  Search  Run  Code  Options  Window  Snippets  Agent  JavaScript  Help
```

Eleven menus, and the tenth is named after the language. In the middle, an empty window titled `main.js`. Along the bottom, at the right-hand end, you should see:

```
1:1  LSP: ready
```

`LSP: ready` means `typescript-language-server` started in this directory. We will use it in Step 8.

## Step 4 — Write the program

Type this in. Type it exactly; we will look at the colours next.

```javascript
// A greeting, several times over.
const { argv } = require("node:process");

/** Greets one person. */
class Greeter {
  #name;

  constructor(name) {
    this.#name = name;
  }

  greet(times = 1) {
    const pattern = /^[A-Z]/;
    for (let i = 1; i <= times; i++) {
      console.log(`Hello, ${this.#name}! (${i})`);
    }
    return pattern.test(this.#name);
  }
}

const who = argv[2] ?? "JavaScript";
new Greeter(who).greet(3);
```

Two things about typing it. **The editor repeats the previous line's indentation when you press `Enter`**, so type only the change: two more spaces after a line that ends in `{`, and `Backspace` twice before a closing `}`. And if a completion list drops down while you type — a `.` asks for one by itself, and `this.` is one — keep typing or press `Escape`; `Enter` would accept the first entry.

Press `F2` to save. The status bar says `Saved main.js`.

## Step 5 — Read the colours

Look at what you have typed. In the default `turbo-classic` theme:

| What | Colour |
| --- | --- |
| `const`, `class`, `for`, `let`, `return`, `new` | bright white, bold — keywords |
| `Greeter`, where it is declared and where it is called | bright cyan — a class |
| `constructor`, `greet`, `log`, `test` | bright yellow, bold — functions and methods |
| `console`, `require` | bright cyan, bold — the globals Node provides |
| `argv`, `name`, `times`, `who`, `#name` | bright yellow — ordinary names |
| `"node:process"`, `` `Hello, ${this.#name}! (${i})` `` | green — strings |
| `/^[A-Z]/` | green — a regular expression, drawn with the string colour in this theme |
| `1`, `3`, `this` | magenta — numbers and constants |
| `// A greeting…`, `/** Greets one person. */` | grey — comments |
| `=`, `<=`, `++`, `??`, `{`, `}`, `.` | white — operators and punctuation |

Three of those rows are worth a second look.

**`Greeter` is cyan and `greet` is yellow**, and nothing in the editor was told which of them is a class. JavaScript's convention decides it: classes are the names people capitalise, so a capital letter is coloured as a class — even in `new Greeter(who)`, where a parenthesis follows.

**`/^[A-Z]/` is a regular expression, not two divisions.** The scanner reads the `=` before it and knows a slash there opens a literal. Change the line to `const half = times / 2;` and the slash goes white again.

**`#name` is one name**, the `#` included, and it is yellow where a comment would be grey — [a deliberate rule](../explanation/colouring-and-completion.md), because `#` opens a comment in half the other languages this editor colours.

## Step 6 — Give the project its tools

Press `F10` to open the menu bar, then `` **nine times** to reach **JavaScript** — past Edit, Search, Run, Code, Options, Window, Snippets and Agent. Faster: press `Alt-J`.

The menu holds two items, and only one of them is available:

```
┌───────────────────┐
│ Create tools file │
│ Open tools file   │   ← greyed out; there is no file to open yet
└───────────────────┘
```

Choose **Create tools file**.

A second window opens on the file that was just written, `.turbo-js/tools.toml`. Read it if you like — it explains every key it uses — then press `Ctrl-W` to close it.

Look at the menu bar: a **Tools** menu has appeared between JavaScript and Help. The starter file's last entry names a menu of its own, and that one line is the whole mechanism.

Open the JavaScript menu again. It now holds six commands, and the two items have swapped: `Create tools file` is greyed out, and `Open tools file` is the one you can choose.

## Step 7 — Run it

Press `Alt-J` and choose **Run**. A box asks for a value before the command runs, because a Node project has no single entry point the editor could know:

```
┌──────────────── Run ────────────────┐
│  script, e.g. main.js               │
│  [                               ]  │
└─────────────────────────────────────┘
```

Type `main.js` and press `Enter`. A terminal window opens and the program runs in it:

```
Hello, JavaScript! (1)
Hello, JavaScript! (2)
Hello, JavaScript! (3)
```

A terminal rather than a dialog, because a program that reads the keyboard has to be answerable. The program has finished, so the window has stopped behaving like a terminal and every key reaches the editor again: press `Ctrl-W` to close it.

## Step 8 — Break it, and see where

Go to the last line, `new Greeter(who).greet(3);`, and delete its closing parenthesis, so it reads:

```javascript
new Greeter(who).greet(3;
```

Press `F2` to save.

Within a second, two things happen. A `×` appears in the gutter, just left of that line's number. And the status bar reads:

```
⚠ ')' expected.
```

Nothing asked for that. `typescript-language-server` publishes it by itself whenever the file changes — this is what the server does for a plain `.js` file: it finds the syntax errors. Put the parenthesis back and save again; both the mark and the message go away.

Now put the cursor on `greet` in that last line and press `F1`. A box titled **Symbol** opens with the method's signature, beginning `(method) Greeter.greet(times?: number)` — the server worked out the parameter's type from its default value and the return type from the `return pattern.test(…)` line, in a language that never declared either. Press `Escape` to close it, then `F12` on the same word: the cursor jumps to the line where `greet` is declared.

## Step 9 — Change the theme

`F10`, then `` **five times** to reach **Options** — past Edit, Search, Run and Code. Choose **Theme…**.

A list opens on the theme you are in, `turbo-classic`. Press `` until `cobalt` is selected — five times — and `Enter`. The whole screen changes, keeping the same shape.

Press `Alt-X` to leave. The editor asks about unsaved files first, if there are any.

## What now?

You have written a Node program in the editor, run it, broken it, and seen the editor say where. To go further:

- To do specific things → the [how-to guides](../how-to/)
- To see exactly what is coloured and how → [languages coloured](../reference/languages.md)
- To understand why the editor is built this way → the [explanation](../explanation/)