Skip to content Documentation index for agents (llms.txt)
Glotto Beta
Get started

Custom code

Generated SDKs cover the API, but real projects need a little hand-written code too — a convenience wrapper, an extra helper, a tweak to a generated method. Glotto is built so your code survives regeneration. There are two mechanisms:

  1. The customer-owned extension directorylib/ in most SDKs and Sources/<Module>/Custom/ in Swift. Shipped today.
  2. Patch preservation — three-way merge of edits to generated files, in the release PR and (opt-in) locally.

For anything you write from scratch, prefer that extension directory: it’s where preservation is guaranteed.

The customer-owned extension directory

Every generated SDK has an extension directory that is yours. Most engines use lib/; Swift uses Sources/<Module>/Custom/, inside its conventional SwiftPM target. The contract is enforced by glotto generate and drift detection the same way for every language:

  • Customer-owned, write-if-absent. Glotto seeds the directory once with an entry-point stub, then never overwrites that customer-owned file. Every managed file is regenerated normally, but your extension is left exactly as you left it.
  • Excluded from drift. Drift detection ignores customer-owned files on both sides, so an edit there never shows up as drift or blocks a release — the extension is not part of the “regenerate must match” contract.
  • A stable import target. The entry-point stub (TypeScript’s lib/index.ts, Python’s lib/__init__.py, Swift’s Sources/<Module>/Custom/Custom.swift, …) gives you a fixed place to export from, and its header comment tells you how code you add there reaches the SDK’s surface in that language.
The half of the tree Glotto never writes twice One TypeScript target, and one real generate run over it. The stub below is the file Glotto writes once and then never writes again; the method beside it is regenerated on every run, under the checksum that decides which of the two you are editing. Derived from examples/custom-code-lib/inputs — every byte below is sliced from that demo or from one real generate run over it.

Your glotto.yml — one TypeScript target, and not a word about custom code

examples/custom-code-lib/inputs/glotto.yml targets
targets:
  typescript: {}

What Glotto seeds ONCE — src/lib/index.ts, yours from then on

typescript/src/lib/index.ts whole file

// Custom code — never overwritten by `glotto generate`.
//
// This file, and everything else under `lib/`, is yours. `glotto generate`
// writes it once and then leaves it untouched on every subsequent run, and
// drift detection ignores `lib/` entirely — so helpers, overrides, and
// extensions you add here survive regeneration. Re-export them from this entry
// point to keep a single import surface for your custom code.

export {};
sha256 066b46389fdd95f09343610f9fdb02d97e8c50f27626cd164f919fe40f029ab8

What Glotto owns — regenerated every run, under the checksum that guards your edits

typescript/src/resources/widgets.ts WidgetsResource.createWidget

  createWidget(params: NewWidget, options?: RequestOptions): Promise<Widget> {
    return this.core.request<Widget>('POST', '/widgets', { ...options, body: params, contentType: 'application/json' });
  }
generated-checksum 405b8140007456df5543f12bcfa55e05b969d62b5cefcbe186d4f484ee1bd247

Put helpers, wrappers, and hand-authored code in the extension directory, and it is preserved on every regenerate. Anything you expose from the stub reaches the SDK’s public surface according to that language’s normal package conventions.

Upgrading an existing Swift SDK: if Glotto finds the former lib/Custom.swift and no file at Sources/<Module>/Custom/Custom.swift, the next glotto generate copies its contents exactly to the SwiftPM target and retains the legacy file as a backup for you to remove after review. If both files already exist, Glotto leaves both untouched and prints the paths to reconcile; it never chooses one customer-owned copy over the other.

Every language, on the SDK’s surface: the lib/ machinery (write-if-absent + drift exclusion) is engine-agnostic, every SDK language seeds an entry-point stub, and custom code joins the SDK’s public surface per language: TypeScript and React Native re-export it as lib; Swift compiles Custom/ as part of its module; Java, Kotlin, Rust, C#, Dart, and Elixir compile lib/ into the SDK artifact; Ruby loads it with require "glotto"; and the Go, Python, and PHP stubs document the exact import path to use.

Editing generated files

Sometimes you need to change a generated file directly. Glotto’s rule is simple: it never silently overwrites your edits.

Every generated file carries a checksum comment over the bytes Glotto produced — the generated-checksum stamped under the emitted pane above is the real one for that file, read out of the run that produced it rather than written here.

On the next regenerate, Glotto compares that checksum to the file’s current contents. If they match, the file is pristine and is regenerated freely. If they differ, you’ve hand-edited it — so Glotto performs a three-way merge (your version against the old and new generator output) and, on any conflict, writes standard conflict markers and surfaces them in the release pull request for you to resolve, rather than clobbering your change.

How it runs today: the checksum marker ships on every generated SDK language, the release-PR flow does the full three-way merge automatically, and locally glotto generate preserves your edited file untouched — or truly merges it when you opt in with --merge. Even the generated README.md is covered — its checksum rides in an HTML comment that’s invisible in the rendered README, so badges and prose you add survive regeneration. The customer-owned extension remains the simplest home for hand-authored code — no merge to think about at all.

Which should I use?

You want to… Use
Add new helpers, wrappers, or utilities The customer-owned extension — always preserved
Re-export or extend generated types The customer-owned extension, importing generated types normally
Change the behavior of a generated method Edit the generated file (preserved; merged in the release PR or with --merge) — or wrap it in the extension

See Drift detection for how customer-owned files are excluded from the drift gate. The CLI reference documents the commands that enforce this contract — glotto generate (whose --force overwrites managed files with local edits) and drift detection.