
Hoodie: very fast web app development - bpierre
http://hood.ie
======
Lazare
Unlike a lot of comments here, I don't need to be sold on the concept. As luck
would have it, I am actively building an app that runs mostly in the browser
using CouchDB, Kanso, and PouchDB. It's a pretty amazing tech stack; I get a
local DB in the browser, which I can sync with the main DB in the cloud the
client is connected. Plus I get some nice APIs for stuff like sessions,
registering users, security, validation, etc.

I see you've already mentioned switching to PouchDB on your backend, and
you're already using CouchDB for the cloud, so it seems like you're basically
competing straight up against Kanso. So.... How is what you're doing different
from what Kanso does? Why should I use Hoodie over Kanso?

I see this code in your docs:

    
    
        hoodie.account.signUp('joe@example.com', 'secret')
        hoodie.account.signIn('joe@example.com', 'secret')
    

Very nice. But Kanso has:

    
    
        users.create('testuser', 'testing', {roles: ['example']}, function (err){});
        session.login('testuser', 'testing', function (err, response){}});
        

Seems like six of one, half a dozen of the other. What's your killer feature?
Kanso has shaky documentation and is currently more aimed at couchapps (they
strongly assume that you'll serve your frontend code from CouchDB), but I'm
not sure how that really differs from Hoodie. :)

If we take the overall architecture as a given (browser based app, PouchDB or
equivalent for local storage, syncing with CouchDB in the cloud, and node
workers handling the backend work), what's the focus of Hoodie that sets it
apart from Kanso?

(In any case, nice stuff. I think the concept is great, and there's definitely
room for several competing frameworks in this space.)

~~~
lifeisstillgood
hi

I am trying very hard not to be dumb, but this is beating me

seemingly Kanso? and Hoodie both have JS stubs at the client and server end,
these synch with each other, then synch with whatever you are using at client
(say backbone) and server (node? CouchDB? My Postgres server behind my python
app?)

If thats roughly right, why do I do this? I control my server apps no? Why
wrap them in another layer? Json->backbone is hardly a difficult synch
operation - I mean its called synch().

I really am interested in understanding the philosophy and driving ideas here
- everyone has a moment of clarity where they can see how to build an app or a
framework, and how it will come together - I am not attacking you (yet !) -
please describe your moment of clarity.

~~~
Lazare
Okay, first off, let's discuss a standard three tier webapp architecture:

    
    
        Browser   <--->   Server   <--->   DB
    

You get some HTML/CSS/JS from the server, you display stuff to the user. As
the user interacts with your app, HTTP requests hit your server which
processes them. As needed, the server will make requests to the DB, which will
reply with data, which then gets passed back to the browser. Everyone knows
how this stack works, I hope. :)

It's simple and it justs works. Almost every website you use works this way.
But for webapps, it's not always ideal. Let's discuss some of the issues:

First off, this architecture is "always online". If the browser loses
connection to the server, then when your user clicks on a button nothing will
happen. Not too bad in a desktop environment, but with laptops or - especially
- mobile clients this isn't ideal.

Worse, what if you're trying to keep the state in sync with multiple clients
(like Trello does)? You're probably using websockets or long polling or
similar techniques so that the server can tell clients about the actions of
other clients. A network hiccup might cause you to miss one of these updates;
detecting and recovering from this sort of sync error is problematic.
Generally the solution is to throw away the last few bits of work the user
did, and force a full reload and re-fetch the current state. Which is fine, in
most cases. Unless the work the user is difficult to replicate, or if the
application state is quite large. Trello takes a second or two to grab the
current cards; if your app takes 30s to grab its data, you may want to avoid
this though. :)

In fact, the more you want to replicate the feel and functionality of a
classic desktop app, while allowing multiple users and clients, the more you
start to struggle against this architecture.

What other architectures are there? Well, there's one obvious one:

    
    
        Browser   <--->   CouchDB   <--->   Workers
    

CouchDB is kind of unique among databases because it speaks HTTP natively. It
can serve your app to the client, and then turn around and have the clients
connect directly to it. It can't, eg, send emails, but what you can do is use
CouchDB as a queue. Add a document that says "send an email to X", then you
spin up some worker processes that monitor it and process any documents like
that as they appear.

CouchDB also has a _changes feed that makes a lot of sync tasks very easy. It
also does master/master replication, and is generally a really nice database
to work with from a devops point of view. Still, we're missing a crucial bit
of magic to really improve over a classic three tier webapp. And that is...

...local DBs, in the form of PouchDB for browsers or TouchDB (apparently
called Couchbase Mobile these days, although confusingly it's unrelated to
Couchbase, which in turn is unrelated to CouchDB. Don't ask.) for Android/iOS.
CouchDB is really _really_ good at syncing and replicating, so now we have a
new architecture:

    
    
        Browser/Mobile App  <-->  PouchDB/TouchDB  <-->  CouchDB  <-->  Workers
    

This isn't appropriate for every task. For one thing, it's quite a lot more
work to implement (partly due to inferior tooling which projects like Hoodie
are, thankfully, addressing). But if you really want the best possible user
experience, you want it to work even if your on an airplane or in a tunnel,
you want a really snappy UI, you want each client to see the changes made by
other clients in as close to real time as practical, you want a consistent
experience for native mobile apps and webapps running in a browser...then this
is the architecture for you.

So to directly answer your questions:

First, Kanso (by default) wants to do something like:

    
    
       Browser  <-->  CouchDB
    

Which is a really slick, really easy way to do single page applications that
don't need local persistence or server processes. But it's not hard to add
them on, in which case you have the architecture above. You seem to be
imagining something like this:

    
    
       Hoodie Client  <-->  Hoodie Server <-->  CouchDB
    

But that's not the idea at all. You're also asking why not do this:

    
    
      Backbone  <--->  Python   <--->  Postgres
    

And that's a perfectly fine architecture. It works, it's rock solid, and it's
easy to code. For many apps (maybe most) it's the best possible architecture
(well, I'd suggest Knockout over Backbone, but that's personal preference).

But for the project I'm working on right now, we decided that wasn't _quite_
good enough. :)

~~~
pjbrunet
If my phone has no signal I'd rather see an error message. I don't want the
app to pretend everything is fine when that's not the case. If I press
"Delete" in the app, don't pretend the thing is deleted if it's not really
deleted yet, that's deceptive. What if I take off on my boat and I press
"Send" and your app says "Sent!" but it's really not sent because now I've
left the coast--your app just lied to me.

~~~
Lazare
With all due respect, I think you're wrong.

If I'm writing an email in the Gmail app on Android, what I want when I hit
send is for the app to save the email locally, and then do its best to try and
deliver it. Ditto for, basically, every other app on the phone that talks to a
remote server. If I try and send a tweet, I want it to go "sure", and then be
able to go on about my business while it works in the background. (And, again,
that's how the actual twitter app works.)

And if I'm using some app that lets me take notes about a meeting or interview
and syncs them with the cloud, I sure as HELL want to be able to take those
notes _and_ save them locally, even if the cloud sync had to be delayed.
"Sorry Mr. CEO, but I can't seem to get wifi in this meeting room. Can we go
out on the balcony and you just run back over those last few points?"

Now, yeah, I need some way of checking to see if it has actually sent the
email or whatever. And if it fails, a notification that it has done so is not
amiss. Mobile apps, typically, already do this sort of thing. (For gmail for
android, you can check the outbox to look for unsent emails, and I believe
twitter for android will notify you if it fails to send a tweet.)

To the extent that you're just saying that the app needs to have a UI which
doesn't lie or surprise the user, then I agree wholeheartedly. If the user
cares whether or not the cloud has been updated, or the message has actually
been sent, don't lie and claim it has when it hasn't!

But if you're saying that as a general rule we need to _not_ handle network
sync stuff in the background, I think that's nuts. Nobody wants to sit there
with an email draft open hitting send every so often to see if the 3G signal
is good enough to talk to the mail server yet. Nor do we want to save a bunch
of emails as drafts when offline, then have to go open each one when we get
net access again and send them. (Come to that, in your model, could we even
save an email as a draft in gmail without net access? Remember, the drafts
folder is synced. Do we want the app to claim that a draft has been saved when
it's not accessible from your desktop gmail client? Isn't that another case of
"pretending we've saved a draft when it's not really saved"? If not, why not?)

TL;DR: Good UI that doesn't lie to the user is important. That's not a good
reason to cripple your apps functionality so it doesn't do anything you can
lie about.

~~~
pjbrunet
You think I'm wrong but you wholeheartedly agree? Funny. Every situation is
unique but bottom line: you can't receive content without a connection. Most
apps NEED a connection to function. So an error message "No Connection,
Retry?" is both common and expected behavior.

------
onemorepassword
Looks lovely, but I wish people would focus less on fast development and more
on something that better maintainability 2 years down the road.

When it comes to the lifecycle of most applications, the speed of developing
something new has a marginal impact on the overall costs, and most tools and
frameworks than enable rapid initial development tend to suck once you have a
big app on top of them. This is why we fawn over a tool when it's shiny and
new, and bitch about how much it sucks 3 to 5 years later.

~~~
wodow
> ... the speed of developing something new has a marginal impact on the
> overall costs

But it has a large impact on the overall probability of getting off the ground
at all - and this is what most projects (and people) never do.

~~~
gbog
> [dev speed has] a large impact on the overall probability of getting off the
> ground

I don't know. This seems common sense but it could be a cliché too.

If we look at other domains, it is not always true. For instance, if you write
novels that are not tied to some evanescent trend like a pop star's private
life, then the chance of getting off the ground if not directly linked to the
timing of publication. It would be the same if you are creating a newly
designed chair.

Even on the web, let's take two success stories: when Wikipedia or Twitter
were created and made public, I don't remember seeing five other contenders
running behind them, and being only two-features-months behind. Same with,
say, Minecraft.

I am all for quick development, because it is more fun, but not because it
would magically increase to probability of success, which is too low to
compute and unpredictable anyway.

I am also all for choosing carefully which path you take, especially when you
cross virgin territories. You don't want to find yourself spending a night
half naked with a toothpick for your sole defense in Borneo's jungle.

~~~
gr2m
Let's say today 1 of 1000 people is able to create an app to solve a problem,
let's say time time tracking. Now imagine we change that drastically, to 100
of 1000 or even more. People will start to build their own little apps to
solve their own little problems. And if these break, nobody cares, but them.

For example, friends of mine like to go climbing. They've build an app in an
afternoon, just for their group, to keep track of what tracks they finished
and how they liked it. I think this is fascinating. I wonder what would happen
if students would learn to build simple apps like that in school, instead of
Excel?

~~~
lkrubner
"Now imagine we change that drastically, to 100 of 1000 or even more. People
will start to build their own little apps to solve their own little problems.
And if these break, nobody cares, but them."

This was the old dream of Hypercard, and it worked very well for a long time.
<http://en.wikipedia.org/wiki/HyperCard>

Both Danny Goodman and Bill Atkinson have stated publicly that they got
programming questions from every kind of person: small business owners, school
teachers, ski bums, taxi drivers, etc.

Hypercard let non-programmers build simple apps, and so a lot of apps were
created that would never have been created if app-creation was left in the
hands of professional programmers. And many of those little apps were tailored
to what the creator needed at that moment, in a way that could never happen if
a professional programmer drew up some spec.

~~~
namdnay
It's ironic that the tool that has replaced Hypercard is in fact Excel. Excel
makes it amazingly easy for non-programmers to develop simple applications

------
danso
I haven't had time to look at try out the walkthrough, so here's a kind of
dumb question that wasn't answered explicitly in the docs: how does it work
with existing front-end frameworks, such as Backbone, Angular, Ember, etc?

I ask this because of the description found on the Github page:
<https://github.com/hoodiehq/hoodie.js>

    
    
       hoodie is a JavaScript library that runs in your browser.
       It gives you
    
          user authentication
          data storage and sync
          sharing
          emails
          and so much more
    

None of these things are really handled by the client-side frameworks
mentioned above, so I'm wondering if Hoodie is basically drop-in easy for
existing projects.

~~~
gr2m
at first, Hoodie is just a Store for data. So instead of Backbone, Angular etc
storing their data via AJAX on a server, or in LocalStorage, we can very
simply build adapters for all of the MV* frameworks to use Hoodie as their
store.

This way, you get accounts and data synchronization for free. And offline ;-)

Emails and other future modules like payments are just extensions of the
available JavaScript API in the browser.

~~~
lifeisstillgood
I have not read any more than the intro linked, but I am kind of "concerned"
by the big claims

    
    
      Behind the scenes, Hoodie takes care of account creation, 
      email validation and all the boring backend tasks you have 
      to think of.
    

yeah, but _how_. You still need to _do_ account creation, even if you are
storing the hoodie-account-object locally in some fashion.

Am I being dense, or is this like a nice client framework that still needs to
talk AJAX to the backend, so still needs to allow oAuth, so still needs to
change code if the API changes, and so on.

"We just want to make apps, and add billing by Monday" is a bit worrying as a
goal to me...

edit: oh, so this stubs out the server side at the client ? It seems like the
same amount of work to keep backbone models in synch with the server as it
does to keep hoodie? What do I gain?

~~~
janl
> yeah, but how.

Hoodie comes with a backend that does all that stuff that can only be sensibly
done server-side for you.

> edit: oh, so this stubs out the server side at the client ? It seems like
> the same amount of work to keep backbone models in synch with the server as
> it does to keep hoodie? What do I gain?

@gr2m can you take this one?

~~~
lifeisstillgood

      Hoodie comes with a backend that does all that stuff that 
      can only be sensibly done server-side for you.
    

wibble? I run your client and your server and talk to the stubs both ways?
Why? Sounds like Microsoft.

Edit: I take back the MS jab - unnecessary when simply trying to understand
something. My apologies

~~~
janl
Yeah, we are basically copying Microsoft.

Edit: No harm done :)

------
old-gregg
I have a question for experts in Hoodie and/or other similar projects (like
Meteor):

How are database connections managed? If every client (browser) basically
talks nearly directly to the database, don't you end up with of thousands of
database connections?

Large number of connections is not a problem by itself, and servers like nginx
handle them well, but I am not aware of a database which will feel comfortable
being exposed this way. MongoDB, for example, really starts struggling with
2K+ connections. PostgreSQL can barely handle a hundred.

Is this why CouchDB is used? Is connection pooling used on the server? Or
maybe the connections are short-lived and never persistent? Basically, how
does this work with large number (say, 10K) of concurrent visitors?

Thanks!

~~~
janl
As long as the underlying OS can provide file descriptors, CouchDB can handle
the concurrent connections through the magic of Erlang, both persistent and
shorter lived.

There are obvious limits to this, but the Hoodie architecture allows easy
scale out (more DB servers and manual sharding, or a dynamo-like BigCouch,
more workers etc.) that we’ll get to making use of once Hoodie apps become
that big.

~~~
tarabukka
Magic of Erlang? I hate to be cynical, but have you got benchmarks to back
that up?

~~~
janl
Yeah.

------
tempaccount9473
Neat, I really like the idea of being able to sync local storage with a Couch
backend.

> Hoodie currently only runs on OS X

Oh, a hipster framework.

~~~
janl
> Oh, a hipster framework.

Never attribute to hipsterism what could adequately be explained with picking
priorities :)

The hoodie backend works anywhere node and Couch work (anywhere, really), it’s
just that the local dev setup with the fancy domains and everything is
tailored to Mac OS X. We have Linux support in the works.

~~~
mserdarsanli
Yeah, a hipster framework.

~~~
monkeynotes
I'd say OSX is pretty mainstream for web development in my experience. If
Hoodie was only available for the Atari ST then perhaps it would be a hipster
framework.

------
janl
Hey there, other @hoodiehq dev here. Here is a bit longer intro to Hoodie:
<http://hood.ie/intro.html>

And a presentation from earlier at @berlinjs including a live demo:
<https://www.youtube.com/watch?v=X3Ttb0BD8pg>

~~~
jufo
Nice presentation. In the description of back end modules, you mention
payments as a future capability. What kind of payment service would you be
able to work with? (I don't see how you could handle card details in the
Hoodie architecture). Thanks.

~~~
gr2m
we definitely won't send any credit card information to a hoodie server.
Instead we use a service like stripe, but then receive the payment
notifications or errors, which lets us notify the user if payment worked or
not.

------
eranation
Self hosted Firebase, nice!

How do you handle permissions by the way? is it the same concept as
Firebase's? how do you handle data validation? (e.g. preventing users gaming
the data, e.g. saving all their stolen ebooks in your system by using a
console, or just cheating in a game by doing illegal moves?)

~~~
gr2m
permissions is handled directly by CouchDB. Every user has an own database
that only he/she has access to. Synchronization between accounts can be done
via shares.

We don't have validation at the moment. You can store whatever you like, it's
just JSON. We could add validation at some point, but it's currently not on
our agenda.

We try to keep it really simple at the moment, getting the core right, then
empowering others to build modules on top of it.

------
beefsack
I'm a Unix developer and would love to have a play, a little bit disheartening
to see that the installation instructions are OS X exclusive.

~~~
janl
I’m a Unix dev too, check out my beard in the linked video :D

Like mentioned elsewhere in this thread, other *nixen support is in the works.
Hoodie core is platform agnostic, we just chose Mac as the dev environment
because we figured that was what most people use. We are definitely not
exclusive and would love to see any help towards getting it run on other
systems :)

------
ZenJosh
This looks pretty optimal for a little app I'm building. I've been bolting
bits to Sinatra and using it as a half-API-half-template engine for a frontend
I built, this looks far cleaner. I'm curious about security though, what's
stopping a user from plugging in random data via the console?

~~~
janl
Nothing, all they can do is fuck up their own data.

~~~
alexaasp
Which sounds kind of bad, if that is the case.

1\. Even if the users are idiots you shouldn't let them ruin their own
application experience. 2\. I would never put anything remotely connected to
security and user privileges in the same storage accessible by users, so I
would have to set up a separate service.

~~~
janl
1\. what if that idiot messes with gmail’s web console?

2\. Security handling is purely server-side. You can’t fake your way without
using a proper auth-channel.

~~~
alexaasp
The distinction here is that Hoodie is supposed to free you from dealing with
servers, but that is currently limited to scenarios where you have users with
uniform access privileges and no concerns about users messing around with
their database information. So until they add modules most projects will have
to get down and dirty in the end if they want to attach any kind of privileges
to users. In both points 1 and 2 you need to have some server side logic
beyond Hoodie.

~~~
janl
Hoodie can only promise to free you from worrying about the backend by
providing one that you can just use.

The sharing module e.g. makes heavy use of server side logic and database
security and access control features. The Hoodie frontend just makes it
accessible to frontend devs.

------
hayksaakian
It's odd that no one's mentioned it yet, but this reminds me most of Meteor.

How does this compare to, say, Meteor?

~~~
gr2m
hood.ie has a different approach. Meteor brings backend logic to the frontend.
hood.ie tries to hide the backend entirely and provide an API that feels
natural for the frontend environment.

The JavaScript API is what we care about most. We do currently have the
hood.ie backend implemented in Node/CouchDB, but it could be everything,
really. The frontend developer doesn't care.

~~~
janl
We love Meteor though :)

------
m_mueller
Berlin and Zurich seem to be doing great lately. I'm also planning on building
a startup in Zurich in the coming months. How about a Hacker News Zurich
meetup?

~~~
thomas11
Would be cool. We had one over a year ago, and the attendance was good, but no
one organized a follow-up.

See <http://techup.ch> and meetup.com for what's going on in the tech meetup
space in Zurich. I'm often at zhgeeks, jszurich, web tuesday.

------
dylanz
It's awesome when you read posts on HN about interesting things and realize
your friends were involved. Congrats gr2m! (P.S... +1 for an Angular adapter
=))

~~~
gr2m
10 cary-minutes is all it takes ;-) Thanks Dylan

------
taybin
I think promising "we want to enable you to build complete web apps in days"
might be promising too much. Programming is difficult, there is no silver
bullet, and a different data store certainly won't change that.

Interesting choice of couchdb. Any reasons for that compared to the
alternatives?

~~~
ConstantineXVI
If I had to guess, the fact that HTTP and JSON are CouchDB's native tongue
(removing the need for a middleman in front of the DB) was likely a factor.

~~~
janl
That, and that CouchDB has Sync already figured out. Hoodie didn’t have to
invent this. Sync is hard, leave it to the experts.

------
bsaul
@hoodiehq : are you using something similar to PouchDB ?

~~~
janl
We have our own little lightweight version of PouchDB that isn’t really a
version of PouchDB. It works well for now, but we might migrate to Pouch
later.

~~~
daleharvey
Yeh we should definitely work on this when you are in town :) the storage part
of pouch is nearing being complete and stable, the server infrastructure was
next on the list (after docs etc)

~~~
gr2m
<3

------
d0m
I know everyone hates that question.. (I hate it too), but what about non-js
users or, maybe more importantly, SEO or crawlers? Honestly, this is what is
holding me back to go pure client-side for most of my projects.. I know
there's the phantomJS server-side hack but how does that work in practice?

Also, something else that really trouble me with javascript client-side is
that, often, when something bugs, _everything_ just stop working. I.e. links
don't work anymore, button obviously don't.. Is there a better solution than a
hard-refresh? Would a first-level try/catch solve this problem?

Thanks!

~~~
verbalist
> non-js users

the web is no longer just text. if you need to consume text then you need a
text-api client, which is what web browsers used to be.

~~~
eevee
I run noscript. If I encounter a site that's broken or useless for seemingly
no reason (e.g. not an interactive thing like Google Maps), I often don't even
whitelist; I just leave. Relatedly, I've stopped clicking on Photobucket or
Blogspot links.

I kinda resent being expected to run your pile of arbitrary code just to
render static text and images on my screen—something that worked just fine
without JS twenty years ago.

~~~
andybak
While I admire your principled stand - you are in a dwindling minority so
there isn't much reason to factor in people such as yourself when making
technical decisions.

The SEO issue is a stronger argument but Googlebot now seems to be executing
javascript in some cases so even that might cease to be an issue.

~~~
eevee
It's not just people like myself; it's people writing one-off scrapers, people
writing new search engines or browsers (Google is not the entire universe),
_everyone_ when you forget a brace and break all of your JS, etc. The Web is
not and has never been merely human beings sitting at a keyboard and using one
of three known GUI browsers.

------
akrymski
so bots can sign up easily:

while (true) { hoodie.account.signUp(_.uniqueId() + '@gmail.com',
_.uniqueId()) }

great effort though, but I still don't think you've got client/server
separation right.

we've built something very similar over a year ago: an offline client db
backed by memory/websql/indexed-db that replicates with dynamo-db so the app
works offline. Looked at Couch/Pouch solution but decided against Couch for
performance reasons.

Might open source it later once we figure out the user management/security
bit. I still find the existing solutions (including Firebase) not ideal.

~~~
Mahn
I was thinking there might be some sort of throttling/banning mechanism within
the signUp function itself, but then being client based that could be easily
circumvented unless there's some server side logic aswell. I wonder whether
there's a sane way to handle this client side short of minify and/or obfuscate
the code and hope for the best.

~~~
espylaub
Let me refer to a great answer Lazare gave further up (more generally about
sync, but very useful nonetheless):
<https://news.ycombinator.com/item?id=5517632>

------
vosper
Apologies for an off-topic question - how did you go about registering a .ie
domain name? I've been wanting to register one for a while, but the last time
I looked there was a requirement to show proof of residency (or a business
address) in Ireland.

Edit: The reason I ask is that it seems like the developers are living in
Zurich and Berlin, not Ireland. I live in SF, so can't fulfil the residency
requirement.

~~~
espylaub
No problem :) There are actually more than three of us working on Hoodie, one
(actually two by now) of them an Irish national. The about section just lists
the core team, if you will.

~~~
vosper
That makes sense. I guess I will just have to go without until they
(eventually?) open up registration to foreigners! Thanks for taking the time
to reply.

------
janl
Alright, Team Hoodie is calling it a day. Thanks for the lively discussion and
nice feedback, you’ve been great! :)

See you again tomorrow CEST. <3

------
cupofjoakim
I'm very interested in using this together with emberjs, but honestly I'm
having trouble understanding what Hoodie actually does. Why do I need Hoodie
to go with my CouchDB? Is it only for the local storage?

------
donjaime_hn
Very cool :).

A few questions. What is the strategy is for concurrent modification of data?
What are the consistency guarantees for the sync operation?

~~~
gr2m
In the current implementation, CouchDB takes care of it. In case of a
conflict, both versions are kept, with one winner. The other version can be
recovered and the conflict resolved, both automatically with a worker process
or by the user.

------
dannyp32
As a new web developer I'm very interested in this. Looks like a not so
complex next step after building basic static websites.

~~~
gr2m
Welcome to Hoodie world :-)

------
fnayr
definitely going to check this out in depth soon, and build some "dreamcode"
with it to test it out!

~~~
janl
That’s the Hoodie Spirit <3 :D

------
je42
How is hoodie solving / handling conflicts when its syncing local storage to
the remote database ?

------
treblig
Test comment for <http://hackerfollow.com>

------
mikhuang
Hoodie devs: Just out of curiosity, what frontend framework (if any) is used
on minutes.io?

~~~
gr2m
backbone

------
laurentoget
How does this compare with Firebase, besides offering a way to host everything
locally?

------
bencollier49
Does "hoodie" mean "juvenile delinquent" in the US as well as the UK?

~~~
bct
No.

------
gdonelli
All art requires courage. ~Anne Tucker

