<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/one-model-many-views-type-safe-transforms-with-valibot-and-doba-jdqcdjqot" -->

---
title: One Model, Many Views: Type-Safe Transforms with Valibot...
description: A guest post introduces doba, a schema registry library that pairs with Valibot (or any Standard Schema compatible library) to manage type-safe transformations...
canonical: https://daily.dev/posts/one-model-many-views-type-safe-transforms-with-valibot-and-doba-jdqcdjqot
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: One Model, Many Views: Type-Safe Transforms with Valibot and doba | daily.dev
og:description: A guest post introduces doba, a schema registry library that pairs with Valibot (or any Standard Schema compatible library) to manage type-safe transformations...
og:url: https://daily.dev/posts/one-model-many-views-type-safe-transforms-with-valibot-and-doba-jdqcdjqot
og:image: https://api.daily.dev/og/posts/jdQcDjqOt.png
og:image:alt: One Model, Many Views: Type-Safe Transforms with Valibot and doba
og:image:width: 1200
og:image:height: 630
og:locale: en
---

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

# One Model, Many Views: Type-Safe Transforms with Valibot and doba

**[Valibot: The modular and type safe schema library](https://daily.dev/sources/valibot)** · 6 min read · 0 upvotes · 0 comments

## Summary

A guest post introduces doba, a schema registry library that pairs with Valibot (or any Standard Schema compatible library) to manage type-safe transformations between different data shapes, such as database rows, frontend views, AI-model inputs, and legacy API formats. Instead of writing ad hoc mapping functions, developers register schemas and define migrations between them; doba automatically chains migrations to find paths between schemas that have no direct transform defined. It also supports a migration context for recording defaulted or guessed values during conversions, a pipe builder for mechanical renames/drops with type-checked chaining, and schema identification for unknown incoming data via field matchers. Use cases highlighted include API versioning, LLM prompt formatting, legacy data imports, and webhook payload normalization.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://valibot.dev/blog/same-data-different-shapes>

## Questions this post answers

### How can I automatically chain data transformations between schemas that don't have a direct migration defined in TypeScript?

A schema registry can walk a graph of defined migrations and chain intermediate ones automatically. For example, if only database-to-frontend and frontend-to-ai migrations are registered, calling a transform from database to ai still works because the registry routes through the frontend schema, without requiring a direct database-to-ai migration to be written.

_Developers comparing data-mapping approaches can find write-ups like this on daily.dev._

### How do I track why fields were defaulted during a legacy data migration in TypeScript?

Pass a context object into each migration function that exposes methods like ctx.defaulted() and ctx.warn() to record decisions made during conversion, such as generating a missing id or guessing an email from a name field. These records appear in the transform result's meta.defaults and meta.warnings arrays so the reasoning is preserved instead of disappearing into function bodies.

_Teams handling messy legacy imports often track patterns like this via daily.dev._

### How can I detect which schema an unknown piece of data matches before transforming it in a TypeScript app?

Define identify guards per schema using field matchers such as match.field('passwordHash') or match.fields('createdAt', 'settings'), then call identifyAndTransform on the unknown data and a target schema name. Guards run in definition order, detecting the source schema, chaining the migration path, and returning a typed error rather than crashing if nothing matches.

_daily.dev surfaces practical patterns like this for developers normalizing inconsistent payloads._

## Similar posts on daily.dev

- [Valibot v1.5: Faster schema construction, Unicode code points, and stricter validation](https://daily.dev/posts/valibot-v1-5-faster-schema-construction-unicode-code-points-and-stricter-validation-fcqzm9kyo) · Valibot: The modular and type safe schema library · 5 upvotes · 1 comments
- [Transformations that know their context](https://daily.dev/posts/transformations-that-know-their-context-bmidy29zd) · dltHub · 1 upvotes · 0 comments
- [DumboDB: Announcing Validator Support](https://daily.dev/posts/dumbodb-announcing-validator-support-pxoap3acs) · DoltHub Blog · 12 upvotes · 0 comments
- [Evolutionary Data Through Schemaboi: Achieving Forward, Backwards, and Sideways Compatibility](https://daily.dev/posts/evolutionary-data-through-schemaboi-achieving-forward-backwards-and-sideways-compatibility-vnkox1i6x) · InfoQ · 0 upvotes · 0 comments

---

Tags: [#typescript](https://daily.dev/tags/typescript)

[View this post on daily.dev](https://daily.dev/posts/one-model-many-views-type-safe-transforms-with-valibot-and-doba-jdqcdjqot)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"One Model, Many Views: Type-Safe Transforms with Valibot and doba","url":"https://daily.dev/posts/one-model-many-views-type-safe-transforms-with-valibot-and-doba-jdqcdjqot","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/one-model-many-views-type-safe-transforms-with-valibot-and-doba-jdqcdjqot"},"datePublished":"2026-08-23T12:23:35.370Z","dateModified":"2026-08-23T12:55:18.364Z","description":"A guest post introduces doba, a schema registry library that pairs with Valibot (or any Standard Schema compatible library) to manage type-safe transformations...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/979f239bb1ad0d6b272fb7ec4ad35850?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/979f239bb1ad0d6b272fb7ec4ad35850?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Valibot: The modular and type safe schema library","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Valibot: The modular and type safe schema library","logo":"https://media.daily.dev/image/upload/s--GHNQZY4x--/f_auto,q_auto/v1787487507/logos/valibot?_a=BAMAMicg0","url":"https://daily.dev/sources/valibot"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/one-model-many-views-type-safe-transforms-with-valibot-and-doba-jdqcdjqot","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"typescript","timeRequired":"PT6M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Valibot: The modular and type safe schema library","item":"https://daily.dev/sources/valibot"},{"@type":"ListItem","position":3,"name":"One Model, Many Views: Type-Safe Transforms with Valibot and doba"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/one-model-many-views-type-safe-transforms-with-valibot-and-doba-jdqcdjqot#faq","mainEntity":[{"@type":"Question","name":"How can I automatically chain data transformations between schemas that don't have a direct migration defined in TypeScript?","acceptedAnswer":{"@type":"Answer","text":"A schema registry can walk a graph of defined migrations and chain intermediate ones automatically. For example, if only database-to-frontend and frontend-to-ai migrations are registered, calling a transform from database to ai still works because the registry routes through the frontend schema, without requiring a direct database-to-ai migration to be written. Developers comparing data-mapping approaches can find write-ups like this on daily.dev."}},{"@type":"Question","name":"How do I track why fields were defaulted during a legacy data migration in TypeScript?","acceptedAnswer":{"@type":"Answer","text":"Pass a context object into each migration function that exposes methods like ctx.defaulted() and ctx.warn() to record decisions made during conversion, such as generating a missing id or guessing an email from a name field. These records appear in the transform result's meta.defaults and meta.warnings arrays so the reasoning is preserved instead of disappearing into function bodies. Teams handling messy legacy imports often track patterns like this via daily.dev."}},{"@type":"Question","name":"How can I detect which schema an unknown piece of data matches before transforming it in a TypeScript app?","acceptedAnswer":{"@type":"Answer","text":"Define identify guards per schema using field matchers such as match.field('passwordHash') or match.fields('createdAt', 'settings'), then call identifyAndTransform on the unknown data and a target schema name. Guards run in definition order, detecting the source schema, chaining the migration path, and returning a typed error rather than crashing if nothing matches. daily.dev surfaces practical patterns like this for developers normalizing inconsistent payloads."}}]}
```

