Skip to content

Add VineJS validation (via drizzle-vine package)#5466

Open
ChronicStone wants to merge 11 commits intodrizzle-team:mainfrom
ChronicStone:features/drizzle-vinejs
Open

Add VineJS validation (via drizzle-vine package)#5466
ChronicStone wants to merge 11 commits intodrizzle-team:mainfrom
ChronicStone:features/drizzle-vinejs

Conversation

@ChronicStone
Copy link

@ChronicStone ChronicStone commented Mar 10, 2026

This PR adds a new package: drizzle-vine. It works just like the other validator packages (drizzle-zod, drizzle-valibot, etc.) but targets VineJS.

The main motivation is AdonisJS. Adonis ships with VineJS as its built-in validator, so anyone building an Adonis app with Drizzle today has to either maintain two separate schema definitions or bolt on a different validation library. This package closes that gap and lets you derive your VineJS schemas directly from your Drizzle tables.

Supported dialects: PostgreSQL, MySQL, SQLite, SingleStore.

Example

import { pgEnum, pgTable, serial, text, varchar } from 'drizzle-orm/pg-core';
import { createInsertSchema, createSelectSchema, createUpdateSchema } from 'drizzle-vine';
import vine from '@vinejs/vine';

const roleEnum = pgEnum('role', ['admin', 'editor', 'viewer']);

const users = pgTable('users', {
	id: serial().primaryKey(),
	name: text().notNull(),
	email: varchar({ length: 255 }).notNull(),
	role: roleEnum().notNull(),
	bio: text(),
});

// Schema for inserting a user — can be used to validate API requests
const insertUserSchema = createInsertSchema(users);

// Schema for updating a user
const updateUserSchema = createUpdateSchema(users);

// Schema for selecting a user — can be used to validate API responses
const selectUserSchema = createSelectSchema(users);

// Refining fields — useful when you need extra constraints on top of what Drizzle knows
const insertUserSchema = createInsertSchema(users, {
	name: (schema) => schema.minLength(2).maxLength(100),
	email: (schema) => schema.email(),
});

// Overriding a field entirely
const insertUserSchema = createInsertSchema(users, {
	role: vine.enum(['admin', 'editor']),
});

// Compile and validate
const validator = vine.compile(insertUserSchema);
const output = await validator.validate({
	name: 'Alice',
	email: 'alice@example.com',
	role: 'admin',
});

Known limitations

VineJS does not have native support for bigint or Node.js Buffer values. Columns of those types fall back to vine.any() at both the runtime and type level. If you need validation on those columns you can supply a custom schema through the refine option.

A note on TypeScript performance

VineJS's type system requires four explicit type parameters on VineObject<Properties, Input, Output, CamelCaseOutput> compared to one for Zod, and its modifier chain adds overhead per column.

As a result drizzle-vine currently sits around 600k type instantiations versus ~80k for drizzle-zod on a typical schema. That gap is mostly structural and inherent to how VineJS exposes its types rather than something fixable with straightforward tuning. The implementation already avoids the most expensive patterns (no per-column modifier chain inference, single-pass output type computation via arithmetic unions), so the overhead that remains is about as low as I could get it for now.

There is probably still room for improvement as VineJS's type architecture evolves, but it works fine in practice and compile times stay reasonable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant