# Getting started

This guide builds and runs the Petclinic reference application using ordinary
Go source and inspectable generated Go. It requires Go 1.26.5. No database,
container, or network download is needed after the application's declared
module and tool dependencies are present.

## Authorize the CLI

From the consuming application's module, select compatible toolchain versions
with ordinary Go commands:

```text
go get -tool github.com/spice-framework/toolchain/cmd/spice@<version>
go get -tool github.com/spice-framework/toolchain/cmd/spice-annotation-core@<version>
go tool github.com/spice-framework/toolchain/cmd/spice version
```

The application's `go.mod` authorizes the executable dependencies. Core does
not build or download the CLI, and Spice does not maintain a second plugin
dependency system. Release archives are produced by the toolchain repository's
exact-tag process described in [releasing.md](/framework/releasing/).

## Create a clean application

`spice new` creates a valid-Go application and its ordinary `go.mod` without
running a Go command, downloading a module, initializing Git, or overwriting a
non-empty directory:

```text
spice new --module example.com/acme/hello --directory hello
cd hello
go mod download
go tool github.com/spice-framework/toolchain/cmd/spice generate --target Hello .
go tool github.com/spice-framework/toolchain/cmd/spice verify .
go tool github.com/spice-framework/toolchain/cmd/spice run --target Hello .
```

The target name and generated-package ID derive from the final module-path
segment through the same compiler-owned normalization used during analysis.
Initial generation supplies the missing generated package through an in-memory
overlay; no physical stub is created. Run `go mod tidy` after that first
generation. `--spice-version` selects an exact pre-release or release when the
CLI build should not select its own version. `--replace` is an explicit local
development option and is never emitted by a release workflow by default.

Add an ordinary dependency through a previewed standard Go operation:

```text
spice add golang.org/x/sync/errgroup@v0.22.0
spice add --apply golang.org/x/sync/errgroup@v0.22.0
```

The first command runs `go get` only against a temporary sibling modfile and
prints the exact bounded `go.mod`/`go.sum` diff. `--apply` creates a fresh plan,
prints it, and writes its exact after-images only while both original file
hashes still match. Add `--tool` to use Go's `go get -tool` authorization path.
These commands are explicit network-capable developer actions; normal
analysis, generation, and editor operation remain offline and read-only.

## Inspect the application

Petclinic is an independent consumer module at
[`spice-framework/petclinic`](https://github.com/spice-framework/petclinic).
Clone it separately from the core framework. Its `go.mod` selects an immutable
Spice version, authorizes the CLI and annotation tool with standard Go `tool`
directives, and contains no local `replace`:

```text
git clone https://github.com/spice-framework/petclinic.git
cd petclinic
go tool github.com/spice-framework/toolchain/cmd/spice verify .
go tool github.com/spice-framework/toolchain/cmd/spice generate --check --target Petclinic .
```

The process entrypoint in `main.go` is valid Go:

```go
// @import { Application } from "github.com/spice-framework/spice/annotation/core"
// @import { Enable } from "github.com/spice-framework/spice/annotation/management"

// @Application
// @Enable(expose=["health", "readiness", "info"], access="loopback")
func main() {
	os.Exit(spiceapp.Main(os.Args[1:]))
}
```

`@import` is file-scoped and explicit. The imported descriptor is a real Go
function that the compiler decodes without executing. The target module's
`go.mod` is the only authority that permits its handler tool to run.
`spiceapp` is the ordinary Go import alias for
`github.com/spice-framework/petclinic/internal/spicegen/petclinic`.

## Verify and generate

From the standalone Petclinic root, use its authorized Spice tool dependency:

```text
go tool github.com/spice-framework/toolchain/cmd/spice verify .
go tool github.com/spice-framework/toolchain/cmd/spice generate --check --target Petclinic .
```

`generate --check` is read-only. To create or update owned artifacts, run the
same command without `--check`. The output has three clear roles:

```text
internal/spicegen/petclinic/spice_assembly_gen.go
    bounded construction-phase sequencing
internal/spicegen/petclinic/spice_{contracts,configuration,providers}_gen.go
    typed contracts, configuration metadata, and dependency construction
internal/spicegen/petclinic/spice_http_gen.go
    HTTP and management coordination
internal/spicegen/petclinic/spice_http_route_<symbol>_<id>_gen.go
    one stable, source-linked route adapter
internal/spicegen/petclinic/spice_{features,lifecycle,command}_gen.go
    optional features, reusable lifecycle, and process entrypoint behavior
internal/spicegen/petclinic/sources/<package>/<source>_spice_gen.go
    one source-owned unit with direct construction, binding, and assertions
internal/spicegen/petclinic/artifacts/openapi.json
    generated non-Go contracts
.spice/petclinic.manifest.json
    hashes, roles, source origins, and generated ranges
```

Generated files are committed, formatted Go. The ownership manifest prevents
Spice from overwriting manual edits or unrelated files. Run `go tool
github.com/spice-framework/toolchain/cmd/spice generated --source main.go` to
locate the source-owned application unit, or pass that generated path with
`--generated` for the reverse mapping.

## Run and debug

Start the application:

```powershell
$env:SPICE_PETCLINIC_ADDRESS = "127.0.0.1:8080"
go tool github.com/spice-framework/toolchain/cmd/spice run --target Petclinic .
```

```sh
SPICE_PETCLINIC_ADDRESS=127.0.0.1:8080 \
  go tool github.com/spice-framework/toolchain/cmd/spice run --target Petclinic .
```

Open `http://127.0.0.1:8080/`. Search owners, edit an owner, add a pet and a
visit, and inspect `/vets`. Management routes under `/actuator/` accept only a
direct loopback peer.

`spice run` generates safely and then builds the complete package with
`-trimpath`; it never compiles a temporary source fragment. A Go debugger sees
normal generated calls and steps directly into handwritten constructors,
controllers, and repositories. The GoLand plugin uses this complete-package
path for Run and generates before native Go/Delve Debug.

## Use the development loop

Replace `run` with `dev`. Spice watches relevant files, debounces changes, and
gracefully replaces the process only after analysis, generation, and build
succeed:

```text
go tool github.com/spice-framework/toolchain/cmd/spice dev --target Petclinic .
```

Add `// @Unknown` below `// @Application` and save. The compiler reports an
exact diagnostic while the last-known-good process remains live. Remove the
invalid annotation and save; Spice regenerates and restarts the package.

## Test a generated application

Use ordinary Go tests for domain code. For generated wiring, create a typed
context with `spicetest.NewContext`; for routes, use `spicetest.NewHTTP`; for
database behavior that must roll back, use `spicetest.NewSQL`. These helpers
accept typed generated applications and never use reflection, provider
replacement, or a runtime container.

Focused module tests retain ordinary Go controls:

```text
go tool github.com/spice-framework/toolchain/cmd/spice test --module example.com/shop/orders --race --count=1 ./...
```

See [testing.md](/framework/testing/) for complete examples and cleanup behavior.

## Next steps

- [application.md](/framework/application/) explains discovery and generated ownership.
- [annotations.md](/framework/annotations/) lists the supported annotation contracts.
- [Spice for GoLand](https://github.com/spice-framework/goland) installs and
  verifies the independently versioned primary editor experience.
- [spring-to-spice.md](/framework/spring-to-spice/) maps familiar Spring concepts.
- [developer-proof.md](/framework/developer-proof/) runs the decisive editor/dev proof.
