rip-lang 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/.cursor/rules/rip-agent-onboarding.md +681 -0
  2. package/.github/ISSUE_TEMPLATE/bug_report.yml +98 -0
  3. package/.github/ISSUE_TEMPLATE/coffeescript_compatibility.yml +86 -0
  4. package/.github/ISSUE_TEMPLATE/config.yml +9 -0
  5. package/.github/ISSUE_TEMPLATE/feature_request.yml +82 -0
  6. package/.github/ISSUE_TEMPLATE/question.yml +55 -0
  7. package/.github/pull_request_template.md +84 -0
  8. package/AGENT.md +623 -0
  9. package/CONTRIBUTING.md +331 -0
  10. package/LICENSE +21 -0
  11. package/README.md +1245 -0
  12. package/SETUP.md +144 -0
  13. package/bar.coffee +394 -0
  14. package/bin/rip +162 -0
  15. package/bunfig.toml +11 -0
  16. package/docs/BROWSER.md +983 -0
  17. package/docs/CODEGEN.md +1023 -0
  18. package/docs/COFFEESCRIPT-COMPARISON.md +740 -0
  19. package/docs/COMPREHENSIONS.md +572 -0
  20. package/docs/REGEX-PLUS.md +441 -0
  21. package/docs/SOLAR.md +846 -0
  22. package/docs/SPECIAL-OPERATORS.md +769 -0
  23. package/docs/STRING.md +363 -0
  24. package/docs/WHY-NOT-COFFEESCRIPT.md +184 -0
  25. package/docs/WHY-YES-RIP.md +690 -0
  26. package/docs/WORKFLOW.md +306 -0
  27. package/docs/dist/rip.browser.js +6798 -0
  28. package/docs/dist/rip.browser.min.js +242 -0
  29. package/docs/dist/rip.browser.min.js.br +0 -0
  30. package/docs/example.html +177 -0
  31. package/docs/examples/README.md +154 -0
  32. package/docs/examples/arrows.rip +84 -0
  33. package/docs/examples/async-await.rip +59 -0
  34. package/docs/examples/existential.rip +86 -0
  35. package/docs/examples/fibonacci.rip +12 -0
  36. package/docs/examples/module.rip +38 -0
  37. package/docs/examples/object-syntax.rip +74 -0
  38. package/docs/examples/prototype.rip +30 -0
  39. package/docs/examples/ranges.rip +45 -0
  40. package/docs/examples/switch.rip +50 -0
  41. package/docs/examples/ternary.rip +36 -0
  42. package/docs/examples/use-loader.js +9 -0
  43. package/docs/examples/utils.rip +20 -0
  44. package/docs/index.html +65 -0
  45. package/docs/repl.html +914 -0
  46. package/docs/rip-1280w.png +0 -0
  47. package/docs/rip.svg +4 -0
  48. package/package.json +52 -0
  49. package/rip-loader.ts +27 -0
  50. package/scripts/build-browser.js +76 -0
  51. package/scripts/serve.js +71 -0
  52. package/src/browser.js +97 -0
  53. package/src/codegen.js +4808 -0
  54. package/src/compiler.js +270 -0
  55. package/src/grammar/grammar.rip +801 -0
  56. package/src/grammar/solar.rip +1056 -0
  57. package/src/lexer.js +3145 -0
  58. package/src/parser.js +352 -0
  59. package/src/repl.js +423 -0
  60. package/test/rip/assignment.rip +115 -0
  61. package/test/rip/async.rip +361 -0
  62. package/test/rip/basic.rip +171 -0
  63. package/test/rip/classes.rip +167 -0
  64. package/test/rip/compatibility.rip +338 -0
  65. package/test/rip/comprehensions.rip +104 -0
  66. package/test/rip/control.rip +177 -0
  67. package/test/rip/data.rip +215 -0
  68. package/test/rip/errors.rip +129 -0
  69. package/test/rip/functions.rip +443 -0
  70. package/test/rip/guards.rip +247 -0
  71. package/test/rip/literals.rip +131 -0
  72. package/test/rip/loops.rip +117 -0
  73. package/test/rip/modules.rip +87 -0
  74. package/test/rip/operators.rip +158 -0
  75. package/test/rip/optional.rip +184 -0
  76. package/test/rip/properties.rip +94 -0
  77. package/test/rip/regex.rip +301 -0
  78. package/test/rip/stabilization.rip +825 -0
  79. package/test/rip/strings.rip +483 -0
  80. package/test/runner.js +329 -0
package/docs/STRING.md ADDED
@@ -0,0 +1,363 @@
1
+ # CoffeeScript STRING Token Properties: Complete Reference
2
+
3
+ ## Overview
4
+
5
+ In CoffeeScript's lexer and parser, the STRING token carries several metadata properties that are essential for correctly transforming source strings into JavaScript output. These properties handle the complex edge cases of string literals, particularly heredocs (triple-quoted strings) and interpolated strings.
6
+
7
+ When the lexer encounters a string in source code, it doesn't just extract the raw text. It also annotates the token with metadata about HOW that string was written, which affects how it should be compiled to JavaScript.
8
+
9
+ ## The STRING Token Structure
10
+
11
+ A STRING token is not just a simple string value. It's an object with these properties:
12
+ - The string content itself (after slicing off quotes with `$1.slice 1, -1`)
13
+ - `quote`: The quote delimiter used
14
+ - `initialChunk`: Boolean flag for first chunk in interpolated string
15
+ - `finalChunk`: Boolean flag for last chunk in interpolated string
16
+ - `indent`: The common indentation to strip from heredocs
17
+ - `double`: Whether backslashes should be doubled in output
18
+ - `heregex`: Object with regex flags for extended regex literals
19
+
20
+ ## Property Descriptions and Usage
21
+
22
+ ### 1. `quote` - Quote Delimiter Type
23
+
24
+ **Purpose:** Records which quote characters were used to delimit the string in source code.
25
+
26
+ **Possible Values:**
27
+ - `"` - double quote
28
+ - `'` - single quote
29
+ - `"""` - triple double quote (heredoc)
30
+ - `'''` - triple single quote (heredoc)
31
+ - `"///"` - heregex (extended regex literal)
32
+ - `\`` - backtick (for template literals, though less common in CoffeeScript)
33
+
34
+ **Why It Exists:**
35
+ CoffeeScript needs to know the original quote style for several reasons:
36
+ 1. To determine if a string is a heredoc (`quote.length is 3`)
37
+ 2. To calculate proper location data (source maps) by accounting for quote length
38
+ 3. To determine the delimiter character (`quote.charAt(0)`)
39
+ 4. To preserve quote style when generating output or AST
40
+
41
+ **How It's Used:**
42
+
43
+ In the `StringLiteral` constructor:
44
+ - Normalizes heregex quotes: `@quote = null if @quote is '///'`
45
+ - Sets the `fromSourceString` flag: `@fromSourceString = @quote?`
46
+ - Provides default: `@quote ?= '"'`
47
+ - Determines delimiter: `@delimiter = @quote.charAt 0`
48
+ - Detects heredocs: `heredoc = @quote.length is 3`
49
+
50
+ In `withoutQuotesInLocationData()`:
51
+ - Adjusts first_column by adding quote length
52
+ - Adjusts last_column by subtracting quote length
53
+ - Adjusts last_column_exclusive by subtracting quote length
54
+ - Adjusts range array by quote length
55
+
56
+ In `StringWithInterpolations`:
57
+ - Stored and passed through: `{@quote, @startQuote}`
58
+ - Used when converting from StringLiteral: `quote: stringLiteral.quote`
59
+
60
+ **Example:**
61
+ ```coffeescript
62
+ x = "hello" # quote: "
63
+ y = 'world' # quote: '
64
+ z = """
65
+ multiline
66
+ """ # quote: """
67
+ ```
68
+
69
+ ### 2. `initialChunk` - First Chunk of Interpolated String
70
+
71
+ **Purpose:** Marks whether this STRING token is the very first chunk in an interpolated string.
72
+
73
+ **Possible Values:**
74
+ - `true` - This is the first string chunk
75
+ - `false` or undefined - Not the first chunk
76
+
77
+ **Why It Exists:**
78
+ Interpolated strings are broken into multiple tokens (string chunks and interpolation expressions). The first chunk has special whitespace handling rules - leading blank lines should be stripped in certain contexts.
79
+
80
+ **How It's Used:**
81
+
82
+ In heredoc processing (when `quote.length is 3`):
83
+ - If `@initialChunk` is true, `LEADING_BLANK_LINE` regex is used to strip the leading blank line
84
+ - Applied: `val = val.replace LEADING_BLANK_LINE, '' if @initialChunk`
85
+
86
+ In simple string processing:
87
+ - Combined with offset check to detect if a newline is at the very start
88
+ - If `@initialChunk and offset is 0`, convert the newline to empty string instead of a space
89
+ - This prevents unwanted leading whitespace in output
90
+
91
+ In the lexer's `mergeInterpolationTokens()`:
92
+ - Set on the token: `addTokenData token, initialChunk: yes if i is 0`
93
+ - Only set when the loop index `i` equals `0`
94
+
95
+ **Example:**
96
+ ```coffeescript
97
+ x = """
98
+ first line
99
+ second line
100
+ """
101
+ # The token for " first line\n second line\n " has initialChunk: true
102
+ # Leading blank line stripped if present
103
+
104
+ y = "prefix #{expr}
105
+ continuation"
106
+ # "prefix " has initialChunk: true
107
+ # " continuation" has initialChunk: false
108
+ ```
109
+
110
+ ### 3. `finalChunk` - Last Chunk of Interpolated String
111
+
112
+ **Purpose:** Marks whether this STRING token is the very last chunk in an interpolated string.
113
+
114
+ **Possible Values:**
115
+ - `true` - This is the final string chunk
116
+ - `false` or undefined - Not the final chunk
117
+
118
+ **Why It Exists:**
119
+ Similar to `initialChunk`, the final chunk has special whitespace handling - trailing blank lines should be stripped in certain contexts.
120
+
121
+ **How It's Used:**
122
+
123
+ In heredoc processing:
124
+ - If `@finalChunk` is true, `TRAILING_BLANK_LINE` regex is used to strip the trailing blank line
125
+ - Applied: `val = val.replace TRAILING_BLANK_LINE, '' if @finalChunk`
126
+
127
+ In simple string processing:
128
+ - Combined with position check to detect if a newline is at the very end
129
+ - If `@finalChunk and offset + match.length is val.length`, convert the newline to empty string
130
+ - Prevents unwanted trailing whitespace
131
+
132
+ In the lexer's `mergeInterpolationTokens()`:
133
+ - Set on the token: `addTokenData token, finalChunk: yes if i is $`
134
+ - Where `$` is the last index in the tokens array (`tokens.length - 1`)
135
+
136
+ **Example:**
137
+ ```coffeescript
138
+ x = """
139
+ some text
140
+
141
+ """
142
+ # The string token has finalChunk: true
143
+ # Trailing blank line stripped
144
+
145
+ y = "start #{x} end"
146
+ # "start " has finalChunk: false
147
+ # " end" has finalChunk: true
148
+ ```
149
+
150
+ ### 4. `indent` - Common Indentation to Strip
151
+
152
+ **Purpose:** Records the common leading whitespace found across all lines of a heredoc that should be stripped during compilation.
153
+
154
+ **Possible Values:**
155
+ - A string of whitespace characters (spaces/tabs)
156
+ - `null` or undefined if no common indentation
157
+
158
+ **Why It Exists:**
159
+ Heredocs allow you to write multiline strings with proper indentation in your source code. The compiler needs to strip this "code indentation" to produce the actual intended string content. This enables readable code without affecting the runtime string value.
160
+
161
+ **How It's Used:**
162
+
163
+ In heredoc processing:
164
+ - If `@indent` exists, create a regex pattern: `indentRegex = /// \n#{@indent} ///g`
165
+ - Apply the regex to strip the indent: `val = val.replace indentRegex, '\n' if indentRegex`
166
+ - This replaces every occurrence of `\n` followed by the indent string with just `\n`
167
+
168
+ In the lexer's string processing:
169
+ - The lexer scans all lines in a heredoc
170
+ - Finds the minimum indentation across all non-empty lines
171
+ - Stores this as the `indent` value: `indent = attempt if indent is null or 0 < attempt.length < indent.length`
172
+ - Passed to `mergeInterpolationTokens` for attachment to tokens
173
+
174
+ **Example:**
175
+ ```coffeescript
176
+ x = """
177
+ Line 1
178
+ Line 2
179
+ Indented more
180
+ """
181
+ # indent would be " " (4 spaces)
182
+ # After processing:
183
+ # "Line 1\nLine 2\n Indented more"
184
+ # Note: The extra indent on line 3 is preserved
185
+
186
+ # With irregular indentation:
187
+ y = """
188
+ First (2 spaces)
189
+ Second (6 spaces)
190
+ Third (4 spaces)
191
+ """
192
+ # indent would be " " (2 spaces - the minimum)
193
+ # After processing:
194
+ # "First (2 spaces)\n Second (6 spaces)\n Third (4 spaces)"
195
+ ```
196
+
197
+ ### 5. `double` - Backslash Doubling Flag
198
+
199
+ **Purpose:** Indicates whether backslash characters in the string should be doubled when generating JavaScript output.
200
+
201
+ **Possible Values:**
202
+ - `true` - Double backslashes
203
+ - `false` or undefined - Don't double backslashes
204
+
205
+ **Why It Exists:**
206
+ JavaScript requires different levels of escaping depending on the context. When CoffeeScript generates string literals, it needs to ensure backslashes are properly escaped. The `double` flag controls whether `\` becomes `\\` in the output.
207
+
208
+ **How It's Used:**
209
+
210
+ Passed to the `makeDelimitedLiteral()` helper function in two contexts:
211
+
212
+ 1. **Main value generation:**
213
+ ```coffeescript
214
+ @value = makeDelimitedLiteral val, {
215
+ @delimiter
216
+ @double
217
+ }
218
+ ```
219
+
220
+ 2. **Template literal conversion:**
221
+ ```coffeescript
222
+ @unquotedValueForTemplateLiteral = makeDelimitedLiteral val, {
223
+ delimiter: '`'
224
+ @double
225
+ escapeNewlines: no
226
+ includeDelimiters: no
227
+ convertTrailingNullEscapes: yes
228
+ }
229
+ ```
230
+
231
+ Inside `makeDelimitedLiteral()`:
232
+ - When processing a backslash: `when backslash then (if double then backslash + backslash else backslash)`
233
+ - When processing other escapes: `when other then (if double then "\\#{other}" else other)`
234
+ - This ensures proper escape sequences in the generated JavaScript
235
+
236
+ **Example:**
237
+ ```coffeescript
238
+ # If double is true:
239
+ "\n" → "\\n" (in generated JS)
240
+ "\\" → "\\\\" (in generated JS)
241
+
242
+ # If double is false:
243
+ "\n" → "\n" (preserved)
244
+ "\\" → "\\" (preserved)
245
+ ```
246
+
247
+ ### 6. `heregex` - Extended Regex Metadata
248
+
249
+ **Purpose:** Contains metadata about extended regular expression (heregex) literals, including flags.
250
+
251
+ **Possible Values:**
252
+ - An object with a `flags` property containing regex flags
253
+ - `undefined` if not a heregex
254
+
255
+ **Why It Exists:**
256
+ CoffeeScript supports "heregexes" - extended regular expressions that allow whitespace and comments for readability. These are delimited with `///` and need special processing. The flags (like `g`, `i`, `m`) need to be tracked and preserved.
257
+
258
+ **How It's Used:**
259
+
260
+ In the `StringLiteral` constructor:
261
+ - Detects heregex mode: `if @heregex`
262
+ - Applies heregex-specific transformations:
263
+ - Removes whitespace and comments: `val = val.replace HEREGEX_OMIT, '$1$2'`
264
+ - Processes unicode escapes with flags: `val = replaceUnicodeCodePointEscapes val, flags: @heregex.flags`
265
+
266
+ In the lexer:
267
+ - When tokenizing a heregex, comment tokens are marked: `heregex: yes`
268
+ - The flags are extracted and stored in the heregex object
269
+ - Passed through in `mergeInterpolationTokens`: `addTokenData token, {heregex} if heregex`
270
+
271
+ **Example:**
272
+ ```coffeescript
273
+ pattern = ///
274
+ ^ \d+ # starts with digits
275
+ \s* # optional whitespace
276
+ [a-z]+ # followed by letters
277
+ $ # end of string
278
+ ///i # case-insensitive flag
279
+
280
+ # heregex: { flags: 'i' }
281
+ # The whitespace and comments are stripped
282
+ # The 'i' flag is preserved for the output regex
283
+ ```
284
+
285
+ ## How These Properties Work Together
286
+
287
+ ### Interpolated String Processing
288
+
289
+ When an interpolated string is lexed:
290
+
291
+ 1. The lexer identifies quote type → sets `quote`
292
+ 2. For heredocs, calculates common indent → sets `indent`
293
+ 3. Breaks string into chunks around interpolations
294
+ 4. Marks first chunk → sets `initialChunk: true`
295
+ 5. Marks last chunk → sets `finalChunk: true`
296
+ 6. Determines escape context → sets `double`
297
+
298
+ When the string is compiled to JavaScript:
299
+
300
+ 1. Check `quote.length is 3` to detect heredoc
301
+ 2. If heredoc and `indent` exists, strip common indentation
302
+ 3. If `initialChunk`, strip leading blank line
303
+ 4. If `finalChunk`, strip trailing blank line
304
+ 5. Use `double` to control backslash escaping
305
+ 6. Use `quote` for location data adjustments
306
+
307
+ ### Heregex Processing
308
+
309
+ 1. Lexer detects `///` → sets `quote: '///'`
310
+ 2. Flags are parsed → sets `heregex: { flags: '...' }`
311
+ 3. In compilation, apply special regex transformations
312
+ 4. Preserve flags in output
313
+
314
+ ## Why This Matters
315
+
316
+ Without these properties, it would be impossible to:
317
+
318
+ 1. **Correctly handle heredoc indentation:** You wouldn't know what common indent to strip
319
+ 2. **Properly trim whitespace:** You wouldn't know which chunks are first/last
320
+ 3. **Generate accurate source maps:** Quote length affects column positions
321
+ 4. **Preserve semantic meaning:** Different quote styles have different escaping rules
322
+ 5. **Support readable regex:** Heregex flags and content need special processing
323
+ 6. **Match JavaScript semantics:** Backslash doubling must match the output context
324
+
325
+ ## Common Pitfalls Without This Information
326
+
327
+ When implementing a string processor without understanding these properties:
328
+
329
+ - **Indentation errors:** Heredocs include unwanted leading whitespace
330
+ - **Newline handling:** Extra blank lines appear at start/end of strings
331
+ - **Escape sequence bugs:** Backslashes aren't properly doubled or preserved
332
+ - **Source map misalignment:** Location data doesn't account for quote characters
333
+ - **Regex compilation failures:** Heregex content isn't properly stripped
334
+
335
+ ## Summary
336
+
337
+ The STRING token is not just a value - it's a rich data structure that captures the INTENT and CONTEXT of how a string was written in source code. Each property serves a specific purpose in the transformation pipeline from CoffeeScript source to JavaScript output. Understanding these properties is essential for correctly implementing string handling in any CoffeeScript-like compiler.
338
+
339
+ ## REGEX Tokens (Rip Extension)
340
+
341
+ While STRING tokens have properties directly on the String object, **REGEX tokens store metadata in `token.data`**:
342
+
343
+ ```javascript
344
+ // REGEX token structure:
345
+ token = ['REGEX', String("/pattern/flags"), location]
346
+ token.data = {
347
+ delimiter: '///', // '/' for normal regex, '///' for heregex
348
+ heregex: {flags: 'gi'} // Only for heregex
349
+ }
350
+ ```
351
+
352
+ **The Rewriter's `exposeTokenDataToGrammar()` copies these to the String object:**
353
+ ```javascript
354
+ token[1].delimiter = token.data.delimiter;
355
+ token[1].heregex = token.data.heregex;
356
+ ```
357
+
358
+ This allows Rip's codegen to detect and process heregex (extended regex with whitespace/comments) by checking:
359
+ ```javascript
360
+ if (strObj.delimiter === '///' && strObj.heregex) {
361
+ // Process heregex: strip whitespace and comments
362
+ }
363
+ ```
@@ -0,0 +1,184 @@
1
+ # Why Not CoffeeScript: The Case Against Revival
2
+
3
+ ## Executive Summary
4
+
5
+ CoffeeScript 2 already achieved the goal of modern JavaScript output in 2017. Any effort toward further CoffeeScript development in 2025 represents a misallocation of resources toward a language that has been definitively superseded by the JavaScript ecosystem's evolution. This document presents the compelling case for why CoffeeScript should remain a respected historical artifact rather than receive continued development.
6
+
7
+ **TL;DR:** The ecosystem has moved on. The tooling has rotted. The community has dispersed. TypeScript won the type safety war. Modern JavaScript absorbed the best ideas. What's left isn't worth the cost.
8
+
9
+ ## The Fundamental Misconception
10
+
11
+ Many assume CoffeeScript needs updating to output ES6+. **This is false.** CoffeeScript 2 (released 2017) already generates:
12
+ - ES6 classes with `extends` and `super`
13
+ - Arrow functions with lexical `this`
14
+ - Destructuring assignments
15
+ - Template literals
16
+ - `for...of` loops
17
+ - ES6 modules (`import`/`export`)
18
+ - Spread operators
19
+ - Computed property names
20
+
21
+ The output is already modern. The problem isn't technical—it's existential.
22
+
23
+ ## 1. Ecosystem Abandonment: The Network Effect in Reverse
24
+
25
+ ### The Developer Desert
26
+ - **Hiring Crisis**: Try posting a "CoffeeScript Developer" position in 2025. You'll get tumbleweeds or developers who haven't touched it since 2015.
27
+ - **Knowledge Decay**: Senior developers who knew CoffeeScript have moved on. Junior developers have never heard of it.
28
+ - **AI Blindness**: GitHub Copilot, ChatGPT, and other AI assistants are trained on modern codebases. Their CoffeeScript suggestions are often outdated or incorrect.
29
+ - **Dead Community**: The CoffeeScript forum has ~5 posts per month. The TypeScript forum has ~500. The network effect that once benefited CoffeeScript now strangles it.
30
+
31
+ ### Library Lockout
32
+ - **TypeScript Hegemony**: Every major library ships with `.d.ts` files. Using them from CoffeeScript means abandoning type safety entirely.
33
+ - **No Native Integrations**: Modern frameworks (Next.js, Nuxt, SvelteKit) assume TypeScript or JavaScript. CoffeeScript requires custom configuration that often breaks with updates.
34
+ - **Security Vulnerabilities**: When was the last time CoffeeScript's dependencies were audited? The maintenance burden falls on a tiny, overwhelmed community.
35
+
36
+ ## 2. The Type Safety Revolution Left CoffeeScript Behind
37
+
38
+ ### TypeScript Won by Solving Real Problems
39
+ - **Refactoring at Scale**: Rename a method in TypeScript, and your IDE updates every call site. In CoffeeScript, you grep and pray.
40
+ - **API Contracts**: TypeScript interfaces document and enforce API contracts. CoffeeScript relies on... documentation? Comments? Hope?
41
+ - **Compile-Time Catches**: TypeScript catches errors before runtime. CoffeeScript catches them... in production.
42
+ - **IntelliSense**: Modern developers expect autocomplete that actually works. CoffeeScript's IDE support is "here's a list of every word in your file."
43
+
44
+ ### The Cost of Being Typeless in 2025
45
+ - **Integration Nightmare**: Every third-party library requires manual type annotations or living without IDE support
46
+ - **Team Scaling Breaks**: CoffeeScript works for 1-2 developers who hold the entire codebase in their heads. At 10+ developers, the lack of types becomes a coordination disaster.
47
+ - **No Migration Path**: You can gradually adopt TypeScript in a JavaScript codebase. CoffeeScript requires a full rewrite.
48
+
49
+ ## 3. Tooling Degradation: Death by a Thousand Cuts
50
+
51
+ ### IDE Abandonment
52
+ - **VS Code**: CoffeeScript extension last meaningful update: 2019. TypeScript: Updated weekly. The gap widens daily.
53
+ - **WebStorm**: CoffeeScript support officially deprecated as of 2024. JetBrains gave up.
54
+ - **Vim/Neovim**: CoffeeScript LSP? Might as well ask for a steam-powered smartphone.
55
+ - **GitHub Copilot**: Trained on modern codebases. CoffeeScript suggestions are often wrong or outdated.
56
+ - **Cursor/AI IDEs**: The future of development doesn't include CoffeeScript in their training data.
57
+
58
+ ### Build Tool Afterthought
59
+ - **Vite**: Requires a third-party plugin that breaks every major update
60
+ - **Webpack**: CoffeeScript loader is in maintenance mode
61
+ - **Bun**: Can bundle TypeScript natively. CoffeeScript? "What's that?"
62
+ - **Deno**: Built for TypeScript-first development. CoffeeScript is alien technology.
63
+
64
+ ### Developer Experience Regression
65
+ - **No Prettier Support**: Your team will have formatting wars like it's 2010
66
+ - **ESLint**: Limited rules, most plugins incompatible
67
+ - **Source Maps**: They exist, but debugging through transpilation layers is always worse than native
68
+ - **Hot Module Replacement**: Works... sometimes... if you hold your mouth right
69
+
70
+ ## 4. Modern JavaScript Didn't Just Catch Up—It Surpassed
71
+
72
+ ### JavaScript Absorbed CoffeeScript's Best Ideas
73
+ - **Optional Chaining**: JS `?.` is everywhere now
74
+ - **Nullish Coalescing**: JS `??` handles null/undefined elegantly
75
+ - **Arrow Functions**: JS `=>` is more explicit about `this` binding
76
+ - **Destructuring**: JS destructuring is more powerful and flexible
77
+ - **Classes**: JS classes are native, optimized, and well-understood
78
+ - **Template Literals**: JS backticks are standard
79
+
80
+ ### What's Left Is Not Enough
81
+ - **Significant Whitespace**: Python developers like it. JavaScript developers see it as a footgun.
82
+ - **Implicit Returns**: Causes more bugs than it prevents. Explicit is better than implicit.
83
+ - **Everything is an Expression**: Clever, but creates debugging nightmares.
84
+ - **Existential Operator**: JavaScript's `?.` and `??` cover 95% of use cases more clearly.
85
+
86
+ ## 5. The Performance and Security Argument
87
+
88
+ ### Runtime Overhead
89
+ - **Extra Transpilation**: Every file goes through an additional compilation step
90
+ - **Larger Bundles**: CoffeeScript's runtime helpers add weight
91
+ - **Slower Development**: Live reload, HMR, all slower due to the compilation step
92
+ - **Memory overhead**: Build tools keep both CS and JS versions in memory
93
+
94
+ ### Security Concerns
95
+ - **Supply Chain Risk**: CoffeeScript itself is a dependency with minimal maintenance
96
+ - **Outdated Dependencies**: The CS ecosystem doesn't get security updates quickly
97
+ - **Audit Complexity**: Security tools are built for JS/TS, not CoffeeScript
98
+
99
+ ## 6. The Business Case Against CoffeeScript
100
+
101
+ ### Technical Debt Multiplication
102
+ - **Training Costs**: Every new hire needs CoffeeScript training
103
+ - **Maintenance Burden**: You maintain both the code AND the build pipeline
104
+ - **Migration Inevitable**: Every CS codebase eventually migrates to JS/TS
105
+ - **Opportunity Cost**: Time spent on CS tooling is time not spent on features
106
+
107
+ ### Project Risk Factors
108
+ - **Bus Factor of One**: Often only one person really knows the CS codebase
109
+ - **Vendor Lock-in**: Stuck with outdated tools that support CoffeeScript
110
+ - **Recruitment Nightmare**: Developers actively avoid CoffeeScript positions
111
+ - **Technical Isolation**: Can't easily adopt new tools, libraries, or practices
112
+
113
+ ## 7. The False Economy of Syntax Sugar
114
+
115
+ ### The "Conciseness" Trap
116
+ CoffeeScript is more concise, but:
117
+ - **Readability > Brevity**: Explicit code is easier to maintain
118
+ - **Debugging Nightmare**: Less syntax means more implicit behavior to debug
119
+ - **Onboarding Barrier**: New developers need to learn a whole new syntax
120
+ - **Copy-Paste Broken**: Can't use code examples from Stack Overflow, documentation, or AI assistants
121
+
122
+ ### The Real Cost of "Beautiful" Code
123
+ - **Cognitive Load**: Developers must mentally transpile CS to JS to understand behavior
124
+ - **Error Messages**: Stack traces reference generated JS, not source CS
125
+ - **Code Review**: Reviewers need CS expertise, limiting your reviewer pool
126
+
127
+ ## 8. The Innovation Dead End
128
+
129
+ ### Language Evolution Frozen
130
+ - **No New Features**: When was the last significant CoffeeScript language feature?
131
+ - **No Standards Process**: JavaScript has TC39. CoffeeScript has... GitHub issues?
132
+ - **No Corporate Backing**: Microsoft backs TypeScript. Who backs CoffeeScript?
133
+
134
+ ### Missing Modern Features
135
+ - **No Decorators**: The rest of the ecosystem is adopting them
136
+ - **No Private Fields**: Modern JS has `#private`, CS has... conventions?
137
+ - **No Pattern Matching**: TC39 is working on it for JS, CS will never get it
138
+ - **No Type Parameters**: Generic programming is impossible
139
+
140
+ ## 9. The Maintainer Burden
141
+
142
+ ### The Human Cost
143
+ - **Burnout**: The few CS maintainers are overwhelmed
144
+ - **No Succession Plan**: When current maintainers leave, who takes over?
145
+ - **Feature Requests**: The backlog grows while maintainer energy shrinks
146
+ - **Breaking Changes**: Fear of breaking existing code prevents evolution
147
+
148
+ ### The Quality Spiral
149
+ - **Bug Accumulation**: Bugs pile up faster than they're fixed
150
+ - **Documentation Rot**: Outdated docs are worse than no docs
151
+ - **Example Decay**: Sample code uses patterns from 2015
152
+
153
+ ## 10. The Strategic Dead End
154
+
155
+ ### No Path Forward
156
+ - **No Migration Strategy**: You can't gradually move from CS to modern alternatives
157
+ - **No Ecosystem Integration**: New tools don't consider CoffeeScript at all
158
+ - **No Corporate Use Cases**: No major company is choosing CoffeeScript for new projects
159
+ - **No Educational Value**: Bootcamps and universities don't teach it
160
+
161
+ ### The Opportunity Cost
162
+ Every hour spent on CoffeeScript 3 could be spent on:
163
+ - **Learning Rust/Go/Zig**: Languages with actual momentum
164
+ - **Contributing to TypeScript**: Where improvements benefit millions
165
+ - **Building Tools**: That solve real problems for modern developers
166
+ - **Creating Libraries**: That the ecosystem actually needs
167
+
168
+ ## The Verdict: Let It Rest
169
+
170
+ CoffeeScript served its purpose. It showed JavaScript could be better and influenced ES6+. That's a tremendous legacy. But continuing to develop CoffeeScript in 2025 is like maintaining a telegraph network in the age of 5G.
171
+
172
+ The language works—CoffeeScript 2 outputs modern JavaScript that runs everywhere. But "works" isn't enough when the entire ecosystem has moved on. Development is a team sport, and CoffeeScript has no team left.
173
+
174
+ ### The Harsh Truth
175
+
176
+ CoffeeScript 3 would be a technical achievement that nobody asked for, solving problems nobody has, for a community that no longer exists. The language's elegant syntax cannot overcome the brutal reality of ecosystem abandonment.
177
+
178
+ The kindest thing for CoffeeScript is to recognize it as a successful historical artifact that accomplished its mission: pushing JavaScript to become better. That mission is complete. CoffeeScript won by losing—its ideas live on in modern JavaScript while the language itself can finally rest.
179
+
180
+ **Building CoffeeScript 3 isn't just unnecessary—it's actively harmful to the developers who would be trapped maintaining codebases in a dead language, cut off from the vibrant, innovative JavaScript ecosystem of 2025 and beyond.**
181
+
182
+ ---
183
+
184
+ *The real question isn't "Why not CoffeeScript 3?" but "Why would anyone choose suffering when better alternatives exist?"*