AutoNumber Field
Read-only auto-generated sequence number
The AutoNumber Field component displays auto-generated sequence numbers. This is a read-only field where the value is automatically generated by the backend when records are created.
Basic Usage
Basic Autonumber
Custom Format
Invoice Number Format
Date-Based Format
Date Based Ticket Id
Field Schema
An auto-number field is authored as AutoNumberFieldMetadata (@object-ui/types),
which is the source of truth for the key set: it extends BaseFieldMetadata with the
sequence format and its starting point.
import type { AutoNumberFieldMetadata } from '@object-ui/types';
const invoiceNumber: AutoNumberFieldMetadata = {
type: 'auto_number',
name: 'invoice_number',
label: 'Invoice Number',
help: 'Assigned by the platform when the record is created.',
readonly: true,
format: 'INV-{0000}',
starting_number: 1000,
};The generated value, and the className a host supplies, are not metadata keys —
they are runtime widget props. See Field Widget Props.
Format Templates
Common format patterns:
Simple Sequential
format: '{0000}' // 0001, 0002, 0003...
format: '{00000}' // 00001, 00002, 00003...With Prefix
format: 'ORD-{0000}' // ORD-0001, ORD-0002...
format: 'INV-{00000}' // INV-00001, INV-00002...
format: 'CUST-{000}' // CUST-001, CUST-002...Date-Based
format: '{YYYY}-{0000}' // 2024-0001, 2024-0002...
format: '{YY}{MM}-{000}' // 2403-001, 2403-002...
format: 'ORD-{YYYYMMDD}-{00}' // ORD-20240315-01...Mixed Format
format: 'PO-{YYYY}-{MM}-{0000}' // PO-2024-03-0001
format: '{YY}Q{Q}-{000}' // 24Q1-001, 24Q1-002...Format Placeholders
{0},{00},{000}, etc. - Sequential number with padding{YYYY}- Four-digit year (2024){YY}- Two-digit year (24){MM}- Two-digit month (03){DD}- Two-digit day (15){Q}- Quarter (1-4)
Backend Implementation
AutoNumber values are generated on record creation:
const generateAutoNumber = (format: string, sequence: number) => {
const now = new Date();
return format
.replace('{YYYY}', now.getFullYear().toString())
.replace('{YY}', now.getFullYear().toString().slice(-2))
.replace('{MM}', (now.getMonth() + 1).toString().padStart(2, '0'))
.replace('{DD}', now.getDate().toString().padStart(2, '0'))
.replace('{Q}', Math.ceil((now.getMonth() + 1) / 3).toString())
.replace(/\{0+\}/, (match) => {
const padding = match.length - 2;
return sequence.toString().padStart(padding, '0');
});
};
// Example usage
generateAutoNumber('ORD-{YYYY}-{0000}', 42);
// Returns: "ORD-2024-0042"Sequence Management
Allocating the next number is the backend's job, not the renderer's. ObjectUI
never generates a value: AutoNumberField displays whatever the saved record
already carries, and renders a muted placeholder dash while the field is still
empty. What ObjectUI owns is the metadata the backend reads — where the
sequence starts, and how each value is formatted:
import type { AutoNumberFieldMetadata } from '@object-ui/types';
const orderNumber: AutoNumberFieldMetadata = {
type: 'auto_number',
name: 'order_number',
label: 'Order Number',
format: 'ORD-{YYYY}-{0000}',
starting_number: 1,
};On the backend, keep one counter per object-and-field pair and increment it in
the same transaction that inserts the record, so two concurrent inserts cannot
read the same current value. Partition the counter (per year, per prefix) only
if the format resets — 'ORD-{YYYY}-{0000}' needs one counter per year if the
sequence is meant to restart each January.
Because the number is assigned at insert time, it does not exist while the record is still being drafted: a create form shows the field empty, and the value appears once the saved record comes back.
Use Cases
- Order Management: Order numbers, PO numbers
- Invoicing: Invoice IDs, receipt numbers
- Ticketing: Support ticket IDs, case numbers
- Customer Management: Customer IDs, account numbers
- Inventory: SKU numbers, serial numbers
- Document Management: Document IDs, revision numbers
Best Practices
- Choose appropriate padding: Use enough digits for expected volume
- Include year for long-running systems: Helps with archival and partitioning
- Use meaningful prefixes: Makes numbers self-documenting
- Don't expose internal IDs: Use auto-numbers for user-facing identifiers
- Consider reset policies: Decide if/when sequences reset (yearly, monthly, etc.)