Anyone from Meteor?

Is anyone here from Meteor? In your opinion, how does Phoenix compare to Meteor? We all know that Phoenix scales much better so it would be more interesting to hear about developer productivity.

3 Likes

I donā€™t know meteor at all, but took a look at its webpage and just from the brief I do see a very major difference (apart from the language): Phoenix is not for desktop or mobile applications but web only.

Meteor isnā€™t desktop or mobile either. It just has good build system with Cordova.

I used meteor briefly for a few production apps.
Phoenix blows Meteor off the face of the planet for my use.

Meteor is faster for some prototyping / product to market because of the packages that are available to it.
That said there were like 1300 hex packages starting this year , now theres almost 1890 packages. so I se that gap closing. Meteor apps in production are a nightmare compared to a phoenix application.

in short , the amount of black magic that makes Meteor interesting is the same thing that leaves it vulnerable. If you want to do something out of the box you have to invent your own black magic and wrap it in voodoo and hope that it does backfire.

We migrated the meteor apps to phoenix btw :slight_smile:

5 Likes

What I know about Meteor, but maybe you can correct me. It enables client <----> server state synchronization. The client has local database. It writes/reads to local database and this database is ā€œautomaticā€ synchronized with server database.
The backed is written in nodejs. It only support some databases like mongodb.

We donā€™t have so tight integration client - server in Elixir,Phoenix. Phoenix can only export REST API/ websockets. The client <ā€”>server synchronization must be done by developer. I know there is plan form more tight integration with ELM.

There are some alternative for example if you want use facebook graphql with relay
The graphql is openstandard, implemented in many lagauges awesome-graphql. There is elixir implementation also.

Other similar solutions:
https://pouchdb.com/ with http://couchdb.apache.org/
Om next clojurescript <----> clojure, video
couchbase-mobile
Firebase

3 Likes

It claims to be (on an inaccessible webpage [in terms of canā€™t copy that part of text]):

1 Like

Have a look at this thread - there are quite a few people who have come to Phoenix from Meteor :slight_smile:

//cc @MichaelC @drb @Mandemus

I discovered Phoenix due to this mega-thread on the meteor forums.

As was said previously Meteor is great for prototyping. However the only way to scale past 200 or so concurrent users appears to be ripping everything out of meteor that makes it meteor. It neither scales vertically or horizontally as itā€™s crippled by the oplog tailing.

Iā€™m happy I made the switch and havenā€™t looked back.

In terms of productivity Iā€™m nowhere near as productive. That mostly being because Iā€™m new to FP and still in the learning stage.

So far it seems to be quite declarative and self documenting as an app is essentially a series of pipes. Itā€™s obvious what my code is doing. Itā€™s also very terse.

Once Iā€™m as comfortable with elixir and phoenix as I am with Javascript I can honestly see myself being more productive.

5 Likes

Yep, that forum post was good gateway to elixir/phoenix platform

1 Like

This is not true! Iā€™ve pitched Phoenix from the very beginning about being a framework that goes ā€œbeyond the browserā€. See the heading in our 1.0 announcement:
http://www.phoenixframework.org/blog/phoenix-10-the-framework-for-the-modern-web-just-landed#beyond-the-browser

Phoenix channels targets all platforms, desktop, embedded, native iOS/Android and whatever transport you want to build on top of.

6 Likes

Can there be some connection of Phoenix channels to http://reactivex.io/ clients: RxJS, RxJava, RxSwift?. I think this could be interesting :slight_smile:

1 Like

This is how I found out about Elixir and Phoenix as well!

Iā€™m glad at least one person said this:

1 Like

This is true with minimongo built in into Meteor but it seems like the trend is going towards leveraging other technologies (Flux, Redux, etc). This is because allow, deny rules are arguably known to have security flaws and Meteor community is moving towards using React instead of Blaze. Although there are other benefits of using Meteor, the client and server technologies are more decoupled meaning Elixir/Phoenix developers should be able to achieve similar results using those front-end technologies.

1 Like

The client - server state synchronization is complicated topic and it hard to do it right. For example for mobile less requests to server is better. The facebook graphql - relay handle this by collecting all data needed by page and sending one request to get this data. On the relay client you build page with components. Each component defines data which needs to render. So page knows what data needs to render it.

Big fan of Meteor, but lack of first class SQL support, and the usage of Fibers as a Node crutch doesnā€™t sit too well with meā€¦

The concurrency patterns and performance benefits of using Elixir/Phoenix on the server are what drew me to this platform.

I am very excited about the Apollo project that MDG is working on.
An Apollo client w/React + Phoenix/GraphQL back-end would be an awesome stack.

4 Likes

By the day we have native channel support for all (important) platforms, with this, of course you are right, and of course, as the creator you do know it best ;).

But, the big difference I do see here, and which I wanted to point out, is that meteor advertises to be full stack, at least thats how I read the aforementioned quote!

Meteors advertisement reads as if I only need to pull a switch and have an Android App, iOS App, or Windows Desktop Program without any change of code. And exactly this is not possible using Phoenix (probably never will). For Phoenix you still need to code distinct applications for each platform.

They are using Cordova (Webview apps) to achieve this. I believe you could get similar results using phoenix.

Sorry, going to partake in some necromancy hereā€¦

Iā€™ve just built and launched a fairly major relaunch of my companies primary app. We also ended up rebuilding the entire data storage and architecture tooā€¦what fun! Any way, between some issues with Meteor evolving and feature-creep, the rebuild has taken close to a year. Now, in that time, not only the features itā€™s expected to deliver, but the scale have changed dramatically. Basically, Meteor will cost us a bomb in hosting!

About two months ago I started writing all new code with a very strict Meteor/React divide, with the intention to break them apart and Phoenix incrementally take over the backend. Now that weā€™ve launched, Iā€™m thinning out all the Meteor dependancies I can, and replacing them with React implementations (alerts, routers, client-side store, etc).

Even with React acting as the middleman, itā€™s going to be a tough progression which I expect us to be chewing through for months.

Long and the short, even if Phoenix was drastically less productive (itā€™s notā€¦itā€™s more) than Meteor, we still would have been way better off using Elixir/Phoenix. I feel really burnt by Meteor, and wonā€™t be building with it again, purely because itā€™s so hard to escape from (better now they have nom support).

3 Likes

Honestly Iā€™d say take a look at webcomponents. They are actually part of the HTML5 spec, the polyfills for them work wonderfully (not even had any issues on the IE11 I test on at work), and it is a standard. React emulate webcomponents but via its little render system. There are dozens of webcomponent libraries too but you can just write them in plain javascript with ease anyway, you can even use react to write them (except using them in react is even easier than normal react components as they act like like normal DOM elements).

Iā€™ve personally been using plain javascript to make webcomponents and Polymer (Googleā€™s webcomponent library, adds templating, almost-stupid-easy two-way data binding, etcā€¦ but for just data-oriented webcomponents I usually make those in plain javascript).

As an example, here is how one of my HTML files looks:

  <body unresolved>
    <page-spa param-token="<%= Guardian.Plug.current_token(@conn) %>" base-path="/spa"></page-spa>
  </body>

And my page-spa webcomponentā€™s html template is just normal html (inside an html5-standard <template> element):


  <template>
    <style>
    /* snip css, for note CSS is scoped to only this webelement,
      nothing leaks into a webelement from outside and nothing leaks
      out, feel free to make them simple like matching on something
      specific instead of class matching, users can pass overrides to
      your internal css via html5 css variables, also polyfilled for
      older browsers. */
    </style>
    <app-location route="{{route}}"></app-location>
    <app-route id="route"
      route="{{route}}"
      pattern="[[basePath]]/:name"
      data="{{moduleRouteData}}"
      tail="{{moduleRoute}}"
      active="{{moduleRouteActive}}"
      ></app-route>

    <phoenix-socket id="socket"
      endpoint="/socket"
      param-token="[[paramToken]]"
      connected="{{socketConnected}}"
      socket="{{socket}}"
      connect="true"
      ></phoenix-socket>

    <phoenix-channel
      socket="{{socket}}"
      channel="{{controlChannel}}"
      topic="SPA"
      msg-joined="{{controlChannelMsgJoined}}"
      connected="{{controlChannelConnected}}"
      ></phoenix-channel>
    <phoenix-channel-msg
      channel="{{controlChannel}}"
      event="view"
      msg-latest="{{mainViewData}}"
      ></phoenix-channel-msg>

    <phoenix-channel
      socket="{{socket}}"
      channel="{{moduleChannel}}"
      topic-pre="SPA:"
      topic="[[moduleRouteData.name]]"
      msg-joined="{{moduleChannelMsgJoined}}"
      connected="{{moduleChannelConnected}}"
      connect="[[moduleRouteActive]]"
      ></phoenix-channel>
    <phoenix-channel-msg
      channel="{{moduleChannel}}"
      event="view"
      msg-latest="{{moduleViewData}}"
      ></phoenix-channel-msg>

    <app-drawer-layout id="layout" responsive-width="1280px">
      <app-drawer swipe-open>
        <app-header condenses reveals shadow effects="waterfall">
          <app-toolbar style="pointer-events:all;">
            <div main-title>Drawer</div>
          </app-toolbar>
        </app-header>
        <div style="height: 100%; overflow: auto;">Testing a drawer</div>
      </app-drawer>
      <app-header-layout>
        <app-header condenses reveals shadow effects="waterfall">
          <app-toolbar style="pointer-events:all;">
            <paper-icon-button icon="menu" drawer-toggle></paper-icon-button>
            <div main-title>MyServer Title</div>
          </app-toolbar>
        </app-header>

        <neon-animated-pages
          id="moduleContainer"
          attr-for-selected="module"
          selected=""
          entry-animation="slide-from-right-animation"
          exit-animation="slide-left-animation"
          animateInitialSelection="true"></neon-animated-pages>

      </app-header-layout>
    </app-drawer-layout>
  </template>

The app-* elements are from http://beta.webcomponents.org/ (a repository that people can upload pre-made webcomponents to, these ones are from polymer, which you can use without polymer in your own stuff if you want, it just exposes normal html5 webcomponent interfacing). The phoenix-* elements I made (mostly data elements, they display nothing).

But for example, the <app-route ... I bind basePath into its pattern (one-way, to it, that is the [[variableName]] part) and match out the path after it, which it and other stuff is put in the data variable of moduleRouteData ({{variableName}} is two-way binding, I.E. it can be set ā€˜fromā€™ the element), which I use later.

The phoenix-socket I built, just a dead simple way to do binding, it auto-disconnects/joins channels that are specified (which you can enable/disable with the connect property, etcā€¦). You can listen for messages and either have the latest stored into a variable or have it appended to a list to keep all (this example only shows latest, but appended is just as easy). Can send messages (though that is not shown in this example) and listen to responses to store in the same way, etcā€¦

Basically a lot of easy data-binding, the javascript side of it is fairly small too. What this does is a SPA with a header and such (this is my testing route) that dynamically loads in or out elements based on what the server tells it to load for its view (it tells it to fetch more webcomponent data from the server if it needs, or does not if it already has it, etcā€¦).

And yes, inside a webcomponent can be whatever library you want, there are react bindings, elm, vanilla javascript is fine, etcā€¦ etcā€¦ You are just defining your own elements is all. :slight_smile:

2 Likes

Iā€™m very late to this thread, but I thought that I would add a few bits of info that I donā€™t think have been mentioned yet.

  • Meteor apps are client rendered whereas Phoenix apps will often be server rendered.
  • If you want client rendering with Phoenix, you use Phoenix to develop your API and then pipe that to your JS client.
  • With Meteor your database will by default be Mongo. Thatā€™s great if you want Mongo. Not great if you want SQL.
  • Meteorā€™s Mongo functionality is simple to use and very powerful. From the client you simply start writing to your Mongo database, no REST API layer required. Itā€™s almost that easy.
  • Iā€™m finding my productivity with Meteor/React/Mongo to be excellent compared to using Phoenix/Mongo
  • Iā€™m using Meteor for prototype development to sell an idea of mine. If I later need to switch out the backend to Erlang/Elixir/Phoenix to get the performance I need, Iā€™ll probably end up having to start from scratch.
2 Likes