CoffeeScript and JSX

I don't think we need JSX.

JSX makes some sense is JavaScript but little in CoffeeScript.

Adding CJSX as a dependency of our apps feels dirty. We're working really hard to support something that nobody wants — "HTML-like syntax" in CoffeeScript preprocessed JavaScript templates.


It's curious, why would we try so hard to get HTML into CS-templates when we fight so valiantly to purge them elsewhere (Haml, Slim).

Experience Building Services:LIVE

JSX(CJSX) did not deliver on the promise of disambiguating function-templates for designers. @dsecrest, @shane, feel free to disagree with me if that is no longer true.

JSX differs from HTML—in important enough areas—that it's difficult to be confident of the output.

Obviously JSX is not HTML. But the shared syntax doesn't make it easy for newcomers to spot the difference.

CoffeeScript for React Templates

I posit that CoffeeScript offers a pretty great syntax for writing React templates. The CoffeeScript syntax maps very nicely to JSX output. Here is an actual CJSX template from LIVE:

render: ->
	{if @props.enabled then 'Watch A Service' else '(no services to watch)'}

Here is the same template written in CoffeeScript:

render: ->
	className: React.addons.classSet(@getClassSet())
	disabled:  !@props.enabled
	onClick:   @handleClick,
	if @props.enabled then 'Watch A Service' else '(no services to watch)'

CoffeeScript offers a lot of clarity over the JSX version:

  • Clearly shows props as object-properties
  • Clearly shows why props must be written in camelCase
  • Disambiguates confusion around HTML-native properties disabled and onClick
  • Lowers the templates surface area for bugs:
    • 1 fewer lines
    • 9 fewer characters
    • 3 fewer interpolations (now 0)
    • no closing tag

Additional benefits:

  • No ###* @cjsx React.DOM ### silly-ness
  • No confusion over what attrs do or don't share HTML syntax
  • Template remains in the language of component logic
    • Conditional statements can be logically formatted, without interpolation
    • Iterator-function can more reasonably be

A note on multi-line props

We got into the practice of placing props/attrs on new lines. It improves diffs and makes actions easier to target.


  • React.DOM prefix for native HTML tags
  • Required trailing comma to separating the props object and children (though, props.children can be passed in as a prop)
  • Required null or {} as first argument when no props are specified (which is rare in practice)

My Position

We don't need JSX. We don't want CJSX.

(can anyone even tell me how to make a comment in CJSX?)