Managing file size for better code organization
File line count measures the total number of lines in a source file, including code, comments, blank lines, and import statements. While not as precise as logical LOC, it provides a quick indicator of file size and complexity.
Large files are harder to navigate, understand, and maintain. They often indicate poor separation of concerns and can slow down development tools and code reviews.
The metric counts every line in the file from the first line to the last line, including:
A focused utility file with a single purpose.
// utils/date-formatter.ts
/**
* Date formatting utilities
*/
import { format, parseISO } from "date-fns";
/**
* Format a date string to a readable format
*/
export function formatDate(dateString: string): string {
try {
const date = parseISO(dateString);
return format(date, "MMM d, yyyy");
} catch {
return "Invalid date";
}
}
/**
* Format a date with time
*/
export function formatDateTime(dateString: string): string {
try {
const date = parseISO(dateString);
return format(date, "MMM d, yyyy 'at' h:mm a");
} catch {
return "Invalid date";
}
}
/**
* Get relative time (e.g., "2 hours ago")
*/
export function getRelativeTime(dateString: string): string {
// Implementation
return "...";
}
// Total: ~45 lines
// Well-organized, single purpose, easy to findA "god file" that tries to do everything related to users.
// user-service.ts
// 50 lines of imports
import { db } from "./db";
import { email } from "./email";
import { auth } from "./auth";
// ... 40+ more imports
// 100 lines of types
interface User { /* ... */ }
interface UserProfile { /* ... */ }
interface UserSettings { /* ... */ }
// ... 20+ more types
// 150 lines of validation
function validateEmail(email: string) { /* ... */ }
function validatePassword(password: string) { /* ... */ }
// ... 30+ validation functions
// 200 lines of user CRUD
export async function createUser() { /* ... */ }
export async function getUser() { /* ... */ }
export async function updateUser() { /* ... */ }
export async function deleteUser() { /* ... */ }
// ... 15+ CRUD functions
// 200 lines of authentication
export async function login() { /* ... */ }
export async function logout() { /* ... */ }
export async function resetPassword() { /* ... */ }
// ... 20+ auth functions
// 150 lines of profile management
export async function updateProfile() { /* ... */ }
export async function uploadAvatar() { /* ... */ }
// ... 15+ profile functions
// 200 lines of user settings
export async function getSettings() { /* ... */ }
export async function updateSettings() { /* ... */ }
// ... 20+ settings functions
// 100 lines of analytics
export async function trackLogin() { /* ... */ }
export async function getUserStats() { /* ... */ }
// ... 10+ analytics functions
// 50 lines of helpers
function hashPassword() { /* ... */ }
function generateToken() { /* ... */ }
// ... 10+ helpers
// Total: 1200+ lines
// Impossible to navigate, multiple concerns, hard to maintainBreaking the large file into focused modules.
// users/ // types/ // user.ts (~50 lines - type definitions) // user-profile.ts (~40 lines) // user-settings.ts (~40 lines) // // validation/ // email-validator.ts (~30 lines) // password-validator.ts (~50 lines) // user-validator.ts (~80 lines) // // repositories/ // user-repository.ts (~200 lines - CRUD operations) // // services/ // auth-service.ts (~250 lines - authentication) // profile-service.ts (~150 lines - profile management) // settings-service.ts (~180 lines - user settings) // analytics-service.ts (~120 lines - tracking) // // utils/ // password-utils.ts (~60 lines) // token-utils.ts (~70 lines) // // index.ts (~30 lines - public exports) // Each file is focused and manageable!
| Sensitivity Level | Max Lines | Use Case |
|---|---|---|
| High | ≤ 300 | Well-organized codebases |
| Medium | ≤ 500 | Most applications |
| Low | ≤ 800 | Legacy code being improved |
Separate code by business domain or feature.
Example:
user-service.ts → user-auth.ts,user-profile.ts,user-settings.tsMove type definitions to separate types.ts files. This is especially helpful in TypeScript projects.
Move configuration and constants to separate constants.ts orconfig.ts files.
Create index.ts files to re-export from a directory, keeping the public API clean.
// users/index.ts
export * from "./user-auth";
export * from "./user-profile";
export * from "./user-settings";
export type { User, UserProfile } from "./types";
// Consumers import from the directory
import { login, updateProfile } from "./users";Each file should have one clear purpose. If you struggle to name a file concisely, it's probably doing too much.