Djangocon Debrief

big_shouldersLast week I went to djangocon.us, the annual conference where Django fans from around the world congregate to toast the web framework we use for most of our web applications at Mozilla (by way of Playdoh). The conference was held in Chicago, “the city of the big shoulders“. I was joined there by the creator of Django, several leaders from the Django Software Foundation, several Mozillians, and lots of excellent developers from around the hemisphere. Some highlights below:

Test Driven Development
On the first day I attended a half-day tutorial about Test-Driven Development in Django taught by Harry Percival, who’s written a book on the subject. It was excellent. In addition to giving me some practice building a Hello World application in Django, the tutorial also taught some great techniques for turning user stories into code by way of functional tests (using selenium) and unit tests (using django’s built in test runner). Key takeaways for me:

  • Test driven development is not necessarily slower than the alternative, and is also kind of fun once you get in the groove.
  • TDD helps document progress; it can significantly ease the context-switching pain of leaving a project and returning to it later.
  • Unit tests are only half of a solid TDD approach. The other half is functional testing, which happens in a simulated user environment (i.e. in Firefox).
  • Basic functional testing is straightforward to implement with selenium. Using selenium would give Mozilla developers increased ability to manage and contribute test coverage that we currently depend on an overtaxed WebQA team for. It might be worthwhile to try it on a project sometime.

A pre-release version of Harry’s TDD book is available online for free.

Client Side Frameworks
There were two presentations about client-side frameworks — Angular.js and Ember.js. These frameworks enable developers to move substantial chunks of an application’s logic onto the client device. Naturally, each speaker was confident that the framework he was presenting was the best one. Their important differences were not clear to me from the presentations, and this area of web development is positively frothing with alternatives. What was clear is that the Django community is eager to learn about and use client-side frameworks; some developers are even asking for official guidance or standardization from the DSF. We may end up using one of these frameworks on reps.mozilla.org in 2014.

DSF Updates
The president of the Django Software Foundation gave a glimpse into the next year of Django’s evolution. Because the framework is moving to an accelerated release schedule, the foundation is considering a long-term support option; this might mean that Django 1.4 will get security releases for longer than we currently expect. The DSF is eager to secure Django’s longevity; to that end they’re asking fans of the framework to promote it, they’re asking for corporate sponsors to support it, they’re looking for new code contributors to bring more modern framework features in, and they’re materially supporting local and regional events about Django.

Of course there were plenty of other talks. I got fired up about Docker, thinking about how it might make things easier for Mozilla’s contributors. And I was glad to hear about powerful core migrations, since they seem like such a fundamental framework feature.

And one of my favorite parts of any conference is exploring a new place with new people. I met folks from Argentina, France and Canada; enjoyed Chicago’s fine IPAs with freelancers and core committers; and led a very large, very hungry group of hackers on a fruitless search for a good bacon cheeseburger (not recommended).

This conference was, for me, a great opportunity to very quickly encounter the people, projects, culture and questions that make Django what it is. While organizers freely admitted that Django is not the newest, hippest web framework available, they stood by its proven capability and pragmatic utility. They also demonstrated a collaborative, creative and accepting open-source culture that distinguishes Django among web frameworks. Within the community there seems to be plenty of shared enthusiasm for keeping Django relevant for years to come.

One highlight unrelated to the conference: I jogged out to the end of Navy Pier one morning in my Mozilla Webprod t-shirt. A bicyclist approaching from behind turned to look at me and asked (with a note of wonder), “Do you really work for Mozilla? That is so cool!

I think so too.

Djangocon Debrief

Baby Sleeper Plans

bottomI promised last year to post the plans that I made when I built the baby sleeper that our baby slept on for the first six months of her life. Here they are! I made them in SketchUp, but WordPress.com doesn’t allow me to attach .skp files here so I’ve attached pictures instead.

This baby sleeper is designed to satisfy a handful of important requirements:

  1. It should fit commercially-available baby mattresses. We found a great organic mattress here sized 15″ x 35″, so that’s the size of this sleeper’s platform.
  2. It must prevent the baby from rolling off the sleeper onto the floor. So it has high walls on 3 sides.
  3. It should put the baby at the same height as her parents — the top of her mattress should be even with the top of the adult mattress.
  4. It must keep the baby mattress and the adult mattress right next to each other, touching. Any gap between the mattresses can be quite dangerous!

Adult beds come in all sizes and designs. We have a platform bed, and these plans are for our bed. Unless you have the exact bed we have, you will probably  need to modify this design. If your bed has a nice fat lip next to the mattress, one edge of the sleeper can rest on the lip. If your bed has a box spring, you will probably want to incorporate some flat slats of wood to go between your mattress and your box spring to help support the sleeper on the front. On the rear are legs that rest on the floor.

Construction details:

  • I made the entire sleeper box, platform and walls from scrap plywood. Every joint is glued. I used assorted deck screws from a pile on my workbench to pull the joints tight.
  • I made the legs from electrical conduit with a conduit socket threaded into a plumbing fixture attaching the legs to the the sleeper (see picture above). I wrapped the bottoms of the legs with an old bike tube to protect the floor. I added some felt pads to the front supporting edge, which sits on the lip of the platform bed.
  • I sanded the sleeper very smooth first with sandpaper and then with steel wool. I filled in big gaps with wood patch. I finished the sleeper with several coats of a tung oil finish, well rubbed. I let the finished sleeper off-gas in the sun and wind for several weeks.
  • In the photo above you will see some holes I drilled in the bottom of the sleeper: These are for stout rope which I used to tightly bind the sleeper to the lip of our platform bed. The photo below shows how tight a fit it was.

attached to bed

Here are some general instructions that may help adapt these plans to another bed:

  1. Measure from the floor to the top of your mattress. In our case it was 15 7/8″.
  2. Subtract from that measurement the height of the baby mattress you bought (for us it was 1 1/2″). The resulting number is the height that the platform must be off the ground. In our case it was 14 3/8″.
  3. Measure from the lip of your bed, or from the top of the box spring, to the top of your mattress.
  4. Subtract from that measurement the height of the baby mattress you bought. The resulting number is the distance between the platform and the bottom of your front edge support. The front edge support is either the box that rests on the lip of your bed, or the slats that slide between your mattress and your box spring. In the drawings below this is 4″ plus the thickness of the platform board (5/8″) and the thickness of the board at the bottom of the box (5/8″), or 5 1/4″.
  5. Measure from your front edge support (the lip of your bed or the top of your box spring) to the ground. The resulting number is the height that your sleeper’s legs will be, minus the thickness of any supporting materials. In our case the legs were 8 1/2″ after I subtracted the thickness of the extra support plank running along the rear edge.

This sleeper was a great way to keep our baby very close at night without putting her in bed with us.

Our baby enjoyed the baby sleeper that I built from these plans, but I cannot guarantee that you or your baby will. By viewing these plans you agree to accept all responsibility for any outcome resulting from your use of them; you agree that your family’s well-being is entirely beyond the control of any party involved in the creation or publication of these plans and instructions; you signal your understanding that these plans are provided here as-is with no warranty and are shared under a Creative Commons BY-SA 3.0 license. If you cannot agree to these terms and you want a great baby sleeper, buy one.

plan-sideplan-front

Baby Sleeper Plans

Release management with Semantic MediaWiki

I did some wiki markup hacking today to make the release management process for Mozillians.org just a tiny bit easier.

Mozilla uses Semantic MediaWiki for its public wiki. Everyone affectionately calls this instance wikimo. Semantic MediaWiki is a powerful tool, and is kind of fun if you think adventures in extreme punctuation are fun. (I do!)

Part of my job is to communicate about web development projects to various stakeholders, and the wiki is one tool I use to accomplish that. I use it to publish project plans — it’s great for those. I also use it to keep track of meetings and product releases, and it’s kind of annoying for those.

wikimo

These kinds of content — meetings and product releases — follow a familiar pattern: An ordered list of content items links to each individual item, and each individual item uses the same layout as the other items. When a new item appears, the list gets longer. Just like a blog, in fact.

But, to date, maintaining this content has meant creating a new page for a new content item, and putting the right markup into it for that content item, including a few variables, and then editing the page where the list is to add another item to the list. Like I said, it’s kind of annoying.

I’d really like to have a link, and when I click on the link I would get a form to enter my variables. Submitting the form would create the new content item, update the list, and I could move on. Enter Semantic MediaWiki’s templates, forms, and queries!

1) As soon as you start talking about variables in any content system, you also start talking about templates. Semantic MediaWiki lets you build templates for wiki content. Here’s the one I built:

<noinclude>Edit the page to see the template text.</noinclude>
<includeonly>
==Features landing in this release==
<bugzilla>
{
"component": "Phonebook",
"product": "Community Tools",
"target_milestone": "[[Milestone::{{{Milestone}}}|{{{Milestone}}}]]"
}
</bugzilla>
[[Release-list::Mozillians| ]]
</includeonly>

view raw
wikimo template
hosted with ❤ by GitHub

This template puts some explanatory text on the page (“Features landing…”) using wiki markup, and the sky is the limit on that. But more importantly it uses wikimo’s very own bugzilla plugin to drop some bugzilla bugs into the page in a nice tabular format, and it also makes this release page known to the page that lists releases. It uses two user-defined properties to accomplish that:

  • A Milestone property, which should correspond to the values of Bugzilla’s target milestone field — in this case, it’ll be something like “2013-09-26”, because our target milestones are all ISO Thursdays.
  • A Release-list property that contains the value, “Mozillians”. This is what our list of releases will be looking for in order to list releases.

If you visit the template you’ll just see the content in the <noinclude> block. You actually have to visit a page using the template to see what it outputs.

2) Semantic MediaWiki’s templates are not form-powered without the Semantic Forms extension. It’s installed on wikimo, luckily. Here’s the form I built:

<noinclude>Edit the page to see the form markup.</noinclude>
<includeonly>
{{{info|page name=<Mozillians Release[Milestone]>}}}
<div id="wikiPreview" style="display: none; padding-bottom: 25px; margin-bottom: 25px; border-bottom: 1px solid #AAAAAA;"></div>
{{{for template|Mozillians Release}}}
{| class="formtable"
! Milestone:
| {{{field|Milestone|mandatory|default=2013-02-07|input type=text|size=10}}}
|}
{{{end template}}}
{{{standard input|save}}} {{{standard input|preview}}} {{{standard input|changes}}} {{{standard input|cancel}}}
</includeonly>

view raw
wikimo form
hosted with ❤ by GitHub

A lot of this is default content — the buttons at the bottom, for example, are pretty straightforward. So let’s talk about the critical parts:

1) The {{{info}}} tag. Its page name parameter specifies the name that any page created from this form should get. In this case, it’ll get the Milestone value from the Mozillians Release template (which we defined above). So the title of a page created using this form will be something like “2013-09-26”.

2) The {{{for template}}} tag. This specifies that submissions made to this form will fill up properties in the Mozillians Release template. It also describes the fields on the form.

If you visit the form you’ll just see the content in the <noinclude> block. You have to visit a special link to use the form.

3) You can create that special link with the {{#formlink:form}} tag. It specifies the template to use; the link text to use; and a query string parameter. Remember, when the form makes a new page it’ll just have a name like “2013-09-26”. But we actually want it to have a name like “Mozillians/Releases/2013-09-26”. We’ll send that “super_page” as a parameter in a query string to the form:

{{#formlink:form=Mozillians Release|link text=Make a new mozillians release|query string=|super_page=Mozillians/Releases}}

4) Finally, we have a link to follow to a form that uses a template to create a release. And we want to list releases. Here is the inline query code to do it:

{{#ask: [[Release-list::{{SUBJECTPAGENAME}}]]
| ?Releases
| format=ul
| order=descending
}}

view raw
wikimo query
hosted with ❤ by GitHub

Here’s what that dense little punctuation poem does:

  • Show all the pages that include a semantic mediawiki property called “Release-list” whose value is the name of this page (in this case, “Mozillians”). Remember the “Release-list” property in our template?
  • Show them as a list.
  • Order them with the lexically largest page name first. Since our page names are uniform strings with ISO dates at the end, this floats new releases to the top.

Putting it all together, I can now create a release page that displays all the bugs associated with a release, and have that release listed in a list of releases, in one easy step. Which, I hope, will mean our release documentation cleaves just a tad closer to the truth.

Note to anyone considering doing something similar on wikimo: You will inevitably create some test pages as you experiment with this. A friendly wikimo manager suggests that you create them in your own personal wiki namespace, which you can access at a link like this: https://wiki.mozilla.org/index.php?title=User:YOUR_USERNAME/.

Release management with Semantic MediaWiki

Why?

In an earlier post I described a project that produced a perfectly good result, but not the result required. This is inevitable — it will happen to everyone buying or selling creative work — and it can be quite demoralizing. As someone in the business of delivering custom services or products, figuring out what people want is the most challenging, most important thing you can do. And you can do it by repeating a single mantra.

A friend once asked a capable carpenter to install a door over a hole in the drywall of her basement where some plumbing valves were accessed. After a day of work she was aghast to discover that the carpenter had bought a full-sized closet door, built a frame for it, drywalled the frame, painted it and even installed a doorknob. The work was high quality and fairly priced. But she wanted a tiny little access hatch — a foot square, maybe — not a giant closet door. She paid the carpenter’s bill, then hired another carpenter to tear the door down and put in a little access hatch.

This has probably happened to you, too. Have you ever realized when your food arrived in a restaurant that you were hungry for something different? Have you ever begrudgingly paid for a service (a haircut, say) that is acceptable, but not what you really wanted?

what a mistake

It is easy to say, “The carpenter should have known his customer wanted a little access door, not a big closet door.” And maybe he should have. But should the barber have known what haircut you had in mind? Should the server have guessed that you wanted a different entree than the one you ordered?

Surely at some point in your journey you’ve thrown away days or weeks of work after a new detail or requirement emerged at the last minute. Almost everyone has. Why didn’t you know what to produce the first time?

Well, it’s because knowing what people want when they ask for something is hard. People often don’t know what they want, or don’t know how to ask for it. Delivering what they actually want requires you to interpret many layers of motivation and establish a shared understanding of the actual desire.

Arrow on flyer layers

Some of us are born with an innate ability to understand what people want very quickly. Others learn to do so by mastering a particular domain. Occasionally a shared understanding is based on a long relationship — it is easier to anticipate your friends than it is to anticipate strangers, after all. But for most of us, on most projects, establishing a shared understanding requires hard work. The sooner we do this work on a project, the less effort we waste.

Every project has a desired outcome — it’s one of the principal characteristics of a project. But in countless projects, the stated outcome would never be enough on its own to satisfy the sponsor or customer. Consider the following common projects:

  • Redesign the website
  • Rewrite the application using Python
  • Make a a new logo

They seem quite clear, don’t they? They’re just as obvious as, “Put a door over the hole in the wall.” It’s simple: Buy a door, frame it in, do some finish work. Make some new website designs that the customer likes. Reproduce the functionality in Python. Keep drawing logos until the customer likes one. Done and done, right?

Lorde Gelo

Bah. That isn’t a list of desired outcomes, it’s a list of implementation details. Those aren’t ends, they’re means. They’re the work you — the expert — do when you’re trying to deliver the thing. But they’re definitely not the thing you’re trying to deliver.

When someone asks you to redesign their website, ask them “Why?”.  They must have something in mind, something they think will happen if you redesign their website. How can you do a good job if you don’t know what that thing is? And when they say, “To make it look more modern,” you say, “Why?” Again, they must have some reason to believe they need a modern-looking website. And when they say, “So more people will visit the site and stay longer,” you say, “Why?” “Because if more people visit the site and stay longer, I can join a better advertising network.” “Why?”

Eventually, after playing 3-year-old for long enough, you’ll have your answer: “Because advertisements on this site are how I make my money, and I’m not hitting my goals right now.” Aha! It has nothing to do with modern design. Design is just an implementation detail. The customer wants to show different advertisements and thereby increase revenues; they think they can get there with a new site design; and they’re willing to invest in that theory. Now you can actually apply your expertise to the customer’s needs. Now you’re solving the right problem.

Almost always, asking “Why?” will reveal how faulty the initial project description was, and how far off-track you might have gone if you didn’t ask. That’s when you get to demonstrate the hard-won experience of a craftsman:

The Cutler's Hands

  • “You don’t need to rebuild the application in Python. You just need to add indexes to your database.”
  • “You don’t need a new logo, you need different colors.”
  • “You don’t actually want me to install a door there. You just need to cover this hole in the wall with a little access hatch, right?”

Extracting enough information to build the right thing can take a lot of time and may require asking and answering the same question over and over. During this exercise it sometimes feels like nothing is happening at all. But what is happening means everything to your project.

Postscript:
Sometimes, this approach simply won’t reveal the information you need to deliver a good project. And, unfortunately, you won’t know that until you’ve already done some work. So, in another blog post I will explain how inexpensive prototypes can help. Hint: Building the wrong thing allows you to ask, “Why not?”

Why?

A drawing of a house.

Somewhere in the clutter of my home office I have a beautiful design packet from a local architect. In big full color pictures it depicts my house with a wonderful modern roofline. Jutting points and angled planes, high windows and slabby overhangs. I love that roofline.

When I engaged the architect, I had already sketched about 12 floorplans for the addition we hoped to build. They were based on daily usage and known pain points. I knew exactly what spaces our house most needed: a mud room, a garage, and a new entryway. I also knew every constraint by heart: how far to the edge of the buildable lot, where the water lines ran, how many additional circuits our electric box could accommodate, which floor joist held the nearest hot air duct. My floorplans were optimized for utility, for ease of implementation. For us.

floorplan1

The architect took a look at my drawings and smiled. “They look good,” he said. “But it doesn’t matter right now. If you get the roofline right, the floorplans will fall into place.” Well, I thought this was very wise advice. And, sure enough, when the architect delivered the designs, the floorplans fell right into place underneath that wonderful roofline. His pictures resembled my sketches but had more light, more windows, more style. Beautiful!

Six years later, we still haven’t built that addition. A roofline like that with the high windows, the slabby overhangs, the complex angles — well, it doubles the cost of building. There was no way we could afford to build the house in those pictures. We didn’t. And we probably won’t. We paid a good architect for nice drawings of a handsome house that may never exist.

rooflineA couple times a year, I think about that wonderful modern roofline, and how it would look from the street. But you know what? I miss having a mud room and a garage far more often — almost every day, in fact.

The architect emails sometimes to ask whether we’ve made any progress. He hopes we will, because he would like to see that roofline soar just as much as I would like to fill the garage full of bikes. Nobody, even the guy who got paid for it, wants to see good work languish.

I’m sure this tale sounds quite familiar to most web designers, web developers and web project managers. Anyone who’s done a few web development projects knows what it feels like to realize, deep into a project, that it isn’t working. The product can’t be built as designed; maybe it can’t even be explained.

Excepting the anecdote above, house design and construction are usually terrible metaphors for web design and development. The apparent similarities simply don’t hold up under close scrutiny. We’ve been building structures for a few thousand years and most of us have lived in one before, and we are all beneficiaries of this vast experience. Even someone who has never considered how a house is built might anticipate that a waterproof roof should precede interior finish work, for example.

The same is not true for web development. There is almost no state of the art: We are making it up as we go, and we are going very quickly. To date, practitioners have made very few cultural agreements that are as obvious as “countertops on cabinets” or “closets in bedrooms”. The trade is young. We build web sites like people without nails and lumber and other standard components build homes: We take whatever materials we have at hand and stack them on top of each other until it resembles a structure.

P1010710

There is another similarity between custom home design and custom web development that I would like to point out before leaving this particular metaphor behind: In both disciplines, establishing a shared definition of success is the greatest challenge and the most likely point of project failure.

The architect in my tale thought success meant delivering beautiful designs within a budget. In retrospect it is clear that success meant helping me figure out how to build a garage within a budget. Neither of us was insistent enough about establishing this definition. Neither of us knew we had different understandings until the drawings were printed.

In upcoming posts I will suggest some simple practices that can make web development projects work better. I’ll describe common features of web development projects that transcend the methodology à la mode. And I’ll talk about various ways to integrate design and development activities.

I will know I have succeeded if just one person says it has helped.

A drawing of a house.

More than a job.

While copying various old work from an old Macbook to a new Macbook today, I ran across a short note I wrote myself back in 2009. I remember typing it. I’d just met Christian Heilmann, who was visiting Denver to speak at a conference. He gave a talk that must have impressed me, because I jotted some instructions to a future self: “Consider Mozilla,” I said.

But I’m getting ahead of myself.

Earlier today, before the episode with the Macbooks, I found myself in an unfamiliar place, surrounded by dozens of strangers. They led me up to the front of the room and told me to stand on a big black X. I did so. A trio of cameras panned and zoomed, and everyone in the room looked at me. I saw my face on the big screen, as did hundreds of people watching from home. I smiled a bit nervously and waved. They smiled back.

They were welcoming me. That’s how they welcome folks to Mozilla. Everyone present had stood on the X at one time. Some might even have given a speech from that X, but I kept my mouth shut.

Today was my first day at Mozilla. I am a web product engineer. I’ll help Mozilla’s many product owners articulate their vision for web sites and applications, and then collaborate with Mozilla’s many, many contributors inside and outside the company to launch new features and products on the web. This job is some web engineering and some web project management, plus a smidgin of every other aspect of web production from architecture to marketing. In fact, it’s precisely what I loved doing at dojo4 and in earlier roles, too. I couldn’t have written a more suitable job description for myself. And I’ve been nothing but impressed by the caliber and quality of people I’ve met at Mozilla.

h-line08

I built my first website in 1995. It had a rainbow-tastic horizontal rule powered by animated GIF. I’ve spent my entire career working on internet technologies. Needless to say, the web has grown up in that time and has become utterly essential to the stability of many social systems. Our government, economic, and communication networks rely on services that themselves depend on open systems and common protocols.

But these foundational elements are not guaranteed. Plenty of powerful interests would prefer to have more control over the way we interact with information. They’d like to choose the tools we use, the voices we hear. But, so far, in this part of the world, the internet remains a wild and free place where submission to such controls is mostly voluntary. This is due in large part to the efforts of a staunch cohort of benevolent technology organizations and individuals who build standard-based tools with open sourcecode. Mozilla is one such organization.

Mozilla HQ Mountain View

This work is important and valuable. It has a clear purpose, one that I support. And there’s plenty of work to do. Mozilla has strong competition for its major products and some very ambitious new releases coming up. I’m thrilled to be here pitching in.

I should mention that I’ll still be working in Boulder. It’s home. Look for me anyplace that serves Boxcar coffee. If you’re a Mozillian, you can also find me in IRC at hoosteeno.

I also wish to thank everyone I met with during the past 3 months. Many, many people made time to talk with me about opportunities within their organizations. I am grateful.

More than a job.

A Rich Public Domain

@randfish posted “Where does Creativity Come From?” today, and linked to Kirby Fergusun’s excellent TED talk, “Everything is a Remix”:

Fergusun’s talk reminded me of this wonderful 2004 video tracing the history of a single drum loop, the “Amen Break”, as it travels from its original recording into a variety of illegally appropriated and infringing remixes and samples during the next several decades:

I could reminisce at great length about the 3rd Bass and N.W.A. songs this video digs up. I spent many days skateboarding around Denver, feeling very tough with that era’s hip hop playing in my head. But lately I’m more interested in the conversation about ownership and creativity these two videos consider.

I’ll dig back into this subject in coming months — not as a legal expert, just as a regular dude who cares about our culture’s ability to create new wonders unencumbered by short-sighted copyright and patent enforcement.

Listening to the second video again today, I was struck by a quote near the end. Here it is:

“Overprotecting intellectual property is as harmful as underprotecting it. Culture is impossible without a rich public domain. Nothing today, likely nothing since we tamed fire, is genuinely new: Culture, like science and technology, grows by accretion, each new creator building on the works of those who came before. Overprotection stifles the very creative forces it’s supposed to nurture.”

– Alex Kozinski

A Rich Public Domain

Hoosteeno.com now with more WordPress than ever!

This blog has only a few readers who might notice (I’m looking at you, Boris) a burp in its content today. I apologize for that. I’ve decided to host it on WordPress.com for reasons that I will share in a separate post.

I did not migrate all the content. Much of it was just photos that I posted because Tumblr made posting photos so dang easy. I do not consider them to be archival material, unlike the timeless masterpieces that made the cut.

A Tumblr-to-Wordpress.com migration cannot include permalinks, which means old article URLs do not go anywhere anymore. Therefore I should apologize as well to the faithful search robots who have come back day in and day out to spider the same old content. Your confusion will not last.

Finally, to all readers old and new: This transition represents a turning point on Hoosteeno.com. Herewith there will be more.

Hoosteeno.com now with more WordPress than ever!

Woodwork: A baby bunk.

In my free time (which has increased some, but not as much as you might imagine), I am building baby furniture. Here I am sanding some birch-veneer plywood that is part of the co-sleeper I built.

One can order co-sleepers online. In the U.S. one company has a real monopoly on these, and I hear they’ve even trademarked the term “Co-Sleeper”. Unfortunately, their products don’t have much visual appeal. To me they resemble the kind of cheap desks you might buy at a big-box office supply store or maybe a TV table from Target.

Across the pond you can order beautiful co-sleepers: modern, sleek, minimal. Maybe some Scandinavian design, no plastic casters. But their price is in British Pounds or Euros, which means they cost about 2x what we would pay here for a similar item. And they must be shipped at great expense.

There are a handful of nice looking products made in the U.S. (or at least sold by U.S. companies. Here’s a nice looking one. And these folks are definitely the real deal.

But after reviewing all the options, I decided that I could build a co-sleeper and would enjoy doing so. This is a nice way to get into woodworking. Babies don’t put a lot of load on furniture, and this is a simple object to make. Also, it’s an opportunity to experiment with wood finishes — if the finish doesn’t turn out perfectly, no big deal. And finally, I saved enough money doing it myself to buy the table saw I need to do it.

(The latter trade reminds me of a coding adage I’ve learned over the years: Invest heavily in the framework you use to build things so you can build more things.)

All of the materials — screws, wood finishes, and planks — are scavenged from earlier projects, so the entire project cost is the table saw and my time. And as far as my time is concerned, I consider it practically recreation to spend an afternoon in late September sanding and cutting in the back yard. The leaves are turning, the sky is blue, the sunlight is warm and golden, the shade is cool.

Here are more images and my SketchUp plans for this baby sleeper.

Woodwork: A baby bunk.

Hello Goodbye dojo4

This entry is crossposted from dojo4.com.

I remember that first meeting. It was Jeff, Dave, me and Ara. We were on a rooftop bar in Boulder. It was fall. The leaves were changing and the sun was angling down. We were all ready for something new. Not a job: Something different. We would do it together. First we would name it, and then we would work it. It couldn’t fail. We were smart and strong.

Ara found the spot, a tiny joint behind Ted’s Montana Grill. It was trashed: No flooring, terrible paint, an awful dirty unfriendly bathroom. Naturally we rented it, and I think Jeff started sleeping there immediately. He was up all night painting for a week straight. All four of us helped when we could, but Jeff was there every single day. And within a few weeks the humble space had become dojo4.

dojo4 was the first name that nobody protested. It was short and easy to remember; it held a secret mystery, something admirable and maybe dangerous. Or vice versa. dojo4 beat out “Death Ninja Squad”, which I protested because I didn’t want to try and market death to my straightlaced customers. dojo4 also beat out “The Mulberry Club” — I have no idea why I thought that one was good.

dojo4 was going to be a coworking space. Invite only, like a speakeasy with Macbooks. We would charge people to join the club. They’d get a door code. Once we decided this, I got busy writing regulations and policies while Ara and Jeff argued about decor and Dave hacked on mobile apps. Amazingly, in that first month we convinced some folks to sign up to be members!

Well, it didn’t take long before we realized that our 3-square-foot bathroom/kitchen combo would never adequately serve a crowded coworking space. And furthermore, we couldn’t see how coworking would ever pay for itself. And meanwhile, people kept walking in the door asking us to build things for them. Web sites. Custom applications. Stuff like that. So we quickly pivoted and became dojo4, the “one chop shop”.

From that moment things moved very quickly. We hired people; we brought on another partner, Corey; we lost Jeff to San Francisco and Dave to Splick*It; we hired more people. All the while we turned out bespoke web applications and sites for enthusiastic entrepreneurs. We generated enough caffeine demand to light up two new coffeeshops on the east side. The nature of our work, our brand and our team were subject to constant change. It was wildly dynamic.

It’s been said many times, so I will merely echo it: The Boulder community made our business possible. People came by at all hours, from the first day until the present day, just wanting to spread cheer and offer a hand. They brought beer; samurai swords; fertility idols; jobs; friends; advice; opportunities. Boulder is awesome. All together we are the caretakers of something special.

One of dojo4’s earlier web sites was built around a single enigmatic declaration: “What we do and how we do it is who we are.” That’s terrible marketing, but it’s true. dojo4 has always been primarily a collection of smart people willing to devote their attention and energy to interesting projects, no matter the nature of the work. At one point I fielded an inquiry from someone who wanted a chicken coop built. I tried to get the work, but we were outbid. Their loss.

I love that about dojo4. I’m a generalist, equally as comfortable in a late night vi-git-cap loop as I am teaching of a crowd of nontechnical people about search engines; just as happy writing marketing copy (most recently on Collective Intellect’s new site) as I am writing Javascript (recently for ultrarunner Scott Jurek’s blog and calendar). Working for dojo4 meant I could do any of it, any day of the week.

Being a generalist often means doing whatever needs doing. And at a small business, that often means being the CEO. So since 2011 I’ve been dojo4’s first CEO, working with Corey and Ara to build a vibrant little business that we’re all very proud of. I’ve never had a more challenging or rewarding work life. In this role I’ve met entrepreneurs from all around the world; I’ve built and launched things way out on the cutting edge of technology; and I’ve worked with a remarkable team of people, too many great folks to name here. It’s been wonderful.

But today I’m leaving dojo4. This is the time of year for change: The sky is changing, the leaves are changing, dojo4 is changing, and I’m changing too. My lovely wife has a wiggly baby on the way. Right away I’m going to spend some time learning what it means to be a dad. And after that I’ll also be looking for some new interesting work to do, something that needs a generalist like me.

To the good people I’ve met down at the dojo: Let’s meet again. Seriously. Email justin@dojo4.com right now; let’s go get a coffee or a beer (I’ll buy) and let’s talk about what’s next. Thank you all.

Hello Goodbye dojo4