> ## Documentation Index
> Fetch the complete documentation index at: https://arkor-92aeef0e-eng-716.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Scaffold an Arkor project, fine-tune a small open-weight LLM, and chat with it from a local Studio.

In a few minutes you will go from zero to a fine-tuned model you can chat with in a local Playground. The training run itself takes 7 to 12 minutes. The first job you submit also waits for a GPU to be allocated before the training run starts; that wait can be a few minutes (occasionally longer) and only happens for the first run after a quiet period.

<Info>
  **How Arkor uses GPUs.** Arkor splits GPUs into two pools:

  * **Inference GPUs** run the model after training (the Playground and any production inference). These stay on an active worker, so they are always warm and respond immediately.
  * **Training GPUs** run fine-tuning jobs. To keep costs predictable, these are not kept warm. When you click **Run training**, Arkor allocates a GPU on demand. If a worker is still warm from a recent job, the allocation finishes in seconds. Otherwise it starts from cold (the so-called cold start: provisioning, pulling the container image, loading the base model), which can take several minutes.

  After GPU allocation, the training run itself takes about 7 to 12 minutes for the templates. The Jobs view in Studio shows both phases.
</Info>

## Prerequisites

* **Node.js 22.22.0 or newer.** Node 24 is recommended.
* **A package manager.** pnpm, npm, yarn, and bun all work. Each snippet below ships as a tab group, so pick the one you use and the rest of the page follows.
* A working internet connection. Training runs on Arkor's managed GPUs.

No account, no credit card, no GPU on your machine.

## 1. Scaffold a project

<CodeGroup>
  ```bash pnpm theme={null}
  pnpm create arkor my-arkor-app
  cd my-arkor-app
  ```

  ```bash npm theme={null}
  npm create arkor@latest my-arkor-app
  cd my-arkor-app
  ```

  ```bash yarn theme={null}
  yarn create arkor my-arkor-app
  cd my-arkor-app
  ```

  ```bash bun theme={null}
  bun create arkor my-arkor-app
  cd my-arkor-app
  ```
</CodeGroup>

The scaffolder asks which template you want. Pick the one closest to what you eventually want to build:

| Template    | Task                   | Output shape                                 | Training run (excludes GPU allocation) |
| ----------- | ---------------------- | -------------------------------------------- | -------------------------------------- |
| `triage`    | Support triage         | `{ category, urgency, summary, nextAction }` | \~7 min                                |
| `translate` | 9-language translation | `{ translation, detectedLanguage }`          | \~7 min                                |
| `redaction` | PII redaction          | `{ redactedText, redactedCount, tags }`      | \~12 min                               |

Each template pairs the same small open-weight base (`gemma-4-E4B-it`) with a curated public dataset on HuggingFace. The training is real and finishes in minutes, so you get to see the whole loop end to end.

To skip the prompt:

<CodeGroup>
  ```bash pnpm theme={null}
  pnpm create arkor my-arkor-app --template triage
  ```

  ```bash npm theme={null}
  npm create arkor@latest my-arkor-app -- --template triage
  ```

  ```bash yarn theme={null}
  yarn create arkor my-arkor-app --template triage
  ```

  ```bash bun theme={null}
  bun create arkor my-arkor-app --template triage
  ```
</CodeGroup>

## 2. Look at what was generated

```
my-arkor-app/
├── src/arkor/
│   ├── index.ts        # createArkor({ trainer })
│   └── trainer.ts      # createTrainer({ ... })
├── arkor.config.ts
├── .arkor/             # state + build artifacts (gitignored)
└── package.json        # dev / build / start
```

The two files that matter for now:

* **`src/arkor/trainer.ts`** holds your trainer definition. Model, dataset, LoRA settings, hyperparameters, and lifecycle callbacks all live here.
* **`src/arkor/index.ts`** is the entry point. It calls `createArkor({ trainer })` so the CLI and Studio can discover what to run.

Open `trainer.ts`. The shape is the same across templates; only the dataset, output schema, and example prompts differ.

## 3. Open Studio and start a run

<CodeGroup>
  ```bash pnpm theme={null}
  pnpm dev
  ```

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

  ```bash yarn theme={null}
  yarn dev
  ```

  ```bash bun theme={null}
  bun dev
  ```
</CodeGroup>

This runs `arkor dev`, which boots Studio at `http://localhost:4000`. Studio is the UI; `arkor dev` itself does not start training and does not watch your trainer files.

In the browser, click **Run training**. Studio submits the job to the managed backend in the background and streams the output back into the page. The first time you trigger anything, an anonymous workspace is created automatically: no signup, no credit card.

Once a run is in flight, three views matter:

* **Jobs.** A list of training runs. Click into one to see live status.
* **Loss chart and event log.** As the run streams from the managed GPU, the loss curve updates and the log tail shows training events. The first job's first phase is the GPU allocation; during that time the status reads `Warming up GPU`, the loss chart shows a `Waiting for GPU` placeholder, and the events list is empty. Once the `training.started` event arrives, the status flips to `Running` and the curve begins to update. The training run itself takes about 7 to 12 minutes depending on the template.
* **Playground.** After a job completes, pick the final adapter from the selector and chat with it. Use the mode toggle to switch between the base model and the adapter. To run inference on intermediate checkpoints while a run is still in flight, use `onCheckpoint` callbacks instead of Studio.

If you edit `src/arkor/` between runs, refresh the Run training page (or run `arkor build`) before the next click so the new code is what runs.

## 4. Tie runs to an account (optional)

Anonymous workspaces are useful for trying things out, but the work is tied to the anonymous token on this local machine and is not visible from another device or another account. To keep training under an account, sign in with OAuth **before** you start the next run:

<CodeGroup>
  ```bash pnpm theme={null}
  pnpm arkor login --oauth
  ```

  ```bash npm theme={null}
  npm arkor login --oauth
  ```

  ```bash yarn theme={null}
  yarn arkor login --oauth
  ```

  ```bash yarn-berry theme={null}
  yarn run arkor login --oauth
  ```

  ```bash bun theme={null}
  bun arkor login --oauth
  ```
</CodeGroup>

This runs the Arkor Cloud OAuth (PKCE) flow on a loopback port and links your local credentials to an account. From then on, runs from this machine show up under that account on any device.

The scaffolded project installs `arkor` as a local devDependency, so use your package manager's local-bin runner over a bare `arkor` invocation unless you have installed the CLI globally. The generated project README walks through the equivalent setup for pnpm, npm, yarn, and bun.

A few caveats. Running `arkor login` without a flag opens an interactive picker that defaults to `Anonymous`; accepting the default mints a brand-new anonymous token (a new `anonymousId`) and overwrites `~/.arkor/credentials.json`, so it lands you in a different workspace from the previous anonymous session, not a refresh of it. Switching to OAuth overwrites the same file and does not migrate prior anonymous workspaces or jobs into the account. Merging anonymous work into an OAuth account once you sign in is on the roadmap; until that lands, sign in before the runs you want associated with the account.

## 5. Where to go next

* **Concepts.** Read [Concepts](/concepts/overview) to build a mental model of `createArkor`, `createTrainer`, the lifecycle callbacks, and Studio.
* **Customize the trainer.** Open `src/arkor/trainer.ts` and tweak `lora.r`, `maxSteps`, or add more callbacks. Refresh the Run training page (or run `arkor build`) before the next click so your edits land.
* **Try another template.** Re-run the scaffolder with a different `--template` to compare.
