Attributes

Configure field and model behavior with powerful attributes and validators.

Field Attributes

Field attributes modify individual field behavior, constraints, and mapping.

Attribute Description
@idMarks field as primary key
@autoAuto-increment for integers
@uniqueUnique constraint
@default(value)Default value or function
@updatedAtAuto-update timestamp on modification
@map("name")Map to different column name
@ignoreExclude from generated client
@relation(...)Configure relation behavior
@db.TypeDatabase-specific column type

Basic Usage

Advanced Usage

Model Attributes

Model-level attributes (prefixed with @@) configure table-wide behavior.

Attribute Description
@@map("name")Map to different table name
@@id([fields])Composite primary key
@@unique([fields])Composite unique constraint
@@index([fields])Create database index
@@ignoreExclude model from client
@@schema("name")PostgreSQL schema name

Relation Attributes

Configure how models relate to each other with referential actions.

Parameter Description
fieldsLocal foreign key field(s)
referencesReferenced field(s) on related model
nameRelation name for disambiguation
onDeleteAction when referenced record deleted
onUpdateAction when referenced key updated

Referential Actions

Action Behavior
CascadeDelete/update related records
RestrictPrevent delete/update if references exist
NoActionSimilar to Restrict (database-dependent)
SetNullSet foreign key to NULL
SetDefaultSet foreign key to default value

ID Generation

Prax supports multiple ID generation strategies for different use cases. Choose the right one based on your requirements for uniqueness, sortability, and distribution.

uuid() UUID v4

Universally Unique Identifier - the industry standard for distributed systems. Generates 128-bit identifiers with extremely low collision probability.

Advantages

  • • RFC 4122 standard format
  • • Native PostgreSQL UUID type support
  • • Widely recognized and supported
  • • Cryptographically random (v4)
  • • No central coordination needed

Considerations

  • • 36 characters with dashes
  • • Not sortable by creation time
  • • Random distribution (index fragmentation)
  • • Larger storage than auto-increment
Example Output 550e8400-e29b-41d4-a716-446655440000

cuid() CUID

Collision-resistant Unique Identifier - designed for horizontal scaling and distributed systems. Includes a timestamp component for rough time-ordering.

Advantages

  • • Roughly sortable by creation time
  • • URL-safe characters only
  • • Designed for distributed systems
  • • Shorter than UUID (25 chars)
  • • Includes machine fingerprint

Considerations

  • • Not a standard format
  • • Timestamp is extractable
  • • Consider CUID2 for new projects
Example Output cjld2cjxh0000qzrmn831i7rn

cuid2() CUID2

Next-generation CUID with improved security. More unpredictable and shorter than the original. Recommended for new projects.

Advantages

  • • More secure than CUID
  • • Shorter (24 characters)
  • • Better entropy distribution
  • • No extractable timestamp
  • • URL-safe characters

Considerations

  • • Not sortable by time
  • • Newer, less widespread adoption
Example Output tz4a98xxat96iws9zmbrgj3a

nanoid() NanoID

Compact, URL-friendly unique IDs with customizable length. Perfect for short URLs, invite codes, and user-facing identifiers.

Advantages

  • • URL-safe (A-Za-z0-9_-)
  • • Customizable length
  • • Compact (21 chars default)
  • • Cryptographically secure
  • • Fast generation

Considerations

  • • Not sortable by time
  • • Shorter IDs = higher collision risk
  • • No embedded metadata
Example Output
V1StGXR8_Z5jdHi6B-myT nanoid(8): 5fX8pK2m

ulid() ULID

Universally Unique Lexicographically Sortable Identifier. Encodes creation timestamp, making IDs naturally sortable by time.

Advantages

  • • Lexicographically sortable
  • • Encodes millisecond timestamp
  • • Case-insensitive
  • • Compatible with UUID (128-bit)
  • • Better index performance

Considerations

  • • Timestamp is extractable
  • • 26 characters (longer than CUID2)
  • • Limited entropy in same millisecond
Example Output 01ARZ3NDEKTSV4RRFFQ69G5FAV
01ARZ3NDEKTSV4RRFFQ69G5FAV
└─ timestamp ─┘└── randomness ──┘

Comparison

Type Length Sortable URL-Safe Best For
uuid() 36 No No (dashes) Database PKs, APIs
cuid() 25 Roughly Yes Distributed systems
cuid2() 24 No Yes Security-sensitive apps
nanoid() 21* No Yes Short URLs, invite codes
ulid() 26 Yes Yes Time-series, logs, events

* NanoID length is customizable

String Validators

Validate string field content with built-in rules.

Format Validators

  • @validate.email - Email format
  • @validate.url - URL format
  • @validate.uuid - UUID format
  • @validate.cuid - CUID format
  • @validate.nanoid - NanoID format
  • @validate.ulid - ULID format
  • @validate.ip - IP address (v4 or v6)
  • @validate.ipv4 - IPv4 only
  • @validate.ipv6 - IPv6 only

Content Validators

  • @validate.alpha - Letters only
  • @validate.alphanumeric - Letters and numbers
  • @validate.lowercase - Lowercase only
  • @validate.uppercase - Uppercase only
  • @validate.slug - URL slug format
  • @validate.hex - Hexadecimal string
  • @validate.base64 - Base64 encoded
  • @validate.json - Valid JSON string

Numeric Validators

Constrain numeric field values with range and sign validators.

Validator Description
@validate.min(n)Minimum value (inclusive)
@validate.max(n)Maximum value (inclusive)
@validate.range(min, max)Value between min and max
@validate.positiveGreater than zero
@validate.negativeLess than zero
@validate.nonNegativeZero or greater
@validate.nonPositiveZero or less
@validate.integerMust be whole number
@validate.multipleOf(n)Must be multiple of n
@validate.finiteNot Infinity or NaN

Array Validators

Validate array fields for length and content constraints.

Validator Description
@validate.minItems(n)Minimum array length
@validate.maxItems(n)Maximum array length
@validate.items(min, max)Array length range
@validate.uniqueAll items must be unique
@validate.nonEmptyAt least one item required

Date Validators

Validate datetime fields with temporal constraints.

Validator Description
@validate.pastMust be in the past
@validate.futureMust be in the future
@validate.pastOrPresentNot in the future
@validate.futureOrPresentNot in the past
@validate.after("date")After specific date
@validate.before("date")Before specific date

General Validators

Universal validators that work across different field types.

Validator Description
@validate.requiredField must have a value (even if optional type)
@validate.notEmptyNon-empty string/array
@validate.oneOf(...)Value must be one of specified options
@validate.custom("fn")Custom validation function

Default Value Functions

Auto-generate values for fields using built-in functions.

Function Description
now()Current timestamp
uuid()Random UUID v4
cuid()Collision-resistant unique ID
cuid2()Next-gen CUID (more secure)
nanoid()URL-friendly unique ID
nanoid(n)NanoID with custom length
ulid()Sortable unique ID
autoincrement()Auto-incrementing integer
dbgenerated("expr")Database-generated expression

Database-Specific Types

Map fields to native database column types with @db.* attributes.

PostgreSQL Types

  • @db.Text - Unlimited text
  • @db.JsonB - Binary JSON (indexable)
  • @db.Uuid - Native UUID
  • @db.Xml - XML type
  • @db.Inet - IP address
  • @db.Cidr - Network address
  • @db.MacAddr - MAC address
  • @db.Decimal(p, s) - Precise decimal

MySQL Types

  • @db.TinyText - 255 bytes
  • @db.MediumText - 16 MB
  • @db.LongText - 4 GB
  • @db.TinyInt - Tiny integer
  • @db.MediumInt - Medium integer
  • @db.Year - Year type
  • @db.VarChar(n) - Variable char
  • @db.Charset("utf8mb4") - Charset

Documentation & Metadata

Add metadata and documentation to fields using doc comments.

Visibility

  • @hidden - Exclude from public API
  • @internal - Admin-only access
  • @sensitive - Mask in logs
  • @readonly - Not settable via API
  • @writeonly - Not in responses

Documentation

  • @deprecated - Mark as deprecated
  • @since version - Version introduced
  • @example value - Example value
  • @label text - Display label
  • @placeholder text - Input placeholder

Index Types

Create different types of database indexes for query optimization.

@for (row of indexTypesTable; track row.type) { }
Type Use Case PG MySQL SQLite
{{ row.type }} {{ row.use }} {{ row.pg }} {{ row.mysql }} {{ row.sqlite }}

* Requires pgvector extension

Vector Indexes

Vector indexes enable fast approximate nearest neighbor (ANN) search for AI/ML embeddings. Requires the pgvector PostgreSQL extension.

Distance Operations

@for (row of vectorOpsTable; track row.op) { }
Operation Description Best For
{{ row.op }} {{ row.desc }} {{ row.best }}

💡 Choosing an Index Type

  • HNSW: Best recall, faster queries, slower builds - recommended for most cases
  • IVFFlat: Faster builds, slightly lower recall - good for large datasets (1M+ vectors)