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.

10 minutesno tooling requiredno API keys

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.vos for anything the operating system owns.

Build it

1

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.

2

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.

html
<!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>
3

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.

json
{
  "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

4

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:

javascript
// 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 type
5

Check the things reviewers check

CheckWhy
Reload the preview — does your text come back?Persistence is the first thing tested.
Resize the window narrow and wideManifest 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

6

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