# JavaScript Quickstart (/agent/adk-ts)

**Run a script that asks Jan a question and prints its answer as it arrives.**

You need **Node.js 20+** and access to a model provider. No Git checkout, Jan Desktop, Rust
toolchain or TypeScript build step is needed.

<Callout type="warning">
The ADK is a preview and is not published to npm yet: `npm install @janhq/adk` does not work.
Install the nightly package below instead. The runtime is a separate, prebuilt download.
</Callout>

<Steps>

### Install the ADK and runtime [#install-the-adk-and-runtime]

In a new directory, install the latest nightly ADK package:

<Tabs items={['macOS / Linux', 'Windows PowerShell']}>
  <Tabs.Tab>
```bash
mkdir jan-js-demo && cd jan-js-demo
npm init -y
npm install "$(node -e "fetch('https://delta.jan.ai/adk-nightly/manifest.json').then(r => r.json()).then(m => console.log(m.packages.javascript.url))")"
```
  </Tabs.Tab>
  <Tabs.Tab>
```powershell
mkdir jan-js-demo; cd jan-js-demo
npm init -y
npm install (node -e "fetch('https://delta.jan.ai/adk-nightly/manifest.json').then(r => r.json()).then(m => console.log(m.packages.javascript.url))")
```
  </Tabs.Tab>
</Tabs>

The command looks up the current build and installs its versioned package URL, so
`package.json` pins that exact build. The [download page](https://delta.jan.ai/adk-nightly/index.html)
shows the same command with the URL written out.

Install the `jan` runtime:

<Tabs items={['macOS / Linux', 'Windows PowerShell']}>
  <Tabs.Tab>
```bash
curl -fsSL https://delta.jan.ai/jan-cli/install-jan-agent.sh | bash
export PATH="$HOME/.local/bin:$PATH"
```
  </Tabs.Tab>
  <Tabs.Tab>
```powershell
irm https://delta.jan.ai/jan-cli/install-jan-agent.ps1 | iex
```
Follow the installer's PATH instructions before continuing.
  </Tabs.Tab>
</Tabs>

```bash
jan cli agent rpc --help
```

If you already have a current Jan runtime, skip its installation.

### Connect a model [#connect-a-model]

Sign in to Tokamak:

```bash
jan login
```

Or [configure your own provider](/agent/quickstart#connect-a-provider). Both the CLI and ADK
use Jan's provider configuration. If you have already configured Jan, skip this step.

### Save and run the script [#save-and-run-the-script]

Save this complete example as `hello.mjs` in `jan-js-demo`:

```js filename="hello.mjs"
import { JanRuntime } from '@janhq/adk'

const runtime = await JanRuntime.start()
try {
  const session = await runtime.createSession({ ephemeral: true, builtins: false })
  const turn = await session.prompt('Explain what a mutex is in one sentence.')

  for await (const event of turn) {
    if (event.type === 'token') process.stdout.write(event.text)
  }

  const result = await turn.result()
  if (result.stopReason === 'error') throw new Error(result.error)
  console.log(`\nFinished: ${result.stopReason}`)
} finally {
  await runtime.close()
}
```

```bash
node hello.mjs
```

The answer depends on your model. A successful run prints answer text followed by
`Finished: completed`.

</Steps>

## What just happened? [#what-just-happened]

- `start()` launched the Jan runtime and checked its protocol version.
- `createSession()` created a conversation. `ephemeral: true` avoids saving it; `builtins: false`
  disables built-in and external tool sources, so this first example only answers a question.
- `prompt()` started a turn. Each `token` event contains another piece of the answer.
- `result()` returned the final status. `close()` ended the process, even if the script failed.

Send another prompt on the same `session` to continue the conversation. To select a specific
configured model, add `model: 'provider/model-id'` to `createSession()`.

TypeScript uses the same API; the installed package includes type declarations.

## If it fails [#if-it-fails]

| Problem | What to do |
| --- | --- |
| Cannot find `@janhq/adk` | Run the `npm install` command above in `jan-js-demo`, and keep `hello.mjs` there. |
| The package download fails | No nightly is available right now. Use the [source install](/agent/adk-nightly#source-install-fallback). |
| Cannot start `jan` | Add it to PATH, or pass its absolute path as `JanRuntime.start({ bin: '/path/to/jan' })`. |
| Unknown `rpc` command or protocol mismatch | Run `jan update`, then retry startup. |
| No model, authentication error, or provider error | Run `jan login` or fix the provider configuration. A model override must name a model that provider serves. |

See [Process & failures](/agent/adk-runtime) for error handling in an application.

## Next: give the agent a function [#next-give-the-agent-a-function]

The first script cannot act on your app. Add a [host tool](/agent/adk-tools) when you want it
to read application data or perform an action.
