Best Practices
Best Practices
Follow these best practices to build maintainable, performant applications with @wayvo-ai/core.
Code Organization
File Structure
src/app/(secure)/module/feature/
├── page.tsx
├── page-content.tsx
├── hooks/
│ ├── use-store.ts
│ ├── use-table-columns.tsx
│ └── smart-search-columns.ts
└── components/
└── edit-form.tsx
Naming Conventions
- Store aliases:
{module}-list,{module}-edit,{module}-dialog,{module}-combobox - Hooks:
use{Entity}Store,use{Entity}TableColumns,use{Entity}SmartSearchColumns - Components: PascalCase (e.g.,
EntityForm,EntityDialog)
Performance Optimization
Use select for Lookup Stores
Only fetch needed fields:
const store = useStore<Customer>({
datasourceId: 'Customers',
alias: 'customer-options',
select: ['customerId', 'customerName'], // Only these fields
limit: 1000,
});
Use filterLocally for Small Datasets
When the complete dataset is loaded:
const store = useStore<Status>({
datasourceId: 'StatusLookup',
alias: 'status-combobox',
limit: 100, // Load all
autoQuery: true,
filterLocally: true, // Filter client-side
});
Appropriate limit Values
- List pages:
20(standard pagination) - Lookup stores:
1000(for combobox options) - Detail pages:
1(single record)
Type Safety
Always Define TypeScript Types
// src/lib/common/ds/types/module/Entity.ts
export interface Entity {
id: string;
name: string;
description?: string;
createdAt: string;
}
Use Type Inference
// TypeScript infers Entity from DataSource
const store = useStore<Entity>({
datasourceId: 'Entity',
// ...
});
// row is typed as Entity
const row = useCurrentRowSync(store);
Store Configuration
Share Stores via Same Key
// Both return the SAME store instance
const tableStore = useEntityStore();
const formStore = useEntityStore(); // Same instance!
Use Descriptive Aliases
// ✅ Good
alias: 'entity-list'
alias: 'entity-edit'
alias: 'entity-dialog'
// ❌ Bad
alias: 'list'
alias: 'edit'
Date Handling
Use UTC Methods
// ❌ Wrong - timezone shifts the date
const formatDate = (date: string) => format(new Date(date), 'MMM yyyy');
// ✅ Correct - use UTC methods
const formatDate = (date: string) => {
const d = new Date(date);
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
return `${months[d.getUTCMonth()]} ${d.getUTCFullYear()}`;
};
Scrollbar Styling
All scrollable regions should include:
className="overflow-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-muted-foreground/20 hover:scrollbar-thumb-muted-foreground/40"
Form Layout
Grid Alignment
Always use items-start for side-by-side fields:
// ✅ Correct
<div className="grid grid-cols-2 items-start gap-4">
<TextInput label="Field 1" helpText="Has help text" />
<ComboboxInput label="Field 2" />
</div>
Next Steps
- Performance - Detailed performance tips
- Code Organization - File structure patterns