# How DrawDB Handles Custom Data Types and Enumerations: A Complete Technical Guide

> Learn how DrawDB handles custom data types and enumerations as first-class schema elements using a centralized registry and React hooks for seamless integration and management.

- Repository: [drawDB/drawdb](https://github.com/drawdb-io/drawdb)
- Tags: deep-dive
- Published: 2026-08-14

---

**DrawDB treats custom data types and enumerations as first-class schema elements that can be defined, edited, and rendered just like built-in column types through a centralized registry system and React hooks.**

DrawDB provides a flexible type system that allows users to extend beyond built-in column types by defining custom data types and enumerations directly within the diagram editor. According to the drawdb-io/drawdb source code, these custom definitions are managed through a combination of centralized registries, React hooks for state management, and serialization utilities that ensure round-trip safety. Understanding how DrawDB handles custom data types and enumerations reveals a well-architected system designed for extensibility and portability across different SQL dialects.

## The Architecture of Custom Type Management

DrawDB implements custom data types through a layered architecture that separates the type registry from state management and persistence logic.

### Central Registry in datatypes.js

The foundation of the type system resides in **[`src/data/datatypes.js`](https://github.com/drawdb-io/drawdb/blob/main/src/data/datatypes.js)**, which exports an array of objects describing every supported column type. Each object contains properties such as `name`, `label`, `icon`, and `default` options. Custom types are dynamically added to this array at runtime, maintaining the exact same shape as built-in types to ensure UI consistency.

### React Hooks for Dynamic Type Handling

State management for custom types is handled by **[`src/hooks/useTypes.js`](https://github.com/drawdb-io/drawdb/blob/main/src/hooks/useTypes.js)**. This hook reads the central registry, merges any user-defined types stored in the diagram's metadata, and exposes immutable actions including **`addCustomType`**, **`removeCustomType`**, and **`updateCustomType`**. By using this hook, React components re-render only when the type list changes, ensuring optimal performance while keeping the UI synchronized with persisted diagram data.

### Enumeration State Management

Enumerations receive specialized treatment through **[`src/hooks/useEnums.js`](https://github.com/drawdb-io/drawdb/blob/main/src/hooks/useEnums.js)**, which treats enums as a special category of custom type named `enum`. The hook provides **`createEnum`** for initialization, plus **`addEnumValue`**, **`updateEnumValue`**, and **`deleteEnum`** for manipulating the list of possible values. Enumeration definitions are serialized under a dedicated `enums` field in the diagram JSON, separate from standard custom types.

## Defining Custom Data Types Programmatically

Adding a new custom type requires calling the `addCustomType` function exposed by the `useTypes` hook. The new type immediately appears in the column-type selector alongside native types.

```javascript
import { useTypes } from '@/hooks/useTypes';

// Inside a component or utility
const { addCustomType } = useTypes();

addCustomType({
  name: 'uuid',
  label: 'UUID',
  icon: '🔑',
  default: () => 'uuid_generate_v4()',
});

```

This pattern demonstrates the **uniform data shape** principle: custom types share the same object schema as built-in types, which simplifies both UI rendering in the column selector and export logic across SQL dialects.

## Managing Enumerations in DrawDB

Enumerations are created and populated through the `useEnums` hook, which manages the lifecycle of enum definitions from creation to value assignment.

```javascript
import { useEnums } from '@/hooks/useEnums';

const { createEnum, addEnumValue, updateEnumValue, deleteEnum } = useEnums();

// Create an enum called "status"
const enumId = createEnum('status');

// Add possible values
addEnumValue(enumId, 'PENDING');
addEnumValue(enumId, 'ACTIVE');
addEnumValue(enumId, 'ARCHIVED');

```

Once defined, the enum appears in the column-type dropdown. When selected for a column, the enum editor component—wired through `useEnums`—allows users to edit the list of possible values via the dedicated UI.

## Persistence and SQL Export

Custom types and enums survive the full save-reload-export cycle through specialized serialization and export utilities.

### Serializing Custom Definitions

**[`src/utils/customTypes.js`](https://github.com/drawdb-io/drawdb/blob/main/src/utils/customTypes.js)** contains helpers that convert custom type definitions (including enums) to and from the diagram JSON format. These functions ensure **round-trip safety**: when a diagram is saved locally or to a backend, the `customTypes` and `enums` fields are included in the payload. Re-opening the diagram restores the exact same definitions without information loss.

### Exporting to PostgreSQL

When exporting diagrams to PostgreSQL, **[`src/utils/exportSQL/postgres.js`](https://github.com/drawdb-io/drawdb/blob/main/src/utils/exportSQL/postgres.js)** generates appropriate `CREATE TYPE` statements for enumerations using the serialization helpers.

```javascript
import { exportPostgres } from '@/utils/exportSQL/postgres';

const sql = exportPostgres(diagram);
// `sql` contains statements such as:
// CREATE TYPE "status" AS ENUM ('PENDING','ACTIVE','ARCHIVED');

```

The export logic accesses the enum definitions stored in the diagram metadata and renders them according to PostgreSQL syntax, while other SQL dialects receive appropriate equivalent statements based on their specific type systems.

## Summary

- **Centralized registry**: [`src/data/datatypes.js`](https://github.com/drawdb-io/drawdb/blob/main/src/data/datatypes.js) maintains the master list of built-in and custom types with a uniform object schema.
- **Hooks-driven state**: [`useTypes.js`](https://github.com/drawdb-io/drawdb/blob/main/useTypes.js) and [`useEnums.js`](https://github.com/drawdb-io/drawdb/blob/main/useEnums.js) expose immutable actions that keep React components synchronized with type definitions.
- **First-class enumerations**: Enums are managed as a distinct category with dedicated creation and value-manipulation functions.
- **Round-trip persistence**: [`src/utils/customTypes.js`](https://github.com/drawdb-io/drawdb/blob/main/src/utils/customTypes.js) ensures custom types survive save, reload, and export operations without data loss.
- **Dialect-aware export**: SQL generators in `src/utils/exportSQL/` convert enums and custom types to appropriate statements for PostgreSQL, MySQL, SQLite, and other supported databases.

## Frequently Asked Questions

### How does DrawDB store custom type definitions?

DrawDB stores custom type definitions within the diagram's JSON payload under the `customTypes` field, while enumerations are stored separately under the `enums` field. The serialization helpers in [`src/utils/customTypes.js`](https://github.com/drawdb-io/drawdb/blob/main/src/utils/customTypes.js) handle conversion between the runtime registry format and the persisted JSON structure, ensuring that all type metadata—including icons, labels, and default values—is preserved when saving to local storage or remote backends.

### Can enumerations be exported to all supported SQL dialects?

Yes, enumerations can be exported to all supported SQL dialects, though the generated syntax varies by database. PostgreSQL exports use `CREATE TYPE ... AS ENUM (...)` statements as implemented in [`src/utils/exportSQL/postgres.js`](https://github.com/drawdb-io/drawdb/blob/main/src/utils/exportSQL/postgres.js), while MySQL and SQLite export logic may map enums to constraint checks or native enum types depending on the target dialect's capabilities. Each exporter in the `src/utils/exportSQL/` directory contains dialect-specific logic for rendering custom types appropriately.

### What happens to custom types when a diagram is shared or reloaded?

Custom types and enumerations remain intact during sharing and reloading operations because they are serialized as part of the diagram's metadata. When a diagram JSON is loaded, the `useTypes` and `useEnums` hooks automatically merge the persisted definitions back into the working registry. This **round-trip safety** guarantees that collaborators opening a shared diagram see the exact same custom type definitions and enum values as the original creator.

### How do I programmatically add a custom type in DrawDB?

Programmatically adding a custom type requires importing and calling `addCustomType` from the `useTypes` hook, passing an object with `name`, `label`, `icon`, and `default` properties. The type immediately becomes available in the column-type selector throughout the application, and the change persists when the diagram is saved because the hook automatically updates the diagram's metadata store.