I’m at a computer lab [probably the one from college] and have written an entire email client app in a day. I’m excitedly showing it off to everyone. It’s kind of glitchy but I can pull up my real emails, including spam.

The app is also, simultaneously, made out of a 2-liter soda bottle. It starts out crushed, and expands and fills with water as it launches. Unfortunately there are some cracks that water squirts out of. I explain that I am going to patch them soon.

People are pretty impressed that I wrote this in a day, but I point to some fat binders lying on the desk and tell them that I have a bunch of libraries I wrote earlier that helped me build the app.

(Inspirations: Obviously there’s the social network app I want to write that I posted about a few days ago. A friend asked me yesterday how it was coming. Also yesterday, Jed in fact wrote a pretty decent Tetris game in one day on the iMac. Plus, obvious visual pun about “memory leaks”. And I’m increasingly frustrated with the poor quality of Apple’s Mail app on 10.9 and wouldn’t mind a replacement, though I’m not really going to write my own.)

Modeling a social networking system like LiveJournal or Facebook in a JSON-document-oriented database like Couchbase [Lite] or CouchDB isn’t hard. Here’s a basic schema that I’ve been playing with for a while.


Top level items are document types (generally distinguished by a reserved type field), nested items are properties.

  • Persona
    • nickname
    • Full name (optional)
    • userpic (optional)
    • bio (optional)
  • Relation
    • author ID
    • target persona ID
    • relation types (one or more of: follows, friend, …)
  • Post
    • author ID
    • date created
    • date updated (only if edited)
    • privacy (public / friends-only / …)
    • body
    • post type (text / quote / picture / audio…)
    • media attachments (optional depending on post type)
  • Comment
    • author ID
    • post ID
    • date created
    • body


Properties that say “ID” contain the ID of the target document (much like a SQL foreign key.) “Author ID” specifically means the ID of the Persona who created/owns the document.

Documents can only be created or updated by the user listed in the ‘author ID’ property (or the doc ID in the case of a Persona.)

Note that this means that relations are one-directional and always point outward: you specify how you relate to someone. Some relationship types are intrinsically bi-directional, like “friend” or “sibling”, and have to be declared in both directions to be considered valid.

I’ve been using the XFN schema as a source of relationship types. It contains a ridiculous number; these might be appropriate for something like Facebook, but for a more casual system like tumblr or Twitter the only one you really need is “follows”.

“Body” properties should probably be tagged with a markup type to distinguish between formats like plain text, Markdown, HTML, and bloggy-HTML (i.e. with hard linebreaks.)

The “post type” is mostly a hint to trigger different visual styling of the post, a la tumblr and other tumble-logs.

“Media attachments” would be, literally, attachments in Couchbase Lite or CouchDB. Other databases might need to use URLs instead and host the media externally.

A “like” / “heart” / “+1” can be treated as a comment with no body.

If you generalize the comment “post ID” property to be able to point to things other than posts, you can easily get hierarchical/threaded comments (comment-on-comment) or “wall” posts (comment-on-persona).

If posts can be non-public, the server needs to limit access to them. Specifically, a “friends-only” type of post should be readable only by people that the post’s author has the right kind of published relationship to, and obviously a “private” post can only be read by its author. (This is basically infeasible with CouchDB, which doesn’t support per-document read access control. The Couchbase Sync Gateway does support it.)


Comment free-for-all: In this model anyone can comment on any post just by publishing a comment targeted at it. There are obvious social problems with that. A workaround is to have the post itself contain an array of “approved comment” IDs; this requires that the post author or her software moderate comments and update the post to add new ones. The UI would generally only display the comments in that list.

Replication/P2P: This schema will suffice in a centralized system where the server can enforce authenticity and limit the visibility of non-public posts. Once you add replication, things get trickier. Authenticating a document requiress that it be signed by its author, which in turn means a Persona document needs to contain a certificate or a public key, which in turn requires some mechanism (a PKI) for so you can verify that a Persona refers to the person you think it does. Also, non-public posts will require encryption if they’re ever to be replicated through intermediary servers that don’t have read access to them.

Here’s my most recent music mix, “Forest Wire”, all music from 2013. This mix is dedicated to my brother-in-law who builds guitars but nonetheless appreciates electronic music. It starts and ends ambient, but builds up into dub and K-pop and jungle and other styles.

Track listing:

  1. How To Disappear Completely — “Until The Night Burns Out”
  2. Lamont Kohner — “WD2”
  3. Braids — “Amends”
  4. Jon Hopkins — “Open Eye Signal”
  5. Anamanaguchi — “Endless Fantasy”
  6. Lusine — “Lucky”
  7. 2ne1 — “I Am the Best”
  8. Zomby — “It’s Time”
  9. Special Request — “Lockjaw”
  10. AlunaGeorge — “You Know You Like It”
  11. Yosi Horikawa — “Bubbles”
  12. Ethernet — “Current (Etbonz remix)”
  13. Tettix — “The Arid Plains”
  14. DFRNT — “Boreal”
  15. Ekca Liena — “Mattie Devore [edit]”

Couchbase Lite

(Née TouchDB, née Couchbase Mobile) Mobile syncable NoSQL database for iOS. My work project in one way or another since I started at Couchbase in mid-2011. I’m still having fun working on it.

Couchbase Sync Gateway

The companion piece – the glue that lets Couchbase Lite sync with Couchbase Server. It’s been challenging and educational and boundary-stretching, and part of me is sick of working on it because the secret is I’m not a big-data guy. I’ve known for years that I like working on apps better than on servers. But this project had to be done, and I think I’ve done a good job of it and learned a lot.


The font preview/management tool I mentioned a few days ago. I had an itch so eventually I gave in and scratched it. Hopefully I can get the app wrapped up soon and put it in the App Store – that’ll be a first for me.


Mixup is an audio app I’ve been working on intermittently since 2005(!) It’s gone through several iterations of audio APIs – QTKit, AudioUnits, now AVFoundation. I use it to make my mixes, but it never gets quite solid enough to think about releasing. Maybe I’ll focus on it again soon and fix the latest crop of bugs…


  • Despite my best efforts I managed to accumulate another piece of unneeded music gear in 2013: a tiny and ultra-cute Korg Volca analog synth.
  • I’ve been dinking around with Jekyll and HPSTR and LESS to bring this blog to life.
  • I’ve got a short story in my brain that really needs to be written down. It’s been too long since I’ve done any writing.
  • I’ve made a couple of mixes that aren’t up on the website yet; I’ll get those uploaded soon.

I’m looking for some more beta testers for a font preview/management utility I’m working on. I’ve been frustrated by not having a good visual way to browse my font library, so I wrote my own. It’s called Jackdaw.

If you have a sizable font collection, choose (or just ogle) fonts on a regular basis, are willing and able to send bug reports/crash logs/suggestions, and are running OS X 10.8 or 10.9 … then you should totally sign up. (Bonus points if you recognize the reason for the app name!) Testers who send useful feedback will get a free license for the finished app.

If you’re interested, send me an email at “thought-palace” @ this domain.