Synthesis : Scott Becker

Enumerated Types in TypeScript

Enumerated Types, also known as enums, are a feature common to many programming languages, that represent a finite set of possible values for a given type.

For example, in a typical 52 card deck of cards, there is four suits: Clubs, Diamonds, Hearts and Spades. All of the 52 cards are one of these suites.

In a typed programming language, we could have a “Card” type, with a “suit” property. In the most basic form, the type could be defined where the value of “suit” must be a string. We could then assign the value “Clubs”, “Diamonds”, “Hearts”, or “Spades” for each card.

Here’s how that might be represented in TypeScript, and for simplicity, we’re going to make every card have a number value for now and not worry so much about face cards.

interface Card {
  value: number // 2, 3, 4, etc...
  suit: string // either "Clubs", "Diamonds", "Hearts", or "Spades"

With this setup, we could assign suit to be “Diamonds”, “Hearts”, etc, but we could also assign it any other string, like “Squares” or “Harts”, and the compiler would not complain, because we said the value can be any string, and “Squares” is a string.

It would be nice if the computer could help us avoid errors like these. That’s one of the things enums can do, along with documenting what the valid values are.

So to lock things down a bit tighter, we can define an enum for Suit, with all possible expected values defined. Here’s how that looks in TypeScript:

enum Suit {

Unless you say otherwise, the value of each item in an Enum is numeric, and starts at 0. Clubs == 0, Diamonds == 1, etc. It can start at a different number, or you can specifically set the value of each item.

You can also make the values be strings, which is handy if you’re dealing with something like a REST API returning JSON data where the value of suit is a string, not a number.

// GET https://awesome.api/cards/32

// JSON Response:
  "value": 5,
  "suit": "Diamonds"

Here’s a string enum for Suit:

enum Suit {
  Clubs = "Clubs",
  Diamonds = "Diamonds",
  Hearts = "Hearts",
  Spades = "Spades",

Slightly redundant since we have to repeat each word twice, but it’s more convenient, and the values map better to the data.

Now you can define a card interface with the more exact Suit enum value defined.

interface Card {
  value: number
  suit: Suit

Then we can define a card:

const card1: Card = {
  value: 5,
  suit: Suit.Diamonds

This works, because we use the enum when setting the value. If we try to use a random string, it does not work:

const card2: Card = {
  value: 5,
  suit: "x" // compiler error 

// error details:
// Type '"x"' is not assignable to type 'Suit'.
// The expected type comes from property 'suit' which is declared here on type 'Card'

It also doesn’t work if we use the same string values as the enum.

const card3: Card = {
  value: 5,
  suit: "Diamonds" // compiler error 

// error details:
// Type '"Diamonds"' is not assignable to type 'Suit'.
// The expected type comes from property 'suit' which is declared here on type 'Card'

If value type is an enum, and you manually define a card at compile time, you must use the enum to set the value.

Sometimes numeric enums are desirable. A single integer takes up less space than a string. Sometimes the numeric values are meaningful – it could represent known id values, sort order, or ranking. One possible example is access roles. If all roles are ranked and one always supercedes the other, you could use a numeric enum where the values represent the ranking order:

enum Role {
  SuperAdmin = 0,
  CompanyAdmin = 1,
  Manager = 2,
  Employee = 3,
  Guest = 4,

Then let’s say a user can have multiple roles, like ["Employee", "Manager"] and we wanted to get that user’s highest privileged role.

First, if the data looks like that instead of numeric values, we can define a typed union with all possible value of a role string, with this handy keyof typeof syntax:

 * This is equivalent to:
 * type RoleStrings = 'SuperAdmin' | 'TenantAdmin' | 'Provider' | 'Guest' | 'NoAccess';
type RoleStrings = keyof typeof Role;

Then we can define a function that compares the values of each role and find the one with the lowest value:

function getHighestRole(roles: RoleStrings[]) {
  return roles.reduce((acc, role) => {
    // if role's number is lower than previous accumulator role's number, it now wins, return it
    if (Role[acc] > Role[role]) {
      return role

      // otherwise return existing accumulator role
    } else {
      return acc
  }, "Guest") // default to lowest privileged "Guest" role string

Now we can define some data and call the function

const myRoles: RoleStrings[] = ["Manager", "Employee"]

getHighestRole(myRoles) // "Manager"

So, enums provide a way to concretely define and document the set of possible values that a specific variable or object property can be, help programmers avoid mistakes while writing code, and enable compilers to catch errors.

Alright, that’s probably enough about enums for now. By this point it’s either totally clear or you’re totally confused. 🙂

Leave a comment

Google Sheets Macros

A macro in Google Sheets is a recording of a series of actions that can be repeated via the Macro menu or with a hotkey.

To start making a macro, click Tools > Macros > Record Macros.

A dialog box pops up showing the macro is currently recording, and lets you choose between absolute and relative references.

Once recording, you can perform some actions (such as formatting a header row), and click the “Save” button in the dialog box, give it a name and an optional hotkey.

The first time you try to use a recorded macro, you will be prompted to authorize it. Authorization cancels the action, so you’ll have to re-run it after you’ve authorized it for it to actually run.

Macros as Code

The really cool thing – is that your recorded actions are automatically translated into statements in a JavaScript function using the Apps Script APIs. After saving a macro, you can go to Tools > Script Editor to view the recorded macro as a script.

Here you’ll see the script editor with a function of the same name as your macro, containing the code statements to reproduce the actions. This macro “Header” changes the colors of the first header row and freezes it.

Here’s that code, with comments for each statement:

/** @OnlyCurrentDoc */
// ^ limit script permissions to current doc

function Header() {
  // get the active spreadsheet (the entire document)
  var spreadsheet = SpreadsheetApp.getActive();

  // get the currently selected sheet
  var sheet = spreadsheet.getActiveSheet();

  // select the entire row, relative to cursor starting point (equivalent of clicking number to left of a row)
  sheet.getRange(spreadsheet.getCurrentCell().getRow(), 1, 1, 

  // set background color, set foreground color, and bold it

  // freeze the first row

Leave a comment

Creating G Suite Add-ons with Apps Script.

I’ve been working on a project to build a G Suite Add-on. This category of software is written in JavaScript and runs within Google’s infrastructure. It’s essentially serverless – you write your scripts, Google runs them, and you don’t think about the compute.

It has it’s own flavor of JavaScript execution environment and a set of APIs for communicating with and extending G-Suite, collectively called Apps Script.

A couple interesting things about it:

CLASP (Command Line Apps Script Projects) is useful and recommended when you’re ready to “get serious” and not just write simple scripts. It lets you:

Interesting things about the Apps Script APIs and execution environment:

Maintaining State

In most business applications, you want to maintain some sort of state, such as a user’s auth token to a 3rd party service, their preferences, etc. Any add-on that talks to a 3rd party service might want this. Until today, I was using an additional “Meta” sheet within a Google Sheet to maintain some state. But I thought there must be a better way and found that there is – the Properties service. This lets you store key/value pairs in a few different contexts:

Leave a comment

Forcing HTTPS on WordPress with Apache

This site lives on a long-lived Dreamhost account, and until a couple months ago, like many older sites, had been happily humming along without SSL setup.

That’s not really a big deal for a public-facing blog site, or so the old thinking went. But since I do login to update content once in a while, it makes sense to get it up to date with current security best practices and not send passwords in the clear, so…

There’s many options on how to do this, and I don’t reach for Dreamhost these days for new web projects, but since it ain’t broke… I went hunting on how to do that on Dreamhost. A couple months ago I did the first half of this project, and figured out how to set up Let’s Encrypt for a website in the Dreamhost admin panel – too easy. Worked right away… But one problem, no redirect of HTTP to HTTPS, so the old insecure site continued to work just fine. Also my custom web font wasn’t rendering correctly.

Then I just forgot all about it, until today. I’m planning to blog here again, so I took a look and fixed the issues.

First, my web font wasn’t rendering because I had a “http://” url referring to the web font, and the browser was refusing to load insecure content. A quick edit of the header php file for my theme to make that a “https://” url fixed that up.

Second, forcing HTTPS. From doing this many times, I know this means redirecting from HTTP to HTTPS. My WordPress site is hosted on Dreamhost and runs within Apache, so I was searching around (much of professional software development is having good internet search skills). First, I searched “wordpress redirect to https” and found “How to Redirect HTTP to HTTPS in WordPress“, which mentions how to do it on Kinsta (a different hosting provider, not applicable), Nginx (not applicable), Apache (applicable!), and via a WordPress plugin (applicable!). Since Apache is lower level than WordPress itself, this is more desirable (can’t get blown away by an update or conflict with other WordPress plugins.) Apache it is, which involves editing a .htaccess file. Then I searched “wordpress dreamhost .htaccess” and found “Force your site to load securely with an .htaccess file” on the Dreamhost knowledge base, which show how to find where on the server file system to find this file for a particular Dreamhost site, and what to put in it – same code as the Kinsta article.

The magical .htaccess incantation?

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]

Looks like it turns the rewrite engine on, runs a rule if the HTTPS condition is not on, and creates a rule to return a 301 (Moved Permanently) redirect for any request to the https:// equivalent.

Then I remembered I used to have SSH access to Dreamhost set up. Did it still work? Yes, it did! Was the file where the help article said it woud be? It was. Edited it. Tested it with curl:

$ curl -i

HTTP/1.1 301 Moved Permanently
Date: Tue, 14 Jul 2020 05:31:58 GMT
Server: Apache
Cache-Control: max-age=600
Expires: Tue, 14 Jul 2020 05:41:58 GMT
Content-Length: 238
Content-Type: text/html; charset=iso-8859-1

<title>301 Moved Permanently</title>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="">here</a>.</p>


Sidenote – The above is a first go at a new format I’m going to try for a bit. I needed a place to put this writing, and this old dusty blog already existed, so I’m reviving it.

I plan to write about / document something I learned once a day or so (with exceptions for trips, vacations, needed breaks, etc.). It can be the simplest, stupidest thing, as long as I learned anything at all.

I’m going to commit to this for at least one week.

Leave a comment

Exploring graph databases and Neo4j

Recently I started learning about graph databases and Neo4j specifically.

In a graph database, you have two main things:

Nodes and relationships can each have properties – pieces of data about them – what type of node or relationship it is, and any other data about it – like it’s name, when it was created, etc. In a relational SQL database, to store relationships you need to add columns in your tables to track foreign keys, indexes, etc. In other words, you need to pre-think things out and get your data into a shape that fits in tables of columns and rows, and define what kinds of things belong to or have many other things. In a graph database, you just start adding nodes, then add relationships from one thing to another. Just interconnected things.

I decided to play around with Neo4j and get a feel for how it works.

I used the instructions on Digital Ocean’s site for installing Neo4j on Ubuntu.

 wget -O - | apt-key add -
 echo 'deb stable/' > /etc/apt/sources.list.d/neo4j.list
 apt-get update
 apt-get install neo4j

Now Neo4j is running. The HTTP api is available on port 7474.

We can send some requests to the api and see how it responds.

Some facts I’ve gathered:

Every request, when using curl, looks basically like this:

$ curl \
  -H "Accept: application/json; charset=UTF-8" \
  -H "Content-Type: application/json" \
  -X POST \
  http://localhost:7474/db/data/cypher \
  -d '{...some json...}'

That JSON generally follows this format:

  "query": "...SOME CYPHER HERE...",
  "params": {
    "key1": "value1",
    "key2": "value2",

The values in the params key/value hash get substituted for names in the query. Name substitution is a nice built in feature.

The exception to this JSON format, atleast in the tutorial I followed, was when creating relationships. For that, you post to a different URL and use a slightly different syntax.

POST http://localhost:7474/db/data/node/0/relationships (url of first node’s relationships resource)

Request Body JSON:

  "to": "http://localhost:7474/db/data/node/1", // url to another node
  "type": "Comes Before" // name you've given this type of relationship

You can also create relationships with the Cypher query language.

Creating a node of type Person with a “name” attribute:


CREATE (n:Person { name : {name} }) RETURN n


name: "John"

Full on JSON:

  "query" : "CREATE (n:Person { name : {name} }) RETURN n",
  "params" : {
    "name" : "John"

The API gives you a lot of data back:

  "columns": [
  "data": [
        "outgoing_relationships": "http://localhost:7474/db/data/node/0/relationships/out",
        "labels": "http://localhost:7474/db/data/node/0/labels",
        "data": {
          "name": "John"
        "traverse": "http://localhost:7474/db/data/node/0/traverse/{returnType}",
        "all_typed_relationships": "http://localhost:7474/db/data/node/0/relationships/all/{-list|&|types}",
        "self": "http://localhost:7474/db/data/node/0",
        "property": "http://localhost:7474/db/data/node/0/properties/{key}",
        "properties": "http://localhost:7474/db/data/node/0/properties",
        "outgoing_typed_relationships": "http://localhost:7474/db/data/node/0/relationships/out/{-list|&|types}",
        "incoming_relationships": "http://localhost:7474/db/data/node/0/relationships/in",
        "extensions": {},
        "create_relationship": "http://localhost:7474/db/data/node/0/relationships",
        "paged_traverse": "http://localhost:7474/db/data/node/0/paged/traverse/{returnType}{?pageSize,leaseTime}",
        "all_relationships": "http://localhost:7474/db/data/node/0/relationships/all",
        "incoming_typed_relationships": "http://localhost:7474/db/data/node/0/relationships/in/{-list|&|types}",
        "metadata": {
          "id": 0,
          "labels": [

Creating a second person:

  "query" : "CREATE (n:Person { name : {name} }) RETURN n",
  "params" : {
    "name" : "Susan"

Create a relationship between them:

Assume the John node has a url of


And the Susan node has a URL of


We want to create a relationship between John and Susan. John loves Susan. That’s the relationship. In Neo4j, relationships have a direction. They go from one node to another. They also have a type. In this relationship, the from node is John, the to node is Susan, and the type is “Loves”. Each node has a set of relationships. This set or collection of relationships is mapped to a rest API.


For John’s node, which is node 0, this would be:

Then, to create this relationship:

POST http://localhost:7474/db/data/node/0/relationships

  "to": "http://localhost:7474/db/data/node/1",
  "type": "Loves"

Neo4j returns a lot more data back:

  "extensions" : {
  "start" : "http://localhost:7474/db/data/node/0",
  "property" : "http://localhost:7474/db/data/relationship/1/properties/{key}",
  "self" : "http://localhost:7474/db/data/relationship/1",
  "properties" : "http://localhost:7474/db/data/relationship/1/properties",
  "type" : "Loves",
  "end" : "http://localhost:7474/db/data/node/1",
  "metadata" : {
    "id" : 1,
    "type" : "Loves"
  "data" : {

It tells us where the relationship starts, where it ends, any metadata, any extensions, properties, and any other data.

Now, lets do a simple query to figure out who loves who (JSON enclosure left out, just the Cypher query):

MATCH (n)-[r:Loves]->(m) 
RETURN AS from, type(r) AS `->`, AS to

And we get back:

  "columns" : [ "FROM", "->", "to" ],
  "data" : [ [ "John", "Loves", "Susan" ] ]

Once you’ve got a lot of relationships set up, you can use Cypher to quickly query these. An immediate use case for graph databases is social networks. If you have all this data regarding who is friends with who, and you want to get some stats on that, like how many friends of my friends friends like pizza and live in Spain, and so forth, with a SQL database, this can be a real pain to write – loads of joins, nested queries, and very slow as the size of the network grows. A graph database is optimized for this, so it’s very fast to perform queries that traverse through many levels of relationships – at least it’s purported to be.

Although social networks are the first data structures to jump to mind, graph databases seem well suited to many other types of data as well, so long as the items are interrelated.

Another nice thing – graph databases seem to be more able to easily represent real life scenarios, where data doesn’t easily fit in a two dimensional grid. Have more data? Add nodes. Does that data relate? Add relationships. This includes one off items, special cases, and things which don’t fit into a traditional two-dimensional grid, or a hierarchical tree, or a flat set of key value pairs. Everything can be inter connected in a giant messy hairball of strange and wonderful relationships, just as it is in real life, and that’s ok – a graph database can easily represent that.

Comments Off on Exploring graph databases and Neo4j

Getting Started with Freelance Web Development

A friend of mine recently let me know his current web development job is ending because the company is shutting down. While he is interviewing at other companies, if at all possible, he’d like to start freelancing, but has no idea where to start.

Since I have a fair amount of experience doing freelance and contract web development over the past 8 years, I thought I’d put together some ideas for the currently non-freelancing, yet marketable-skill possessing web developer. If you don’t yet have technical or design chops, this doesn’t apply to you yet. Go back and get those. If you do have the chops, soldier on.

What do you NEED to get started?

Are you ready? All you need to get started is your first client. That, and a few more obvious things like: technical skills, communication skills, the ability to think of creative solutions, manage your own time, and follow through on commitments in a timely manner. No big deal. You have all of those, right? What you might not have is that first client.

Notice what I didn’t say you needed. The following is a list of nice-to-haves that you can work on later once you’re generating a modest amount of cash flow: a website, business cards, a corporate entity. Your initial focus should be on getting client #1. Sure, you can work on the other business admin things, but they shouldn’t be your first priority.

To get started, you should be spending more than 50% of your time finding that first client.

How do you get your first client?

To get a client, you need some leads. A lead in this case, is a person or company that is interested in getting some work done – which could be a brand new website or application, or additional work on an existing project. Start building a list of leads.

Are you already known to friends and colleagues as a skilled web developer? If so, you may have already been contacted at some point by someone asking for help. If so, congrats, you’ve got a lead! Follow up and engage with this person.

What if no one is currently requesting your services? Then, my friend, you need to get proactive. You need to hustle.

How do you hustle?

Let’s look at some definitions of hustle. “To move or act energetically and rapidly.” “To sell, promote, or publicize aggressively or vigorously”. This is the hustle I’m referring to. “Hustle” also has many other definitions, some with illicit connotations, like to sell drugs or stolen goods, or to swindle and deceive people. Just to be clear, that’s not the kind of hustlin’ we’re talking about. This is all about getting more assertive with communicating, making connections, and asking for business. In other words, anything but wasting time.

If you’ve been comfortably working away in a bubble on whatever you’ve been asked to work on for your previous employer, you might not yet have experience with this world. It’s time to get out of the bubble and start talking to people.

Clarify your offering

You need to let people know what services you’re offering, and spread the word that you’re available for work. Before you start initiating contact with people, you should put together some talking points. Start by putting together a list of the kinds of things you can do. Bear in mind your audience when you build this list. Are you talking to technical people, business people, creative people? Know your audience and tailor the list to them. If you plan on going after multiple kinds of people, build multiple lists.

For the technical list – do you have a LinkedIn profile with a list of technical skills and endorsements? If so, you can start there. Work on any open source projects? That’s even better. Flesh it out, but emphasize the things you’re best at. No one is awesome at everything, so don’t depict yourself as a grab bag of every possible technical skill. Pick the things you’re best at and that you actually like doing, and emphasize those. Balance that with what’s actually in demand. Don’t just stop at the keyword. You should have examples you can talk about. “I do HTML5” is not a good example. “I’ve used HTML5 to build responsive designs that look just as great on PCs as they do on tablets and mobile phones” is better. Having numbers is best. How many people use your open source project? How many more visitors (absolutes and percentages) from mobile devices are you getting on your website now that you’ve implemented that new whiz-bang responsive HTML5 design?

For the business list – think of the past projects you worked on. What did you contribute? Did you improve the project? How did you move the needle for the business? Improve sales or conversions in any way? Do any A/B testing that quantifiably improved something? That kind of stuff is extra-awesome. Start collecting some metrics that you can tout.

For the creative list – what kind of unique, innovative projects have you worked on? How did they do things differently? Any unique ways of navigating the site? New paradigms for conveying information? Simplify something previously complex? Did you work with other creative people and help realize their vision? Have visual examples.

Finding people

Now that you’ve got a list of services you can offer, who do you offer it to? Where do you find these people? Many places. Web development is in demand. Here’s some ideas:

  1. Previous Colleagues

    These are some of your best initial connections. They already know you and your abilities. Let them know you’re available for work, should they know of any. They might not right now, but next week a new project may appear on their horizon and you might come up as a potential do-er of said project. They’re also good people to ask to write LinkedIn testimonials for you.

  2. Local Meetup Social Hour

    Do you live in a city? Then there are probably some meetups you can and should attend. I live in Portland, Oregon, where there are technical, business, and creative meetups happening on a daily basis. You can find these on sites like, and local sites like, which is specific to Portland. Not every group is on though. There’s probably a website or three with a calendar of professional events happening in your town. Don’t have a local group that discusses technical/business/creative topic X? Start one! I’ve done this three times. It’s great, and gets everyone coming to you.

    Many times these group meetings are split into two halves. The speaker presentation(s) for the month, and the social mixer component. If you’re looking for work, the social component is your priority. It might be beforehand or afterwards in the lobby, or it might take place at a bar nearby. Many times this is actually more interesting and fun than the scheduled presentation. What you want to do here is simply walk up to or sit by people you don’t already know, say hello and introduce yourself, and ask what they do. Let them know what you do. If there’s any common interest, or it seems like they might be valuable to know in the future, ask for their contact info, like a twitter handle or an email address. When the conversation wanes, say “it was great to meet you,” move on and repeat!

    You don’t want to be wasting time, so don’t just find the person you already know and hang out with them the entire time. Split up and meet new people. And since you spent the time to come here, set a quantifiable goal, such as exchanging contact info with at least five people. If you’re new to doing this, you can start slow and build up to it, but it’s hustle time. Get out there and chat it up. Remember there’s no pressure here. You’re not out to find that one person who’s going to lead to some work, you’re just practicing meeting people, and building your network. Have nice casual conversations and move on. Then follow up with them later with a short email, or an @ reply on Twitter. Get used to doing it regularly so it becomes automatic, and no big deal.

  3. Local Meetup Presentations

    This is a step up from social hour. Do you have some topic you can talk about for 5-15 minutes that would be interesting to the members of some group? It’s a great way to make yourself the central topic of conversation, and get people coming to you afterwards to ask follow up questions. You can also post your slides online, and the video if one was recorded. (Hint: use screencast software to record one yourself.) Posting presentation decks and videos online gets you a lot of mileage over time, and it makes you look like an expert on that topic.

  4. Online Forums

    Google groups is a good one. also. Again I recommend starting local. Find where local people are having discussions online and hang out there. It’s easier to start an initial business relationship if you have the ability to meet up face to face, at least once or twice to get started. So find groups related to what you do, preferably local to your area. Technical groups frequently have job postings from companies or individuals looking for skilled people. Each of these is a lead. If they match up with what you’re offering, email them.

  5. Twitter

    You should have a twitter account where people can find you. Something short that you can tell people while talking, and write on a name tag. You should post there regularly, about what your working on. You can also share links you find interesting. You should follow interesting people and engage with them as well – replying and retweeting. BUT remember, you need to primarily be working. Don’t let Twitter take over your mind. There are some good strategies for this. You can get a BufferApp account and queue it up with tweets to go out at measured, regular time intervals. Timebox 15 minutes a day or so to review what others have said, and retweet interesting things. But limit your time here. You need to be producing, not consuming.

  6. Blog

    It would be good to get one of these if you don’t yet have one. As a technical person, you might view this as a technical project that you need to build from scratch in the new cool language and framework du jour. Nope. Don’t do that! You’re a business person now, who makes smart decisions about the value of their time. Unless you’re in the business of building a better blog engine, or someone is paying you to do it (and even then), working on building a blog engine when you need to get client work is like not working at all.

    Just get a standard WordPress blog started. They’ve already solved the blog problem, and there’s a huge thriving ecosystem behind it. So many useful plugins and themes, and constant security updates. Host it somewhere you don’t even have to think about the hosting. I use Dreamhost. They keep it updated with the latest version automatically. Timebox this. It should take you two hours max to get setup and online. You can tweak it later.

    I also recommend getting your own domain, vs being on the domain of the latest hosted blog platform out there. You’re building your own brand and creating your own content now, not bolstering someone else’s.

    Once it’s setup, link it to your Twitter profile, LinkedIn, etc. Then set a goal to post about one interesting, useful thing a week to start. Make a content plan: a list of potential blog post ideas, and start outlining them. Set aside an hour or two per week to bang it out. Get a friend or two to review it and use the feedback to make adjustments before you show it to the entire world. Schedule the post to go live in the morning of the next day. Schedule a tweet to go out at the same time. When you feel you’ve really knocked a post out of the park, submit it to forums like Hacker News and Reddit, or others more specific to what you’re talking about. Start building an audience.

Have some savings

When you’re first getting started, you won’t have any momentum yet. You need to spend some time getting the ball rolling, and learning how to make things work. There might not be any immediate action, aka money coming in. It’s ideal to have some money saved before you take the plunge into freelance. Like three to six months worth, because it takes time to get started and build momentum. If you don’t have any savings, stay gainfully employed and start doing this on the side so you don’t go broke. Understandably, you might not always have a choice, if for example, your current company is going under. In that case, use your best judgement to decide if now is the right time to go freelance. You want to be thinking rationally, not in a panic about paying the bills.

Get a peer group

If you’re used to being around co-workers and heading out on your own, it can get lonely. You’ll still need a group to talk shop with. Find some people that are doing the same thing. Being around other motivated, successful people in pursuit of similar goals goes a long way towards helping you succeed. If everyone in your current professional peer group is employed by a company, they’re good connections for work, but not necessarily going to be the best motivators. Keep them, but also find some other people who are already freelancing, and go to lunch or out for drinks. Find or start a mastermind group.


All of the things I’ve listed here are things to do regularly and repeatedly. Your overall goal here is to boost your professional profile and visibility.

A single burst of energy is not going to fill your inbox with potential clients. Instead, pick a few simple things to do on a regular basis, and keep it up.

Make a list for yourself, and set daily and weekly reminders so you don’t forget. Make the list short and simple to start. Like two or three key things to do regularly. Here’s an example list you can use:

  1. Attend one meetup per week. Exchange contact info with 3-5 new people.
  2. Write one blog entry, and a few tweets per week. Preferably something meaningful and useful to others.
  3. Make personal contact with one to three people per week. Meet someone for lunch, send them an email, reply to them on Twitter, etc.

Don’t give up

Starting freelancing is like starting any other new job. The first six months are a time of intense learning. There’s a lot to learn. It takes time and patience. It doesn’t happen over night. The secret is to just keep at it. Take one day at a time and set short achievable milestones for yourself. There are ton of other topics that can be covered about freelancing, such as pricing and creating proposals. But that comes later. Before you can focus on those things, you have to focus on finding the people who need work done. Network and meet people. Business requires two parties. You are one. Find the other. Have fun!

Comments Off on Getting Started with Freelance Web Development

Checklists and Habits

Lately I’ve become obsessed with checklists – a simple list of everything to complete a certain task. The book “The Checklist Manifesto” by Atul Gawande is a great introduction to the topic, on how checklists reduce defects in medicine, aviation, and architecture, with some dramatic medical stories thrown in for excitement. The basic idea is that humans are fallible, and a simple checklist can help us do things the right way every time, without overlooking something simple or skipping a step. This can be especially helpful in a stressful situation. It’s challenging to remember every step of a simple, mundane process when we don’t have a lot of time to think, if we’re distracted, or if we’re forced to multitask.

Although we’re drawn to stories of the brilliant creative genius, or the hero who reacted quickly under pressure, many times what really lies beneath these stories are established routines and engrained habits.

How Companies Learn Your Secrets“, an article by Charles Duhigg is a fascinating look at the analytics and marketing groups inside Target, and how, using existing data of their customer base, they determine within a degree of certainty, whether a female customer is likely to be pregnant. The statistical analysis behind that is interesting, but there’s another half of the same article which explores habit formation and how existing habits can be changed or manipulated. That’s because when a woman is pregnant, it is one of the main times in their lives when they are thrown into unfamiliar territory, and their shopping habits can dramatically change. If Target is there at this critical juncture, the thought is that they can be the new favored store for all kinds of things the expectant mother must buy.

This knowledge of habit manipulation is surely great for companies to use on their customer base in order to generate more sales, but it can also be useful to all of us at the individual level, in order to improve ourselves.

For most of our lives, when we’re not making major changes and just going about our day to day lives, we are operating mostly out of habit. When we operate out of habit, our brains go on autopilot. We’ve done this before, we’ve got it down, and we can do it blindfolded. This is true for everything from our morning shower routine to our commute to work. We don’t have to think much. This is our brain’s way of conserving energy.

A habit has a structure. The structure includes a “cue” – the thing that prompts us to begin the habit, a “routine” – the things we do to complete the habit, and a “reward” – the thing we get for completing the routine. Duhigg calls this “The Habit Loop”.

For example, take washing the dishes. The cue – seeing a pile of dirty dishes. This won’t do. The routine – clear the sink so you can work, start the hot water, put in some dish soap, soak the dirty dishes. Then clean something, rinse, repeat until all are done. The reward – a clean, empty sink, a strainer full of clean dishes. The second reward – if you do it daily, not that many dishes build up, so it gets done fairly quickly. All done until next time.

While washing dishes isn’t my favorite way to spend my time, at this point I do it out of habit, and I find it somewhat calming and relaxing. My brain gets to disengage from the task at hand and think about other things.

It can be very hard to change habits. By their nature, we do them without really thinking about it, and sometimes without even realizing it. One of the best ways the marketers have found to change a habit is to piggy back on to an existing habit.

In the article the example was Febreze. Initially, marketers originally sought to sell the product as an odor eliminator. The problem is, people become used to the smell of their own house and don’t realize it stinks. Ever been to a friends house and smelled an intense, overwhelming smell of dogs or cats and wonder how they stand it?

So, most people saw no need for a product like Febreze. Their houses were clean (or so they appeared) and of course they didn’t want to think of themselves as people whose houses stink.

The marketers found the solution by observing customers who actually used the product. A woman who loved it used it after cleaning every room in her house, as part of the reward – a little spritz of Febreze as the finishing touch. This was the key. Instead of trying to create a new behavior in customers – going around eliminating the odors in their stinky houses, the answer was to pitch Febreze as a product to incorporate into your existing cleaning routine as part of the reward.

How can we use this information to change and improve our personal habits and routines? Maybe there is something you want to start doing regularly, like writing, or exercising. Start by thinking about what existing habits you have, that you like to do or just do without thinking. What causes you to start? What is your reward for completing them? Here lies the answer. You can hijack your existing habits by planning to do a different routine or give yourself a different reward for an existing habit by figuring out the cue that triggers it.

For more info, see “How Habits Work” by the author of the article mentioned above, and the book “The Power of Habit“.

Comments Off on Checklists and Habits


I’ve been heads down working on a small, simple software app that is super simple but potentially pretty useful to individuals working within companies with more than a handful of employees. I’m finally getting close to finishing the first release.

I mentioned the idea to a friend one day last fall and he said “Yes! You should do it!” so I suspended work on the other side project I was working on and jumped right on it, since it would be super quick. I’d get it out there and be back to work on my other side project. Funny how that works.

The initial proof of concept was done in a couple days – you could get the idea of how it would work, but it was just a fake out. All that was left was to make it real. Simple, right? I kept at it for two weeks, then left for a three week trip, which brought progress to a halt. Once I got back from the trip, it was the holiday season and I needed to focus on billable work in December to make up for being gone. Finally in January I picked it back up. What initially seemed like something that could be done in a month has stretched into a few, but it’s so close.

Game Mechanics

The app is actually a game, which is my first foray into building something intended to be “played” – to be fun and challenging. Designing a game is super interesting, it’s almost like playing a game in itself, and eventually once you’ve built enough of it, you are indeed playing the game. Implementing game mechanics like scoring points, playing rounds, and thinking about how to make something fun and challenging vs. efficient and useful is super enlightening. The best part is that this app sits in the middle – it’s fun, but also useful and repeated play gives you real value in your actual life.

1 Comment

2012 Review

2012 was a big year, packed with travel, new business ventures, new experiences, and challenges along the way. I certainly didn’t stand still long.

In January I gave myself a 30 day challenge to eat healthier. It was tough, but fun being forced to think and do things differently. Making an arbitrary rule and sticking to it can highlight your patterns and break you out of well-worn grooves.

That was good preparation for February, when I would really need discipline. I set up Olio Apps and started working for myself again, splitting time between consulting and product development.

In March, O and I travelled to Hawaii, where we lived and worked remotely for a month. It was awesome to be in the warm sun and skip some of the cold and gray back home.

In April I travelled to Scottsdale Arizona for JSConf, which was full of brilliant people and ideas. Scottsdale was quite pleasant, but super dry. Your skin needs moisturizer in the south west, or you will rapidly turn to dust.

Late April through May we headed out again, this time living and working near the beach in St. Pete, Florida. It was great to spend some decent time with family and friends in the area I grew up, versus the momentary visits I generally have back home for holidays.

June was spent back in Portland, when the weather starts to get consistently nice again and all the fair weather cyclists come out for group rides and Pedalpalooza. I also spent part of the time preparing the two talks I gave at a technical conference.

In July I made up another silly month long challenge for myself, to write on this blog once a day, and run every other day. This time a friend decided to join me and proposed making a bet with actual money on the line if either of us failed. I accepted. We both managed to finish without losing the dough. Committing to blog every day is tough. Some days I’ll admit I had to just pull something out of my ass in order to win the bet. Doing a project or challenge like that is way more fun with a friend. Suddenly you’re accountable, pushing each other, and watching how the other is doing, instead of just talking yourself into it.

August found us white water rafting down the Rogue River and camping among the giant, ancient trees in the Redwood forest of California. So glad I got a chance to see them and hope to get back there again sometime soon.

September took us to Atlanta and the northern reaches of Georgia for my cousin’s wedding. This was the second wedding on my father’s side in the last couple years, and each time it’s like a big family reunion, because everyone lives so spread out now that rarely is everyone in one place. It was awesome to get to see everyone again.

In October, O surprised me with a weekend trip to Florida for my birthday, so we could attend my good friend’s annual haunted house / halloween blowout. It’s been happening nearly every year since I’ve moved to Portland and I finally got to go. It was terrifyingly amazing.

In November, I went to another tech conference, this time in Denver Colorado to attend my forth RubyConf, with my friends at The Clymb. After that I was back for a couple days before we took off to explore Japan and South Korea for 3 weeks.

In December, after all the travel we decided to stay put in Portland and enjoy being home for Christmas and New Years.


I successfully got a consulting business off the ground last year. I’ve done this before in ’05-’07 with Electro Interactive, so getting started again was fairly familiar. Once up and running, it was pretty much on autopilot, just finding clients and working diligently. I initially loaded up on client projects, but quickly decided that more than 3-4 is too much to juggle. I need to keep it simple if I expect to launch products in 2013. I’ve whittled it down to two active client projects at any one time. More is possible if full time consulting was the plan, but my end goal is to use consulting to bootstrap a product-focused business, so I’ve tried to hold consulting down to 50% of the time. Lately I’ve been doing more to make up for time off, and I plan to cut it back a bit.

I wanted to do more public speaking last year. I gave two talks at Open Source Bridge, an annual conference held in Portland. One talk was an intro to web development with Clojure, a language I started learning earlier in the year, and the other on building developer platforms, and my experiences while helping to do that at Jive Software. Presentations are hard to quantify in terms of a pay off – it takes a lot of preparation time, and a fair amount of stress, but it’s worth pushing yourself. It was great to have two of my proposals accepted, though in the future, I’ll only give one talk per conference. Better to keep it simple, focus on less things and do them better.

Travel was obviously part of the plan last year, and I think we knocked that one well out of the park.  I also visited two new countries this past fall, fulfilling an ongoing goal to explore the rest of the world. Travel reminds you of the open possibilities beyond the microcosm of your everyday life and breaks you out of your routine.


Top of the agenda for this year is launching projects initially started in 2012, both business-wise and creatively. There are a couple product ideas I intend to get launched by Q1. I plan to complete and release atleast one album with one of the musical projects I’m a part of. I plan to write here at a more regular cadence, either monthly or bi-monthly. In 2013 we haven’t made solid plans yet, but we may travel further and for longer stretches of time. The overall goal to simplify and focus more time on less things is paramount.

Happy new year and good luck with your own goals and plans for 2013.


Comments Off on 2012 Review

Deliberate Practice

I read the book “So Good They Can’t Ignore You” by Cal Newport. It’s a quick read and I recommend it. A little repetitive (before this book the guy wrote books on how to study, he repeats things so you’ll remember it). The key ideas are – blindly following your passion is bad advice – especially if you don’t know what your doing and are going to make a big switch to something you fantasize about but know little, and instead you should focus on the hard work of building the marketable / valuable skills in your field, aka “Career Capital”.

There were two other key takeaways for me. 1 – “deliberate practice” – putting in time getting better at the basics in whatever field you are in. Professional musicians and athletes are awesome at this. Knowledge workers not so much. 2 – the “adjacent possible” – which is what is waiting around the corner to be discovered once you’ve gotten to the edge of existing knowledge in your field. Once you get to that point, making the jump to that next discovery is easier. I’ve been trying to put in more time doing deliberate practice, building out my ideas and reading.

Comments Off on Deliberate Practice