# Quickstart

In five minutes you'll write a component, run it from the terminal, and see how nesting becomes a dependency and `<Parallel>` becomes independent work. Start after [Installation](https://june.dev/docs/installation.md).

## Check your setup

With `OPENAI_API_KEY` set, run:

```sh
june doctor
```

```text
✓ bun 1.3.0
· ANTHROPIC_API_KEY is not set (anthropic)
…
✓ OPENAI_API_KEY is set (openai)
· XAI_API_KEY is not set (xai)
```

If `OPENAI_API_KEY` shows `not set`, set it before going on.

## Write a workflow

A workflow is a React component that a file default exports. Save this as `brief.tsx`:

```tsx
import { openai } from "june/sdk/openai";
import { Agent, Parallel, Step } from "june";

export default function Brief({ topic }: { topic: string }) {
  return (
    <Agent
      model={openai("gpt-5-mini")}
      instructions="You write short, plain technical briefs."
    >
      <Step id="outline" prompt={`Outline a one-page brief on ${topic}.`}>
        {(outline) => (
          <Parallel>
            <Step
              id="brief"
              prompt={`Write the brief from this outline:\n${outline}`}
            />
            <Step
              id="questions"
              prompt={`List three questions a reader will ask about:\n${outline}`}
            />
          </Parallel>
        )}
      </Step>
    </Agent>
  );
}
```

Read it as a tree. `outline` must finish before its children can render, because they're a function of its result. `brief` and `questions` are independent inside `<Parallel>`, so they start together. There's no separate graph to define.

- `<Agent>` sets the model and instructions for every step inside it. The model is an AI SDK model, passed straight through.
- Each `<Step>` is one call to the agent, named by its `id`: a single model call here, or a whole tool loop when the agent has tools.
- `topic` is an ordinary component prop. A workflow's props are its input.

## Run it

```sh
june run brief.tsx --input '{"topic":"React Suspense"}'
```

`june run` prints progress to stderr as steps start (`▸`) and finish (`✓`):

```
▸ outline
✓ outline
▸ brief
▸ questions
✓ questions
✓ brief
```

Then it prints each step's result to stdout, under its id, in the order the steps finished:

```
── outline
…
── questions
…
── brief
…
```

`outline` ran first, then `brief` and `questions` ran at the same time. Which of those two finishes first depends on the model.

## Use the output

The plain text is for people. To hand the run to a script, add `--json`:

```sh
june run brief.tsx --input '{"topic":"React Suspense"}' --json > brief.result.json
```

stdout is then one JSON object: `steps` (each step's result, by id), `usage` (the tokens the run used), and `tree` (the run's trace). Progress still goes to stderr, so stdout stays clean to parse or pipe into the next program.

## Pass input from a file

`--input` takes the workflow's props as a JSON object. For anything longer, put them in a file and pass `--input-file`:

```json
{ "topic": "React Suspense" }
```

```sh
june run brief.tsx --input-file brief.json
```

June doesn't echo the input, even in errors, and refuses anything that isn't a JSON object. Input your workflow puts in a prompt or a result still shows up in its output.

## If it doesn't run

- **`OpenAI API key is missing`**: the step fails with a `✗` and `june run` exits 1. Set `OPENAI_API_KEY`, or put it in a `.env` file where you run `june`.
- **`june: command not found`**: run it as `bunx june`.
- **A model error from the provider**: `openai(...)` takes OpenAI model ids. For another provider, install its package and use its model function.

[Installation](https://june.dev/docs/installation.md) and the [CLI reference](https://june.dev/docs/cli.md) cover the rest.

## Next

Read [React as the workflow](https://june.dev/docs/workflows.md) next: branches, fan-out, recovery, approvals and resuming, with the same components. The [CLI](https://june.dev/docs/cli.md) is the reference for every command and option.
