-
Notifications
You must be signed in to change notification settings - Fork 90
Description
tl;dr: the version 6 to 7 migration path is causing me to rethink continued use of runtypes.
I'm a longtime runtypes fan and use the library in many of my projects. Obviously there are other more widely-adopted options, but I've enjoyed using runtypes despite its limitations—e.g., collisions with existing global TypeScript names (Record), incompatibilities even across minor versions that require careful synchronization across dependencies, possibly poor performance compared to alternatives, etc.
I try to keep my dependencies updated, and have spent several days working on migrating to v7. Even with a lot of help from Claude, this has been a frustrating experience, and in many cases I have few ways to determine whether or not the changes were applied properly without a lot of manual review. Which is particularly concerning given the purpose of the library!
Some of the changes seem puzzling to me. For example, the Record -> Object rename. We all have naming preferences, but this just creates a lot of upgrade import fuzz for unclear benefits. And, just like Record, Object also collides with a TypeScript global, meaning it probably can't be safely imported as Object anyway. Introducing the .optional modifier is nice, but why did Partial need to be dropped entirely? Again, this just creates more migration effort, and more potential for mistakes.
I suspect a codemod could have handled these issues, had one been provided. But in other cases the semantics have changed—for example, in the withConstraint method, which creates compilation errors at best and subtle bugs at worst, while also removing the ability to do whole-object validation, which was useful. Types also seem to be propagating through check differently, which is likely an improvement but can cause spurious TypeScript errors.
My understanding from examining a few issues is that these changes were made to support parser semantics. I'm sure that some will find that capability useful. But it seems likely that there were more existing runtypes users who didn't need parser semantics who must now navigate this upgrade just to preserve existing behavior. Or stay on v6 forever—or until they can migrate to a different library, which is what I'm thinking that I should have done. I know that zod is a much larger project, but they seem to be setting a much better example in their v3 to v4 migration, including continuing to export both versions and providing a codemod.
I really do appreciate all the hard work that the maintainers have put into this library. I've found it incredibly helpful over the past five years, and I'm definitely not looking forward to migrating to something else. But that seems like a safer option rather than worrying about the next set of breaking changes. (And I haven't even deployed the v7 upgrade yet, so there may be even more trouble ahead...)