Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions docs/getting-started/create-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,24 @@ veryfront dev
Open [http://localhost:3000](http://localhost:3000). File changes reload the
browser.

### Change the port

The dev server binds port 3000. Pass `--port` to bind a different one:

```bash
veryfront dev --port 4000
```

When the requested port is already taken, `veryfront dev` does not fail. It
scans forward for the first free port, reports the switch, and serves there:

```text
! Port 3000 is in use, using 3001 instead
```

Open the URL the CLI prints, not the one in the examples above. The development
MCP server follows the port the dev server bound, plus 2.

## Inspect the scaffold

The `minimal` template creates:
Expand Down
14 changes: 12 additions & 2 deletions docs/getting-started/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,20 +77,30 @@ also set `VERYFRONT_API_TOKEN` directly. Direct provider keys such as
veryfront dev
```

The dev server binds port 3000. When that port is already taken, `veryfront dev`
prints `! Port 3000 is in use, using 3001 instead` and serves on the first free
port after 3000, so open the URL the CLI prints. Pass `--port` to pin one
yourself:
Comment thread
kojiwakayama marked this conversation as resolved.

```bash
veryfront dev --port 4000
```

`veryfront dev` also starts the development MCP server on the app port plus 2.
With the default app port, coding agents can connect to
`http://localhost:3002/mcp` and call `vf_bootstrap` once at session start.
Use [Coding agents](../guides/coding-agents.md) for setup details.

## Verify it worked

Open `http://localhost:3000` and ask:
Open the URL `veryfront dev` printed. Unless the port moved, that is
`http://localhost:3000`. Ask:

```text
What is 128 divided by 8?
```

To test the route without the UI:
To test the route without the UI, using that same port:

```bash
curl -N -X POST http://localhost:3000/api/ag-ui \
Expand Down
33 changes: 33 additions & 0 deletions tests/docs/guide-content.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,39 @@ describe("guide content contracts", () => {
"agents guide samples must guard the getAgent() result before using it",
);
});

it("tells getting-started readers how to choose the dev server port", async () => {
// Port 3000 is the most contended port on a developer machine. `veryfront
// dev` no longer hard-fails on it: it falls forward to the next free port
// and announces the switch. Both halves are invisible to a doc-only
// reader, who then opens the 3000 the page prints and reaches whatever
// process took it. `--port` exists but lives only in `veryfront dev
// --help`, so the getting-started pages that start the dev server have to
// name it and describe the fallback.
const repoRoot = new URL("../../", import.meta.url);
const help = await Deno.readTextFile(
new URL("cli/commands/dev/command-help.ts", repoRoot),
);
const portFlag = help.match(/flag: "(--port [^"]*)"/)?.[1];
assert(
portFlag !== undefined,
"veryfront dev must declare a --port flag in its command help",
);

for (
const path of [
"docs/getting-started/create-project.md",
"docs/getting-started/quickstart.md",
]
) {
const page = await Deno.readTextFile(new URL(path, repoRoot));

assertStringIncludes(page, "veryfront dev --port");
// The exact notice `veryfront dev` prints, so a reader who lands on a
// different port than the page's examples recognizes what happened.
assertStringIncludes(page, "is in use, using");
}
});
});

/**
Expand Down