A JavaScript playground that lives on your desktop. Write code, press Play, and watch the output appear in the built-in console. No terminal, no installation, no configuration.
Important
Pattojs is currently in Beta. This means it's still being actively tested and refined. You can use it normally, but you might occasionally run into bugs or performance changes.
-
Open Pattojs and select New File...
-
Type some code:
console.log("Hello, world!"); console.log(2 + 2);
-
Press Play. Output appears in the console below.
Follow these step by step to learn the basics.
-
Open Pattojs and select New File...
-
Type the following:
console.log("Hello, world!"); console.log(2 + 2); console.log("Apples:", 3, "Bananas:", 7);
-
Press Play. Three lines appear in the console.
-
Change something and press Play again. Each run starts clean.
-
Try variables and template literals:
const fruit = "mango"; const count = 12; console.log(`I bought ${count} ${fruit}s today.`);
const inventory = [
{ item: "apple", qty: 12, price: 0.4 },
{ item: "banana", qty: 0, price: 0.25 },
{ item: "cherry", qty: 300, price: 3.1 },
];
console.log(inventory); // Expandable tree
console.table(inventory); // Table view
console.table(inventory, ["item", "qty"]); // Specific columnsconst res = await fetch("https://jsonplaceholder.typicode.com/todos");
const todos = await res.json();
console.log("Received", todos.length, "todos");
const unfinished = todos.filter((t) => !t.completed && t.userId === 1);
console.table(unfinished.slice(0, 10), ["id", "title"]);-
Open Settings > Properties
-
Add key
USERNAMEwith your name -
Run:
const user = Props.get("USERNAME"); if (user === null) { console.error("USERNAME not set. Add it in Settings > Properties."); } else { console.log(`Welcome back, ${user}!`); }
-
Add
BASE_CURRENCY=USDin Properties -
Run:
const base = Props.get("BASE_CURRENCY") ?? "EUR"; async function getRate(from, to) { const url = `https://api.frankfurter.app/latest?from=${from}&to=${to}`; const res = await fetch(url); if (!res.ok) throw new Error(`API error ${res.status}`); const data = await res.json(); return data.rates[to]; } const rate = await getRate(base, "JPY"); console.info(`1 ${base} = ${rate} JPY`); console.table( [10, 50, 100, 500].map((amount) => ({ amount, converted: Number((amount * rate).toFixed(2)), })), );
ReferenceError: X is not defined— typo in a variable nameTypeError: Cannot read properties of null— use optional chaining:user?.nameRangeError: Infinite loop prevented— loops are capped at 2000 iterations
- Save:
Ctrl+S - Open:
Ctrl+O - Save As:
Ctrl+Shift+S
- Select Manage (gear icon)
- Under Common, switch Color scheme between Light and Dark
You can import from URLs or npm packages directly:
import { z } from "https://esm.sh/zod";Or using the npm prefix:
import { z } from "npm:zod";Example usage:
const User = z.object({
name: z.string(),
age: z.number().int().positive(),
});
console.log(User.safeParse({ name: "Ada", age: 36 }).success);- Press Stop — the runtime is killed immediately
- Clear console if needed
- Fix code and press Play again
| Shortcut | Action |
|---|---|
Ctrl+O |
Open file |
Ctrl+S |
Save |
Ctrl+Shift+S |
Save as |
Ctrl+Q |
Quit |
Ctrl+Z |
Undo |
Ctrl+Y |
Redo |
Ctrl+X / C / V |
Cut, copy, paste |
Open with the Manage button (gear icon).
| Setting | Values | Default |
|---|---|---|
| Color scheme | Light, Dark | Dark |
| Font size (editor) | 10–24 px | 14 |
| Font size (console) | 9–20 px | 13 |
| Tab size | 1–8 spaces | 2 |
| Line wrapping | on, off | on |
Store tokens in Settings > Properties. Access them in code:
const token = Props.get("MY_TOKEN");- Values are always strings
- Missing keys return
null - Keys are case-sensitive
- Work through the tutorials in order
- Move tokens into Props before saving scripts
- Check the how-to guides when you need help with a task
Want to understand how Pattojs works under the hood? Read the architecture notes.