meteor / meteor/blaze

Handlebars syntax is not bad at all, we can make it faster than React, Vue, or Svelte

Open
#361 5 comments 2 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
543
Forks
117
Avg merge
6h 18m
Merged PRs (30d)
2

Description

### Summary

The new component system [Solid.js](https://solidjs.com) looks like React (because it uses JSX syntax), but it compiles to something way better using dependency-tracking reactivity just like Meteor's reactive variables and tracker autoruns (called "signals" and "effects" in Solid).

This makes Solid.js an excellent pairing for Meteor because the paradigms match perfectly.

I believe we can use a package like https://www.npmjs.com/package/handlebars-to-jsx to compile Blaze templates into super fast Solid.js runtime equivalent to what Solid.js compiles JSX to.

### Background

To give a brief example, here's how to use Solid inside of Meteor:

```js
import {createEffect, createSignal} from 'solid-js'
import {ReactiveVar} from 'meteor/reactive-var'
import {Tracker} from 'meteor/tracker'

const meteorCount = new ReactiveVar(0)

setInterval(() => meteorCount.set(meteorCount.get() + 1), 1000)

// Solid's createSignal is the equivalent of Meteor's ReactiveVar
const [solidCount, setSolidCount] = createSignal(0)

Tracker.autorun(() => {
console.log('meteor count is: ', meteorCount.get())

// map the Meteor reactive var to the Solid signal
setSolidCount(meteorCount.get())
})

// Solid's createEffect is the equivalent of Meteor's Tracker.autorun, any used signals become dependencies of the effect.
createEffect(() => {
console.log('solid count is: ', solidCount())
})

function MySolidComponent() {
// Solid's JSX
return

The count is {solidCount()}

}
````

`MySolidComponent` compiles to something like the following (simplified, this hand written version is less optimized):

```js
function MySolidComponent() {
// Solid's JSX (looks like React)
const div = document.createElement('div')
const staticText = new Text('The count is ')
const dynamicText = new Text('')

div.append(staticText)
div.append(dynamicText)

createEffect(() => {
// Update the specific part of DOM any time the solidCount signal changes
dynamicText.nodeValue = solidCount()
})

return div
}
```

### How

To make this work, the best way would be to replace internals of Meteor Tracker with Solid reactivity in a backwards-compatible way. Then, with a handlebars-to-JSX transformation convert HTML to the JSX output (possibly optimized to avoid a JSX step, and just go straight to equivalent output).

### Why

Solid has gained popularity because of its simplicity, and performance. It beats well-known libs in some benchmarks, without sacrificing dev experience (actually improving it in various cases, for example compared to React). The [JS Framework Benchmark](https://krausest.github.io/js-framework-benchmark/current.html) is one example benchmark.

(@ryansolid @edemaine)

Contributor guide

Open the contributing guide

Research direction

Start by reviewing Meteor Tracker internals and the proposed handlebars-to-jsx package, then compare the Solid.js reactivity examples described in the issue with Blaze's existing component behavior. The issue does not identify files, tests, or a concrete completion criterion, so the intended scope would need to be defined before implementation.

Written by the indexing model from the issue text.

Assessment

Tech stack
handlebars, javascript
Domain
frontend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.