jstash Apps · Demo

Cloud Notes
Sign in anywhere. Your note is there.

A tiny notes app with no server and no database of its own. Google signs you in. jstash keeps your note. Saving and loading it takes about 20 lines of plain fetch, shown below.

  1. 1

    Sign in with Google

    Any Google account.

  2. 2

    Write a note and press Save

  3. 3

    Sign out, or switch device

    Another browser, a private window or your phone.

  4. 4

    Sign in again

    Same Google account. Your note comes back.

Your note is real data, saved in jstash. Don’t write anything sensitive.

The code

That’s the backend.

Google signs people in and gives the page an ID token. The page sends that token with each save and load, and jstash keeps one document, note, for each person. This is the jstash part: the starter code the dashboard gives you for a Google login. The rest of demo.js is buttons and messages.

jstash.js
const JSTASH = 'https://api.jstash.app/v1/apps/app_…/me';

let idToken; // set it in your Sign In With Google callback: idToken = response.credential

function token() {
  return idToken; // valid for one hour; sign in again after that
}

async function save(name, value) {
  const res = await fetch(`${JSTASH}/${name}`, {
    method: 'PUT',
    headers: { Authorization: `Bearer ${await token()}` },
    body: JSON.stringify(value),
  });
  if (!res.ok) throw await failure(res);
}

async function load(name) {
  const res = await fetch(`${JSTASH}/${name}`, {
    headers: { Authorization: `Bearer ${await token()}` },
  });
  if (res.ok) return res.json();
  const err = await failure(res);
  if (err.code === 'DOC_NOT_FOUND') return null; // nothing saved yet
  throw err;
}

// failure(res) turns jstash’s JSON error into an Error: 5 more lines
notes.js
// Google signs the person in and hands the page an ID token
google.accounts.id.initialize({
  client_id: GOOGLE_CLIENT_ID,
  callback: (response) => { idToken = response.credential; },
});

// Save
await save('note', { text: textarea.value });

// Load, after signing in on any device
const note = await load('note');

What isn’t here

  • No server. Cloud Notes is a static page, a script and a stylesheet.
  • No database or security rules. jstash files each note under this app and the person’s Google user ID. A token only ever reaches its own person’s note. That rule is built in.
  • No secret in the page. The Google client ID and the jstash app ID are meant to be public. The only credential is the person’s own Google token, which jstash checks against Google’s published keys.

One catch: an hour

Google’s ID tokens last an hour and the page can’t refresh them, so after that Cloud Notes asks you to sign in again. For apps people keep open, use Clerk, Supabase or Firebase, which refresh tokens for you. Only token() changes (guide).

Your note

Your note is real data

Cloud Notes is an ordinary jstash app, run by jstash. It works the way your app would.

  • What’s kept: your note, as one document filed under a one-way hash of your Google user ID. jstash doesn’t keep your email address or your Google token. This page shows your email from the token, in your browser only.
  • Don’t write anything sensitive: no passwords, health details or other private information. jstash isn’t for sensitive data (Terms).
  • No live sync: another device gets your latest note when you sign in there. Changes aren’t pushed to devices that are already open.
  • Google runs the sign-in: you sign in with Google, under Google’s privacy policy. This page loads Google’s sign-in script, which sets one cookie here, g_state, for its own use.
  • It counts like any app: each person who saves a note counts toward the users of the jstash account that runs Cloud Notes. If that account is full, saving shows the jstash error that says so.
  • Questions, or want your note removed and can’t sign in? Email support@jstash.app. See also our Privacy Policy.
No backups. “Delete my note” removes it from jstash for good, and so does saving over it. Keep your own copy of anything that matters.

Give each signed-in user their own JSON.

PUT https://api.jstash.app/v1/apps/app_…/me/note