If you've ever spent hours debugging a mobile app because the client expected one data shape and the server sent another, you know the frustration. With Inky, that problem doesn't exist. The Inky iOS app and its backend never disagree about a shape, because the Swift types are generated from the same Zod schema the server validates against. One source of truth, two languages — the client cannot drift from the contract.
This approach cuts out an entire class of bugs that plague mobile development. You define your data contract once, in a language-agnostic way, and then let tooling handle the translation. It's a fundamental shift in how you manage your API surface, moving from manual synchronization to automated consistency.
The Problem with Manual Type Management
Most mobile applications, especially those with a small team or a single operator, rely on manual type definitions. You might have a User struct in Swift and a User interface in TypeScript or a User class in Python. When the backend changes the User object — maybe adding a new field or changing a type — you have to remember to update the client-side definition. And vice versa.
This process is brittle. It's easy to forget a field, misspell a property, or get a type wrong. These small discrepancies lead to runtime errors, silent data corruption, or unexpected UI behavior. The more complex your data models and the more endpoints you have, the higher the chance of these mismatches. For a solo operator, every minute spent on these avoidable bugs is a minute not spent building new features or improving the product.
How Inky Solves It: Zod as the Single Source of Truth
The core of Inky's solution is Zod, a TypeScript-first schema declaration and validation library. Zod allows you to define your data shapes with a rich, expressive syntax. But the real power comes from its ability to be a single source of truth for both your backend and your client.
On the backend, Zod schemas are used to validate incoming requests and outgoing responses. This ensures that the data flowing through your API adheres to the defined contract. If a request comes in with an unexpected shape, Zod catches it immediately, preventing bad data from entering your system.
Generating Swift Types from Zod
The magic happens when you extend this concept to the client. Instead of manually writing Swift Codable structs, we use a custom script to generate them directly from the Zod schemas. This means:
- Backend defines the schema: The backend team (or the solo operator) defines the canonical data shape using Zod.
- Swift types are generated: A build step runs a script that reads these Zod schemas and outputs corresponding Swift
Codablestructs. - Client uses generated types: The iOS app imports and uses these generated Swift types for all its network requests and responses.
This workflow guarantees that the Swift types in the Inky app are always in perfect sync with the Zod schemas on the server. If a field is added to a Zod schema, the generated Swift type will automatically include it. If a field is removed, it's removed from Swift. There's no room for human error in translating the contract.
