# Introduction

> voxal is a platform for interactive terminal apps that anyone can run with a single SSH command, no install required

voxal is a platform for **interactive terminal apps that anyone can run over SSH**. You
write a small JavaScript app, deploy it with one command, and from then on anyone can use
it with `ssh your-app@voxal.sh`. No frontend to host, no binary to ship, nothing for your
users to install. If they have an SSH client, and every machine does, they can run your app.

Think of it as Vercel, except the interface is delivered over SSH instead of the browser.
You ship the logic; voxal runs it, renders it live to each user's terminal, and keeps your
backend code (API calls, secrets, business logic) on the server where users never see it.

```js title="app.js"

createApp()
  .onConnect((conn) => {
    conn.write('hello from voxal\r\n');
    conn.write('press q to quit\r\n');
  })
  .onKey((conn, data) => {
    if (data === 'q') conn.close();
  })
  .listen();
```

```bash
npm create voxal-app my-app
cd my-app && npm run deploy
# then anyone can run:  ssh my-app@voxal.sh
```

## Start here

<Cards>
  <Card title="Quickstart" href="/quickstart" description="Go from nothing to a deployed app you can SSH into, in about five minutes." />
  <Card title="How voxal works" href="/how-it-works" description="The connection lifecycle and the model your app runs in." />
  <Card title="Guides" href="/guides/building-uis" description="Build real things: React UIs, keyboard input, data fetching, and a chat app." />
  <Card title="SDK reference" href="/sdk" description="createApp, the connection, fetch, and the full React UI layer." />
  <Card title="CLI reference" href="/cli" description="The commands for scaffolding, previewing, and shipping an app." />
  <Card title="Limits and quotas" href="/platform/limits" description="Bundle size, compute, timers, and fetch limits, in one place." />
</Cards>

## What you write

Every voxal app imports one package, [`@voxalsh/sdk`](/sdk), which gives you two ways to
build. Use whichever fits the app.

- **Core.** [`createApp`](/sdk/lifecycle) plus a [connection](/sdk/connection) object. You
  handle events and write strings (with ANSI escapes) straight to the terminal. Ideal for
  small tools, streams, and anything you want byte-level control over.
- **UI (React).** [`@voxalsh/sdk/ui`](/sdk/ui) is a real terminal UI framework: flexbox
  layout, `<Box>` and `<Text>`, and hooks like `useInput`. It mirrors
  [Ink](https://github.com/vadimdemedes/ink) one to one, so React knowledge transfers directly.

```jsx title="app.jsx"

function Counter() {
  const [n, setN] = useState(0);
  const { exit } = useApp();
  useInput((input, key) => {
    if (input === 'q') exit();
    if (key.upArrow) setN((c) => c + 1);
    if (key.downArrow) setN((c) => c - 1);
  });
  return (
    <Box borderStyle="round" padding={1} flexDirection="column">
      <Text>count: <Text bold color="green">{n}</Text></Text>
      <Text dimColor>up and down to change, q to quit</Text>
    </Box>
  );
}

serve(() => <Counter />);
```

## How it runs

When someone connects, voxal hands the SSH session to your app and nothing else. There is
no shell, no login prompt, and no filesystem on the other end. The username in
`ssh your-app@voxal.sh` is your app's name.

Your app runs in an isolated sandbox, one per app, that serves every connected user at once.
Each user gets their own connection; your shared logic lives in one place. Idle apps scale
to zero and boot again in milliseconds on the next connection, so you only run when someone
is actually using your app. Read [How voxal works](/how-it-works) for the full picture.

<Callout title="New here?">
The fastest path to a running app is `npm create voxal-app`. The
[Quickstart](/quickstart) walks through it end to end.
</Callout>

---

Source: https://docs.voxal.sh/
