---
title: "The generated client"
description: "tide generate writes a typed Go client into a repository, committed so schema changes appear in review as an API diff."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.tryatlantis.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# The generated client

`tide generate` writes a typed Go client into your repository, scoped to
the namespaces your caller consumes. The generated code is committed: a
schema change appears in review as a diff of the API your application
calls, and the application builds from a clean checkout with no atlantis
server, no `buf`, and no shared SDK.

## What gets generated

With `output_dir` and `generate:` set in `tide.yaml`, `tide generate`
fetches the canonical schema from the server, so proto field numbers match
the server exactly. It filters that schema to the `generate:` namespaces.
A cross-namespace foreign key is a scalar column, so referencing another
namespace's entity does not require generating its types. It then emits
proto sources and typed wrappers under `output_dir`, inside your own
module with your own import paths, running `buf generate` for the wire
types.

Each entity gets a client interface with its six RPCs (`Get`, `BatchGet`,
`Create`, `Update`, `Delete`, `Query`) and a typed method per custom query
and procedure. A `keyless` entity gets no client: without a key there is
nothing to address a row by. A namespace declaring jobs also gets a
`jobs.go` with a typed `Args` struct, handler interface, and
`Register<Job>` helper per job.

`generate` owns only the roots it writes — `atlantis/`, `pb/`, `client/`,
and the two buf config files — and leaves everything else under
`output_dir` alone. It refuses a tree generated by a different caller.

## Why a stale client still works

Proto field numbers are preserved by field name across applies. A removed
field's number is retired and reserved for as long as the entity exists,
and a new field takes the smallest free number. An old client therefore
keeps sending a shape the server understands. It cannot see fields added
since it was generated, and code using a new entity will not compile until
you regenerate. A column whose type changes keeps its number with a new
proto type, so regenerate after a type change before relying on that
field.

`tide apply` never regenerates the client; it refreshes only the
`.tide-cache/` mirror. Its success message reminds you to run
`tide generate`.

## The manifest and `--check`

`tide generate` writes `tide.manifest.json` beside the code: the caller,
the namespaces, the module prefix, and a committed hash per generated
file.

- `tide generate --check` verifies the tree against the manifest with no
  server, no credentials, and no `buf`. It catches hand-edited, missing,
  and leftover files.
- `tide generate --check --against-server` also reports whether the
  schema has moved since this client was generated. It needs credentials
  for that.

The manifest records no timestamp and no checkpoint hash, so two runs that
produce identical code produce an identical manifest.

## Related

- [The typed query surface](/concepts/the-typed-query-surface/) — what the generated `Query` can express.
- [`tide generate`](/reference/cli-tide/#tide-generate) — flags and exit codes.
- [Set up CI](/guides/set-up-ci/) — where `--check` belongs in a pipeline.

Source: https://docs.tryatlantis.dev/concepts/the-generated-client/index.mdx
