Getting started
Quickstart
Build a real, submittable VibeOS app in about ten minutes. It stores data with the SDK, asks for the minimum permissions, and follows every convention reviewers look for.
Before you start
- You need nothing installed — no Node, no bundler, no framework. A VibeOS app is one HTML document inside one JSON file.
- You will write and run it in the VibeOS IDE, which gives you a live preview, a JavaScript console and a file explorer.
- What you build here is the shape of every VibeOS app: an inline document plus
window.vosfor anything the operating system owns.
Build it
Open the IDE
Go to the IDE and start from a blank app or a template. The left pane is your code, the right pane runs it live with the real SDK attached.
Write the document
This is a complete app: a text area that loads and saves itself to the app's private folder. Four things are worth noticing — the boot guard at the bottom, the getInfo() call that finds the private folder, the debounced save, and the fact that every style and script is inline.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
/* Everything is inline — no external CSS or fonts. */
body { margin:0; padding:20px; font-family:system-ui,sans-serif;
background:#0f172a; color:#e2e8f0 }
h1 { font-size:18px; font-weight:500; margin:0 0 12px }
textarea { width:100%; height:calc(100vh - 110px); resize:none;
background:#111c33; color:inherit; border:1px solid #22304d;
border-radius:12px; padding:12px; font:14px/1.6 inherit }
#status { margin-top:8px; font-size:12px; color:#7e8ba3 }
</style>
</head>
<body>
<h1>Scratchpad</h1>
<textarea id="pad" placeholder="Start typing — saves automatically"></textarea>
<div id="status">Starting…</div>
<script>
var FILE = "scratchpad.txt";
var dir = null, timer = null;
var pad = document.getElementById("pad");
var status = document.getElementById("status");
function setStatus(t) { status.textContent = t; }
function start() {
// 1. Ask the host who we are and where our private folder is.
window.vos.app.getInfo().then(function (info) {
dir = info.sandboxPath;
// 2. Load anything saved earlier. null means first run.
return window.vos.fs.readFile(dir, FILE);
}).then(function (text) {
if (text) pad.value = text;
setStatus("Ready");
}).catch(function (err) {
setStatus("Could not open storage: " + err.message);
});
}
// 3. Save on a debounce so we never write on every keystroke.
pad.addEventListener("input", function () {
setStatus("Saving…");
clearTimeout(timer);
timer = setTimeout(function () {
window.vos.fs.writeFile(dir, FILE, pad.value)
.then(function () { setStatus("Saved"); })
.catch(function (err) { setStatus("Save failed: " + err.message); });
}, 400);
});
// 4. Boot correctly whether or not the SDK is ready yet.
if (window.vos) start();
else window.addEventListener("vos-ready", start, { once: true });
</script>
</body>
</html>Wrap it in a manifest
The manifest is the app: metadata for the listing, the permissions you need, and the document itself as the html field. The IDE produces this for you — you rarely escape it by hand.
{
"vibe": 1,
"name": "Scratchpad",
"iconEmoji": "📝",
"iconBg": "linear-gradient(135deg,#10b981,#0ea5e9)",
"description": "An instantly-saving scratchpad for quick notes and snippets, stored privately inside VibeOS.",
"version": "1.0.0",
"author": "Your Name",
"genre": "productivity",
"width": 520,
"height": 560,
"closeBehavior": "close",
"permissions": { "read": [], "write": [] },
"html": "<!doctype html>…your document as one escaped JSON string…"
}"read": [] and "write": [] are the important lines: they declare filesystem access scoped to only this app's private folder, so it installs with no permission prompt. See permissions for the full model.
Test it
Run it and watch the filesystem
Type in the preview, then open the Files tab — you will see scratchpad.txt appear inside your app's folder. The Console tab lets you call the SDK by hand:
// In the IDE's Console tab:
const info = await window.vos.app.getInfo();
info.sandboxPath // "home/.apps/scratchpad"
await window.vos.fs.readDir(info.sandboxPath) // ["scratchpad.txt"] after you typeCheck the things reviewers check
| Check | Why |
|---|---|
| Reload the preview — does your text come back? | Persistence is the first thing tested. |
| Resize the window narrow and wide | Manifest width/height is only the opening size; layouts must flex. |
| Console clean of errors? | A red console is the most common cause of requested changes. |
| Does it work before you type anything? | First run has no saved file — readFile resolves null, not an error. |
| Are you requesting only what you use? | Unused permissions get flagged in review. |
Two mistakes that break most first apps
1. A bare vos-ready listener. The event fires once and does not replay, so a listener attached too late never runs. Always check window.vos first.
2. External scripts, styles or images. The sandbox blocks them. Inline everything, and fetch remote data through vos.net.
Ship it
Submit for review
Save the app from the IDE, or paste your manifest into the submit form as a draft. Give it a clear description and an icon, then submit. Reviewers install it, use it, and either publish it or send you notes by email.
Full details, including what gets an app rejected, are in submission & review.
Where to go next
- SDK reference — the whole
window.vossurface: files, AI, network, app info. - Runtime architecture — why the rules above exist, and how to design around them.
- To-Do example — a bigger app with a downloadable template.
- AI chatbot example — add hosted AI with no keys.