Skip to main content
doc0blade47/drizzle-ormdocumentation home
Sign in

Custom Column Types

Last updated Oct 12, 2026100% grounded

Overview

Introduction

Sometimes your application needs to store data types that are specific to your business logic or not natively supported out of the box. Custom Column Types let you define your own data types and map them directly to database columns. This feature bridges the gap between your application's TypeScript data models and how values are represented, serialized, and retrieved from your database.

By defining a custom column type, you can control the exact database data type string used for migrations, automatically serialize JavaScript or TypeScript objects into driver-accepted parameters before writing to the database, and deserialize incoming database values back into your desired runtime format.


Defining a Custom Type

To create a custom column type, use the customType function. You provide configuration parameters that dictate how the column behaves during database interactions and type-checking.

import { customType } from 'drizzle-orm/pg-core';
 
const customVarchar = customType<{
  data: string;
  driverData: string;
  config: { length: number };
  configRequired: true;
}>({
  dataType(config) {
    return `varchar(${config.length})`;
  },
  toDriver(value) {
    return value;
  },
  fromDriver(value) {
    return value;
  },
});

Configuration Options

When defining a custom type, you configure its parameters using standard type definitions:

OptionDescriptionDefault
dataThe TypeScript type used in your application after selecting or when inserting.unknown
driverDataThe type accepted by the database driver for this database type.unknown
configThe configuration object type passed into dataType generation.Record<string, any>
configRequiredWhether the configuration argument is mandatory when defining the column.false
notNullMarks the custom data type as non-nullable by default.false
defaultMarks the custom data type as having a default value by default.false

Mapping Values Between Application and Driver

Custom types allow you to transform data seamlessly as it travels between your TypeScript code and the database driver using two main mapping functions:

  1. toDriver: Converts your application data model into a format accepted by the database driver right before an insert or update query executes (for example, serializing an object into a JSON string).
  2. fromDriver: Converts raw database values coming from the driver back into your application's preferred runtime data type (for example, parsing a date string into a real JavaScript Date object).

Tip

The toDriver function can return either the expected driver parameter type or a custom raw SQL expression object when advanced query manipulation is needed.


Working with Optional and Required Configurations

You can configure your custom types to accept optional settings or enforce required parameters depending on your database schema needs.

// Example with an optional configuration
const flexibleString = customType<{
  data: string;
  driverData: string;
  config: { length: number };
}>({
  dataType(config) {
    return config ? `varchar(${config.length})` : 'text';
  },
  toDriver(value) {
    return value;
  },
  fromDriver(value) {
    return value;
  },
});
 
// Usage with config
const col1 = flexibleString('col1', { length: 50 });
// Usage without config (falls back to text)
const col2 = flexibleString('col2');

Warning

If you set configRequired: true in your custom type definition, omitting the configuration object when declaring the column will trigger a TypeScript compilation error.

Was this page helpful?