PocketBase Collection Fields Schema – Complete Reference

Here’s the comprehensive field structure documentation for creating PocketBase collections.


Common Field Properties (All Field Types)

All field types share these base properties:

{
name: string; // [REQUIRED] Unique field name
type: string; // [REQUIRED] Field type (see types below)
id?: string; // Auto-generated stable identifier
system?: boolean; // Prevents renaming/deletion when true
hidden?: boolean; // Hides from API response
required?: boolean; // Field must have a value
presentable?: boolean; // Show in relation preview labels
primaryKey?: boolean; // Only one per collection
}

All Field Types & Their Specific Properties

1. TextField (text)

Stores string values. Zero default: "" (empty string)

{
name: "title",
type: "text",
required: true,
hidden: false,
presentable: false,
system: false,

// Text-specific options
min?: number; // Minimum characters (default: 0)
max?: number; // Maximum characters (default: 5000)
pattern?: string; // Regex pattern validation (optional)
autogeneratePattern?: string; // Pattern to auto-generate on create, example:
"abc-[0-9a-zA-Z]{5}"
}

2. BoolField (bool)

Stores true/false values. Zero default: false

{
name: "isActive",
type: "bool",
required: false,
hidden: false,
presentable: false,
system: false

// No additional options
}

3. NumberField (number)

Stores numeric/float64 values. Zero default: 0

{
name: "price",
type: "number",
required: true,
hidden: false,
presentable: false,
system: false,

// Number-specific options
min?: number; // Minimum value (optional)
max?: number; // Maximum value (optional)
onlyInt?: boolean; // Allow only integers (default: false)
noDecimal?: boolean; // No decimal places (default: false)
}

4. EmailField (email)

Stores email addresses with validation. Zero default: ""

{
name: "email",
type: "email",
required: true,
hidden: false,
presentable: false,
system: false,

// Email-specific options
exceptDomains?: string[]; // Blocked domains (e.g., ["gmail.com"])
onlyDomains?: string[]; // Allowed domains only
}

5. URLField (url)

Stores URL strings with validation. Zero default: ""

{
name: "website",
type: "url",
required: false,
hidden: false,
presentable: false,
system: false

// No additional options
}

6. EditorField (editor)

Stores HTML formatted text. Zero default: ""

{
name: "description",
type: "editor",
required: false,
hidden: false,
presentable: false,
system: false

// No additional options
}

7. DateField (date)

Stores date values (YYYY-MM-DD format). Zero default: ""

{
name: "birthDate",
type: "date",
required: false,
hidden: false,
presentable: false,
system: false

// No additional options
}

8. AutodateField (autodate)

Auto-sets on create/update. Zero default: ""

{
name: "created",
type: "autodate",
required: false,
hidden: false,
presentable: false,
system: false,

// Autodate-specific options
onCreate?: boolean; // Auto-set on record create (default: true)
onUpdate?: boolean; // Auto-set on record update (default: true)
}

9. SelectField (select)

Stores single/multiple predefined values. Zero default: "" or []

{
name: "status",
type: "select",
required: false,
hidden: false,
presentable: false,
system: false,

// Select-specific options
values: string[]; // [REQUIRED] Array of options ["active", "inactive"]
maxSelect?: number; // 1 for single, 2+ for multiple (default: 1)
}

10. FileField (file)

Manages record files. Zero default: [] (empty array)

{
name: "avatar",
type: "file",
required: false,
hidden: false,
presentable: false,
system: false,

// File-specific options
maxSelect?: number; // Max files allowed (1+ required, default: 1)
maxSize?: number; // Max file size in bytes (0 = unlimited)
mimeTypes?: string[]; // Allowed MIME types
thumbs?: string[]; // Thumbnail sizes (e.g., ["100x100", "250x250"])
protected?: boolean; // Requires auth to access (default: false)
}

Example with image restrictions:

{
name: "photos",
type: "file",
maxSelect: 5,
maxSize: 5242880, // 5MB in bytes
mimeTypes: [
"image/jpeg",
"image/png",
"image/svg+xml",
"image/gif",
"image/webp"
]
}

11. RelationField (relation)

References records from other collections. Zero default: "" or []

{
name: "author",
type: "relation",
required: false,
hidden: false,
presentable: false,
system: false,

// Relation-specific options
collectionId: string; // [REQUIRED] Target collection ID
collectionName?: string; // Target collection name (convenience)
maxSelect?: number; // 1 for single, 2+ for multiple (default: 1)
cascadeDelete?: boolean; // Delete when related record deleted (default: false)
onDelete?: string; // Action on related delete: "cascade", "restrict", "set_null" (default: "restrict")
}

12. JSONField (json)

Stores any serialized JSON. Zero default: null (unlike others, can be nullable)

{
name: "metadata",
type: "json",
required: false,
hidden: false,
presentable: false,
system: false

// No additional options
// Can store: objects, arrays, strings, numbers, booleans
}

13. GeoPointField (geopoint)

Stores geographic coordinates. Zero default: {lon: 0, lat: 0}

{
name: "location",
type: "geopoint",
required: false,
hidden: false,
presentable: false,
system: false

// No additional options
// Value structure: { lon: number, lat: number }
}

System Fields (Auto-Generated in Auth Collections)

When creating an auth collection, these fields are automatically included:

{
name: "id",
type: "text",
system: true,
primaryKey: true,
autogeneratePattern: "[a-z0-9]{15}"
}

{
name: "password",
type: "password",
system: true,
hidden: true,
required: true,
min: 8
}

{
name: "tokenKey",
type: "text",
system: true,
hidden: true,
autogeneratePattern: "[a-zA-Z0-9]{50}"
}

{
name: "email",
type: "email",
system: true,
required: true,
presentable: false
}

{
name: "emailVisibility",
type: "bool",
system: true
}

{
name: "verified",
type: "bool",
system: true
}

Complete Collection Creation Example

Base Collection

await pb.collections.create({
name: "products",
type: "base",

// API Rules
listRule: null, // Anyone can list
viewRule: null, // Anyone can view
createRule: '@request.auth.id != ""', // Auth users only
updateRule: '@request.auth.id = owner', // Own records only
deleteRule: '@request.auth.id = owner', // Own records only

fields: [
{
name: "title",
type: "text",
required: true,
presentable: true,
max: 255
},
{
name: "description",
type: "editor",
required: false
},
{
name: "price",
type: "number",
required: true,
min: 0,
max: 999999
},
{
name: "stock",
type: "number",
required: true,
onlyInt: true
},
{
name: "status",
type: "select",
required: true,
values: ["draft", "published", "archived"],
maxSelect: 1
},
{
name: "category",
type: "relation",
required: false,
collectionId: "categories_collection_id",
maxSelect: 3,
cascadeDelete: false
},
{
name: "images",
type: "file",
required: false,
maxSelect: 5,
maxSize: 5242880,
mimeTypes: ["image/jpeg", "image/png", "image/webp"],
thumbs: ["100x100", "300x300"]
},
{
name: "location",
type: "geopoint",
required: false
},
{
name: "metadata",
type: "json",
required: false
},
{
name: "owner",
type: "relation",
required: true,
collectionId: "users_collection_id",
maxSelect: 1,
cascadeDelete: true
},
{
name: "created",
type: "autodate",
onCreate: true,
onUpdate: false
},
{
name: "updated",
type: "autodate",
onCreate: true,
onUpdate: true
}
],

indexes: [
"CREATE UNIQUE INDEX idx_title ON products (title)",
"CREATE INDEX idx_status ON products (status)",
"CREATE INDEX idx_owner ON products (owner)"
]
});

Auth Collection

await pb.collections.create({
name: "users",
type: "auth",

// API Rules
createRule: "", // Anyone can register
viewRule: '@request.auth.id = id',
updateRule: '@request.auth.id = id',
deleteRule: '@request.auth.id = id',

// Auth-specific options
authRule: '@request.auth.id != ""', // Verified users only
manageRule: null, // Allow manage rule

passwordAuth: {
enabled: true,
identityFields: ["email"]
},

oauth2: {
enabled: false,
providers: []
},

mfa: {
enabled: false,
duration: 1800,
rule: ""
},

otp: {
enabled: false,
duration: 180,
length: 8
},

authAlert: {
enabled: true,
emailTemplate: {
subject: "Login from a new location",
body: "..."
}
},

fields: [
{
name: "name",
type: "text",
required: false,
max: 255
},
{
name: "avatar",
type: "file",
required: false,
maxSelect: 1,
mimeTypes: ["image/jpeg", "image/png", "image/gif", "image/webp"],
thumbs: ["100x100"]
},
{
name: "role",
type: "select",
required: false,
values: ["admin", "user", "moderator"],
maxSelect: 1
}
],

tokenConfig: {
authToken: { duration: 604800 }, // 7 days
passwordResetToken: { duration: 1800 }, // 30 minutes
emailChangeToken: { duration: 1800 }, // 30 minutes
verificationToken: { duration: 259200 } // 3 days
}
});

View Collection

await pb.collections.create({
name: "product_stats",
type: "view",

// Query that populates the view
viewQuery: `
SELECT
products.id,
products.title,
products.price,
COUNT(orders.id) as totalOrders,
SUM(orders.quantity) as totalSold
FROM products
LEFT JOIN orders ON orders.product_id = products.id
GROUP BY products.id
`,

listRule: null,
viewRule: null,

fields: [
{
name: "id",
type: "text",
system: true,
primaryKey: true
},
{
name: "title",
type: "text"
},
{
name: "price",
type: "number"
},
{
name: "totalOrders",
type: "number"
},
{
name: "totalSold",
type: "number"
}
]
});

Important Notes

Non-Nullable Fields

All fields except JSONField are non-nullable and use zero-defaults when missing:

  • Text:ย ""
  • Number:ย 0
  • Bool:ย false
  • Select (single):ย ""
  • Select (multiple):ย []
  • File:ย []
  • Relation:ย ""ย orย []
  • GeoPoint:ย {lon: 0, lat: 0}

API Rules Context Variables

  • @request.auth.idย – Current user ID
  • @request.auth.emailย – Current user email
  • Nested relations:ย author.id,ย category.name
  • Comparison:ย ==,ย !=,ย <,ย >,ย <=,ย >=,ย ~
  • Logical:ย &&,ย ||,ย ()

Best Practices

  1. Always setย presentable: trueย for relation fields you want to display in previews
  2. Useย cascadeDelete: trueย carefully – only for owned/dependent records
  3. Set appropriateย maxย sizes for text to prevent bloating
  4. Useย patternย regex validation for standardized fields (phone, ID numbers)
  5. Mark system fields withย system: trueย to prevent accidental removal
  6. Useย hidden: trueย for internal fields (password is auto-hidden in auth collections)
  7. Combineย required: trueย withย createRuleย for data integrity

This comprehensive reference covers all field types and properties you’ll need for your PocketBase projects, whether building pesantren management systems, e-commerce, or other business applications with Supabase/PostgreSQL backends.


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *