Coding Standards
This guide covers the coding standards and conventions used across the LAMISPlus 3.0 frontend codebase.
TypeScript
We use strict mode. Type everything properly.
// Good
const handleSubmit = (e: React.FormEvent<HTMLFormElement>): void => {
e.preventDefault();
};
// Bad - don't use any
const handleSubmit = (e: any) => {
e.preventDefault();
};
Use unknown instead of any when you don't know the type:
const handleError = (error: unknown): void => {
if (error instanceof Error) {
console.error(error.message);
}
};
Path Aliases
Always use path aliases instead of relative imports:
// Good
import { Button } from '@/components/Button';
// Bad
import { Button } from '../../../components/Button';
Available aliases:
@/*-./src/*@/components/*-./src/components/*@/features/*-./src/features/*@/hooks/*-./src/hooks/*@/config/*-./src/config/*@/utils/*-./src/utils/*@/types/*-./src/types/*
Import Order
// 1. External dependencies
import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';
// 2. Core imports (remote apps only)
import { useAppDispatch } from 'core/hooks';
// 3. Local imports
import { Button } from '@/components/common/Button';
import type { User } from '@/types/common';
// 4. Styles
import './styles.css';
File Naming
| Type | Convention | Example |
|---|---|---|
| Components | PascalCase | DataTable.tsx |
| Hooks | camelCase + use prefix | useAuth.ts |
| Utils | camelCase | errorHandler.ts |
| Services | camelCase + Service | authService.ts |
| Types | PascalCase | User.ts |
| Constants | UPPER_SNAKE_CASE | API_ENDPOINTS |
Component Structure
import React, { useState, useEffect } from 'react';
interface Props {
title: string;
onAction: () => void;
}
const MyComponent: React.FC<Props> = ({ title, onAction }) => {
const [state, setState] = useState('');
useEffect(() => {
// ...
}, []);
const handleClick = () => {
onAction();
};
return (
<div>
<h1>{title}</h1>
<button onClick={handleClick}>Action</button>
</div>
);
};
export default MyComponent;
Barrel Exports
Create an index.ts in each feature folder:
// features/auth/index.ts
export { default as Login } from './pages/Login';
export { default as Register } from './pages/Register';
export * from './types';
export { authService } from './services/authService';
Then import cleanly:
import { Login, authService } from '@/features/auth';
Git Commit Convention
We use Conventional Commits:
<type>(<scope>): <subject>
Types:
feat- New featurefix- Bug fixdocs- Documentationrefactor- Refactoringtest- Testschore- Maintenance
Examples:
feat(auth): add password reset
fix(ehr): resolve patient search bug
docs: update setup instructions
Rules:
- Keep subject under 100 characters
- Use lowercase for type
- No period at end of subject
Branch Naming
feature/descriptionfix/descriptionrefactor/descriptionchore/description
Before You Commit
pnpm lint:fix
pnpm format
pnpm typecheck
pnpm test
All checks must pass before committing.
Best Practices
- Keep remote apps focused on one domain
- Reuse Core components when possible
- Write tests for new features
- Keep commits small and focused
- Always use path aliases
- No
anytypes - Lazy load heavy components
- Never commit
.envfiles or credentials - Validate user input