Skip to content
Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


Greenkeeper badge

This addon allow use .jsx/.tsx syntaxis for templates.

q: Why?

a: If you came from React, or want to "touch" JSX in Ember with an easy way, this is for you!

q: Can I use typings? Component types for autocomplete?

a: Yes! You can create .tsx template and import any typings into it.

q: How it's working?

a: Addon perform .jsx to JSX-AST transform, after we transform JSX-AST into HBS-AST and after we compile template from valid handlebars AST.

q: Is it Turing complete transpilation?

a: Nope, and never planned to be, all supported cases described in jsx-caster tests and jsx-extractor tests

q: If I spend some time, playing this addon, can I revert created jsx into hbs?

a: Yes, if you played enough with jsx you able to convert template to hbs using ember-meta-explorer extractJSXComponents method.


  • Ember.js v3.16 or above
  • Ember CLI v2.13 or above
  • Node.js v10 or above


ember install ember-cli-jsx-templates


template-only usecase

// app/templates/components/my-functional-component
export default function MyFunctionalComponent({name, onChange}) {
 const inputPrefix = 'New name:';
 return (
   <h1>JSX templates for Ember!</h1>
   <p>Hello, {name}!</p><br />
   {inputPrefix}: <input class="my-input" value={name} onkeyup={onChange}/>

any ember component + template usecase (with this):

// app/components/my-functional-component
import Component from '@ember/component';
export default class MyComponent extends Component {
    inputPrefix = "Nemo";
    onChange(e) {


// app/templates/components/my-functional-component
export default function MyFunctionalComponent() {
    return (
      <h1>JSX templates for Ember!</h1>
      <p>Hello, {this.inputPrefix}!</p><br />
      Update: <input class="my-input" value={name} onkeyup={action(this.onChange)}/>

basic usage:

// app/templates/components/my-component.jsx
<div attributes>{3 + 2} { props.children } { name } { props.external }</div>

will be compiled into:

<div ...attributes> {{add 3 2}} {{yield}} {{}} {{@external}}></div>

jsx for ember components:

<MyComponent attr-name="foo" value={42} data-test-name="item" onChange={action("update")} />

will be compiled into:

<MyComponent name="foo" @value={{42}} data-test-name="item" @onChange={{action "update"}} />

jsx having modifier:

<div mod-style={{color:"#face8d", ["font-size"]: "12px"}}></div>
// named arguments for modifiers not supported

will be compiled into:

<div {{style (hash color="#face8d" font-size= "12px")}}></div>

access to component's yielded context:

<MyComponent as={ctx, param}>{} {param}</MyComponent>

will be compiled into:

<MyComponent as |ctx param|>{{}} {{param}}</MyComponent>

yield with params:

<div>{yield(name, {foo:1})}</div>

will be compiled into:

<div>{{yield name (hash foo=1)}}</div>

.tsx template, with typings & autocomplete:

import { FooProp } from "./../../typings";
export default function TypedHello(props: FooProp) {
    return <h1>This is typed template! And name is: {}</h1>

will be compiled into:

<h1>This is typed template! And name is: {{@name}}</h1>

subtemplates declaration:

export function MyComponent() {
  const localTemplate = <h1>Hello!</h1>
  return <div>{localTemplate}</div>

will be compiled into:


How convert JSX back to HBS and save it?

Following blueprint created to convert any .jsx/.tsx file into .hbs template.

ember g jsx-template-to-hbs app/templates/components/hello-world.jsx

   no-remove - no remove jsx/tsx source
   no-write  - no wite converted output
   no-rewrite - no rewrite template file if already exists
   new-path:"app/templates/components/original.hbs" - new template file name

Can I convert HBS back to JSX? - nope

All supported cases: lifeart/ember-meta-explorer/test/utils/jsx-caster.test.js


See the Contributing guide for details.


This project is licensed under the MIT License.