> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tinycloud.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Web SDK quickstart

> Create a browser app that signs in and verifies its first TinyCloud write

Start here when your app runs in the browser. You will create a small Vite app, sign in with a browser wallet, and write and read back one record.

## Prerequisites

* Node.js 18 or newer
* A modern browser with an injected Ethereum wallet
* A test wallet account; the tutorial does not require funds

## Create the project

```bash theme={null}
npm create vite@latest tinycloud-web -- --template vanilla-ts
cd tinycloud-web
npm install
npm install @tinycloud/web-sdk@2.7.0
```

Replace `src/main.ts` with this complete example:

```typescript theme={null}
import { TinyCloudWeb } from '@tinycloud/web-sdk';

document.querySelector<HTMLDivElement>('#app')!.innerHTML = `
  <main>
    <h1>TinyCloud first write</h1>
    <button id="start">Sign in and write</button>
    <pre id="status">Ready</pre>
  </main>
`;

const button = document.querySelector<HTMLButtonElement>('#start')!;
const status = document.querySelector<HTMLPreElement>('#status')!;

button.addEventListener('click', async () => {
  const provider = (window as Window & { ethereum?: unknown }).ethereum;
  if (!provider) {
    status.textContent = 'Install or unlock a browser wallet, then try again.';
    return;
  }

  button.disabled = true;
  status.textContent = 'Waiting for wallet approval…';

  try {
    const tc = new TinyCloudWeb({
      provider,
      tinycloudHosts: ['https://node.tinycloud.xyz'],
      spacePrefix: 'tinycloud-quickstart',
    });

    await tc.signIn();

    const saved = await tc.kv.put('first-record', {
      message: 'Hello from TinyCloud',
      writtenAt: new Date().toISOString(),
    });
    if (!saved.ok) throw new Error(`${saved.error.code}: ${saved.error.message}`);

    const loaded = await tc.kv.get<{ message: string }>('first-record');
    if (!loaded.ok) throw new Error(`${loaded.error.code}: ${loaded.error.message}`);

    status.textContent = JSON.stringify({
      space: tc.spaceId,
      record: loaded.data.data,
    }, null, 2);
  } catch (error) {
    status.textContent = error instanceof Error ? error.message : String(error);
    button.disabled = false;
  }
});
```

## Run and verify

```bash theme={null}
npm run dev
```

Open the local URL printed by Vite, select **Sign in and write**, and approve the wallet prompts. Success looks like this:

```json theme={null}
{
  "space": "tinycloud:pkh:eip155:1:0x…:tinycloud-quickstart",
  "record": {
    "message": "Hello from TinyCloud"
  }
}
```

The exact chain, address, and timestamp will differ. If the wallet never opens, confirm that the extension is unlocked and allowed on the local Vite origin. If a KV operation fails, the page prints the SDK error code and message instead of reporting a false success.

## What happened

`TinyCloudWeb` used the injected provider to request a SIWE signature. `signIn()` created or restored the app session and ensured the `tinycloud-quickstart` space was hosted. The KV result was only displayed after the same key was read back successfully.

## Next steps

* [Web authentication and session lifecycle](/guides/authentication/web)
* [KV basic operations](/guides/kv/basic-operations)
* [Sharing data](/guides/sharing)
* [Web client overview](/reference/sdk/web)

<Note>
  Verified against `@tinycloud/web-sdk` 2.7.0.
</Note>
