Skip to content

Latest commit

 

History

History
113 lines (67 loc) · 3.76 KB

README.md

File metadata and controls

113 lines (67 loc) · 3.76 KB

JFramework: Rapid prototyping for Meteor + React

Play with our 97-line example app using the sandbox on MeteorPad: http://meteorpad.com/fork/mC4wQPmJNpWBqvXZ2

Cut through the CRUD

How would you like to build a web app with no boilerplate code at all?

JFramework gives you these rapid prototyping features:

1. Full reactivity everywhere, powered by Meteor's Tracker

  • J.List is a reactive Array
  • J.Dict is a reactive Object
  • J.Component wraps a React component to add support for reactive field values, and seamlessly turn your render function into a Meteor-style reactive computation

For example: If your J.Component has a state variable called books, you'd normally have to update it like this:

this.setState({books: this.state.books.concat([anotherBook])};

Or like this:

this.state.books.push(anotherBook);
this.forceUpdate();

With JFramework, you can just say this:

this.books().push(anotherBook);

Since this.books() is a reactive getter for this.state.books, whose type is J.List, JFramework tracks all dependencies related to this push operation. Your component will then re-render if and only if it needs to rerender.

2. "Synchronous" client-side access to your whole database... seriously!

JFramework lets you write synchronous-style fetch statements in your components, like this:

J.defineComponent 'BooksPage',
    state:
        limit:
            default: 10

    render: ->
        $$ ('ul'),
            {}

            $$.Book.fetch(
                {}
                limit: @limit()
            ).map (book) =>
                author = $$.Author.fetchOne book.authorId()

                $$ ('li'),
                    {}
                    ("#{book.title()} by #{author.name()}")

JFramework then executes your synchronous-style fetch statements asynchronously. And it even bulks your fetchOne queries together into fetch queries. Which is sweet!

We used to think it was logically impossible to make a framework do this, given the single-threadedness of client-side JavaScript. But we were wrong.

3. Reactive URL paths and query strings

J.Routable is a mixin that makes your page URL reactive to the state of your top-level J.Component, like this:

J.defineRouter ->
    $$ (ReactRouter.Route),
        name: 'books'
        handler: J.components.BooksPage

J.defineComponent 'BooksPage',
    mixins: [J.Routable]

    state:
        limit:
            default: 10
        showAuthor:
            default: false

    reactives:
        route:
            val: ->
                query:
                    limit: @limit()
                    authors: if @showAuthors() then '1'

Now when you visit /books, the URL instantly changes to /books?limit=10. Then if at some point you change your component's state by calling @showAuthors true, the URL will reactively change to /books?limit=10&showAuthors=1.

Normally, it sucks to spend time wrangling with your URLs. But with JFramework, it's actually fun.

Watch this 5-minute demo

See how JFramework lets you create a web app with no boilerplate code at all.

JFramework demo video (5:12)

Examples

BooksDemo

The 97-line project from the video.

LastBreath

A social network for people with 1% battery life. Relies on the HTML5 battery API, so only works on Chrome for desktop and Chrome for Android.