grit sync — Go to TypeScript

Why it exists, when to run it, what it does and doesn't handle.

6 minmedium

One command, one purpose: keep the TypeScript types in sync with the Go structs. grit sync reads every model and re-writes packages/shared/src/types/. Run it any time the API shape changes.

What it does

Terminal
$grit sync

You'll see:

Syncing Go types → TypeScript...
✓ packages/shared/types/contact.ts
✓ packages/shared/schemas/contact.ts
✓ apps/admin/resources/contacts.ts (added 1 field to columns + form)
✓ packages/shared/types/group.ts
✓ packages/shared/schemas/group.ts
✅ Synced 2 model(s) to TypeScript + Zod
✅ Auto-added 1 field to admin resource files
v3.31.16: sync now also walks apps/admin/resources/<plural>.ts and auto-appends any new model fields between the // grit:cols:auto-end and // grit:fields:auto-end markers. Customised entries are never touched. Resources scaffolded before v3.31.16 don't have the markers — sync prints a per-resource warning telling you what to add.

Why it matters

Without sync, every time you add a field to a Go struct you also have to remember to add it to the TS type. That's how schema drift happens — your API returns is_active but the frontend types still say it doesn't exist, so VS Code says "property does not exist" while the data IS being sent.

With sync, you change Go once and run one command. TS picks up the new field. Build errors point you at every place to update.

When to run it

  • After every grit generate resource ...
  • After you manually edit a Go struct
  • After you pull from main and someone else changed models
  • In CI before pnpm build
Many teams add grit sync to a pre-commit hook or to the first step of turbo dev. Make it muscle memory and you'll never ship a drifted type again.

What it doesn't do

Sync handles the shape — the TS type matches the Go struct. It doesn't handle behaviour — e.g., custom validation rules, derived fields, or computed properties. Those still need manual work in the Zod schema.

Quick check

You add a `discount` field to Product in Go. You re-run `grit migrate` but not `grit sync`. What breaks?

Try it

Trigger schema drift, then fix it:

  1. Add IsActive bool `gorm:"default:true" json:"is_active"` to Product in apps/api/internal/models/product.go.
  2. Run grit migrate.
  3. Try to access product.is_active somewhere in apps/web/ — TypeScript will complain.
  4. Run grit sync. The TS error vanishes.

Paste before/after TS errors in notes.md.

What's next

Generate writes eight files plus a handful of marker-fenced injections; sync keeps the types and the admin definitions aligned. Together they let you add a resource to a Grit project in under a minute.

Next lesson — grit remove resource. The reverse: undo every file write and injection from a generate run in one command. Useful when an experiment doesn't pan out and you don't want stale resources cluttering the sidebar and routes file.

Spot a typo? Have an idea?

Help us improve this lesson. One click opens a GitHub issue with the lesson URL pre-filled — suggest clearer wording, report a bug, or request more depth. The course keeps improving thanks to learners like you.

Suggest an improvement on GitHub