Line ending handling across platforms — CRLF vs LF detection, normalization, and git config
Scanned 9/3/2026
Install to Claude Code
npx -y skills add fabioc-aloha/Alex_Skill_Mall --skill line-ending-parsing --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Line Ending Parsing?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/fabioc-aloha-line-ending-parsing)More formats (shields.io, HTML) on the badges page.
---
name: line-ending-parsing
description: "Line ending handling across platforms — CRLF vs LF detection, normalization, and git config"
lastReviewed: 2026-04-30
---
# Line Ending Parsing
**Category**: Cross-Platform
**Time Saved**: 30 minutes debugging string comparisons
**Battle-tested**: Yes — breaks pattern matching silently
---
## The Problem
You split a text file into lines and process each one. It works on macOS/Linux. On Windows, your regex patterns fail to match, or string comparisons return false even though the content looks identical.
## Why It Happens
Windows uses `\r\n` (CRLF) for line endings. Unix uses `\n` (LF).
```javascript
// File content on Windows:
"line1\r\nline2\r\nline3"
// After split("\n"):
["line1\r", "line2\r", "line3"]
// ↑ invisible \r still attached!
// Your pattern fails:
"line1\r" === "line1" // false
/^line1$/.test("line1\r") // false
```
## The Rule
**Always use `/\r?\n/` regex for splitting text files into lines.**
```javascript
// ❌ WRONG — leaves \r on Windows
const lines = content.split('\n');
// ✅ CORRECT — handles both CRLF and LF
const lines = content.split(/\r?\n/);
```
## Implementation Pattern
```javascript
const fs = require('fs');
function parseTextFile(filepath) {
const content = fs.readFileSync(filepath, 'utf8');
// Normalize line endings
const lines = content.split(/\r?\n/);
// Or use a helper
return normalizeLines(content);
}
function normalizeLines(text) {
// Option 1: Split with regex
return text.split(/\r?\n/);
// Option 2: Normalize then split
// return text.replace(/\r\n/g, '\n').split('\n');
}
```
## When This Matters
| Use Case | Impact of \r |
|----------|-------------|
| String equality | `"word\r" !== "word"` |
| Regex matching | `/^word$/` fails |
| Hash/checksum | Different hash values |
| JSON parsing | Usually OK (JSON.parse handles it) |
| CSV parsing | Column values have trailing \r |
| Config parsing | Key/value lookups fail |
## Common Symptoms
- "Pattern doesn't match on Windows"
- "String comparison fails but they look the same"
- "Works on Mac, breaks on Windows"
- `console.log` shows correct content but code doesn't match
## Debugging Hidden Characters
```javascript
// Reveal hidden characters
function showHidden(str) {
return str
.replace(/\r/g, '\\r')
.replace(/\n/g, '\\n');
}
console.log(showHidden(line));
// "expected value\r" ← the culprit!
```
## Related Scenarios
### Trimming Doesn't Always Help
```javascript
// trim() removes \r, but only at ends
" line1\r ".trim() // "line1\r" — \r still there if spaces follow!
// Be explicit
line.replace(/\r$/, '').trim()
```
### Reading Streams
```javascript
// readline module handles this automatically
const rl = readline.createInterface({ input: stream });
rl.on('line', (line) => {
// line has no \r or \n
});
```
### Writing Cross-Platform
```javascript
const os = require('os');
// Write with platform-appropriate line endings
const output = lines.join(os.EOL);
// Or force Unix line endings (common in config files)
const output = lines.join('\n');
```
## Verification Checklist
- [ ] All `split('\n')` calls use `/\r?\n/` instead
- [ ] String comparisons work on Windows test machine
- [ ] Config/CSV parsing tested with CRLF files
- [ ] Git autocrlf settings considered for repos
## Related Skills
- `cloud-storage-paths` — Cross-platform file access
- `terminal-backtick-hazard` — Cross-platform command execution
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!