Mixins

Mixins provide field reuse for .cstack models. They are a schema authoring convenience, not a runtime inheritance feature.

Syntax

Declare a top-level mixin block and apply it inside a model with @use(...).
mixin AuditFields {
  createdAt DateTime @default(dbgenerated())
  updatedAt DateTime @default(dbgenerated())
}

model Post {
  @use(AuditFields)

  id Int @id
  title String
}
You can apply more than one mixin:
mixin AuditFields {
  createdAt DateTime @default(dbgenerated())
  updatedAt DateTime @default(dbgenerated())
}

mixin SoftDelete {
  deletedAt DateTime?
}

model Post {
  @use(AuditFields, SoftDelete)

  id Int @id
  title String
}

Semantics

CrateStack expands mixin fields into the model before semantic validation and before Rust, Dart, and TypeScript code generation. That means:
  • generated clients and generated server code see normal model fields after expansion
  • validator rules run on the expanded model field set
  • mixins do not create a separate generated runtime type

Rules

Current mixin support is intentionally narrow:
  • mixins are only supported as top-level declarations
  • @use(...) is only supported inside model blocks
  • mixins contain fields, not model-level attributes
  • mixins must not declare @id
  • model-local fields win on name conflicts with mixin fields
Example of local override:
mixin Timestamps {
  createdAt DateTime
}

model Post {
  @use(Timestamps)

  id Int @id
  createdAt DateTime?
}
In that example, the model’s createdAt DateTime? definition wins.

Non-goals

Mixins are not:
  • polymorphism
  • inheritance between generated model types
  • a way to share model @@... attributes
  • a way to declare shared primary keys