Building Digital

Startups, Engineering, JavaScript

Tuesday the 23rd of March 2015 joe8bit.com/talk/uit-startup/

Joe Pettersson

@Joe8Bit | github.com/Joe8Bit

Raising Money

Don't raise money, bootstrap as long as you can

Raising capital is the easiest thing a successful founder will do

  • Hiring engineers is harder
  • Building a culture is harder
  • Getting viral growth for a B2C business is harder
  • Selling to enterprises for B2B is harder
  • Growing advertising revenue is harder

The fundamental problem

  • 4000 VC fundable companies each year
  • 200 funded by 'top tier' VCs
  • 15 will someday reach a market cap of $100 million+
  • Those 15 will generate 97% of returns for entire VC sector for that year

Extreme outliers

What investors look for

  • Great founding team
  • Solid idea
  • In growth sector
  • Solving a real problem
  • Consumer early adoption, metrics matter
  • Working product
  • Understanding of success
  • Distribution and business development - sales!

Prepare your message

  • Good elevator pitch. Tell me in one sentence what you do. Practice it and make it compelling
  • Make your pitch deck sing
  • Exec summary in your pitch deck

Founders

  • Born leaders, lead by example, 24/7
  • Procrastination is death, decisiveness is king
  • Rifle focused, strong willed by flexible (good listeners)
  • Why did you do this? Does it solve a personal problem?
  • Communication focused
Almost always better to work hard on your business that it is to work hard on raising capital

Advisors are the best or the worst thing to happen to your company

Hiring

Know who you're looking for

  • Skills? Technical skills?
  • Role
  • Responsibilities
  • Personality

When are you hiring?

  • Seed stage?
  • Venture stage?
  • Growth stage?

Compensation

  • Salary/equity mix
  • Try to think in absolute $ terms with equity, not relative percentages
  • Being cheap and/or screwing people will backfire
  • Understand the talent market your working in
  • Reassess compensation against the market quarterly

Interviewing

  • Tech interviewing is broken.
  • Puzzles are bullshit
  • Treat people with respect, value their time
  • You need to sell your organisation to the best engineers
  • Open source is great, but don't use it exclusively
The best engineers don't care about tools at a macro level, they solve problems with whatever technology best suits
Avoid specialisation as long as it's reasonable to do so

Engineering

Tools should be fit your problems, your problems shouldn't be fit to your tools

"We build all our [domain] in [technology], so we're going to use [technology] for everything"

Don't silo your people, their skills or their work. People are motivated by transformational change, give it to them.

Pay money to make things "not my problem". Spend time on your business, concentrate on where your value lies.

Releasing fast and releasing often are key, pick a stack that is conducive to that.

Test everything. Unit, functional and integration testing*

However, working and in production is better than tested and not.

Analytics lead product development, base decisions on key metrics. Data based product development.

Beware the GPL (et al)

Getting hired

Reminder: technical interviewing is broken

Some sample interview processes

Try to be technology agnostic

Definitely be framework agnostic

Try to contribute to open-source projects, or create your own

Attitude and aptitude

JavaScript skills

  • The JS stack/execution model
  • The DOM API
  • Scoping (this, let, bind/call, hoisting, closures etc)
  • Async
  • Performance
  • Types and grammar (primitive types etc)
  • Testing

System design

Code structure, modularity, dependency injection etc

CSS. Ugh.

Don't bother, use SASS/LESS/Stylus.

Framework's

Angular, Ember, React etc

Algorithm's, "Big-O" complexity etc

Never be afraid to say you don't know

Know your value, they want you more than you want them

Talent sourcing

  • 25% internal personal recommendations
  • 10% direct channels
  • 65% third-party referrals

Angular

It's core value is massive for startups

You probably don't need two-way binds

Use {{:: foo}} expressions instead

The digest loop will eventually bite you on the ass

Use an isolate scope for element directives. Share scope for attribute directives

Use element directives when content is injected, else use attribute directives

Use UI-Router. Routes are state, embrace a router that follows that representation

While you're at it, use controllerAs when referencing scope

Use resolvers

View is rendered once, user doesn't see flash, makes testing much easier

// Recommended
$stateProvider.state('customers.show', {
  url: '/customers/:id',
  template: template,
  controller: 'CustomersShowController',
  controllerAs: 'ctrl',
  resolve: {
    customer: [
      'Customers',
      '$stateParams',
      function customerResolver(Customers, $stateParams) {
        return Customers.findOne({
          params: { id: $stateParams.id }
        });
      }
    ]
  }
});

// Avoid
// Note: Controller written inline for the example
$stateProvider.state('customers.show', {
  url: '/customers/:id',
  template: template,
  controllerAs: 'ctrl',
  controller: [
    'Customers',
    '$stateParams',
    function CustomersShowController(Customers, $stateParams) {
      var ctrl = this;
      Customers.findOne({
        params: { id: $stateParams.id }
      }).then(function(customers) {
        ctrl.customers = customers;
      });
    }
  ]
});

Inject ready data instead of loading it in the controller.

// Recommended
angular.module('customersShowControllerModule', [])
  .controller('CustomersShowController', [
    'customer', 'payments', 'mandates',
    function CustomersShowController(customer, payments, mandates){
      var ctrl = this;

      _.extend(ctrl, {
        customer: customer,
        payments: payments,
        mandates: mandates
      });
    }
  ]);

// Avoid
angular.module('customersShowControllerModule', [])
  .controller('CustomersShowController', [
    'Customers', 'Payments', 'Mandates', '$stateParams',
    function CustomersShowController(Customers, Payments, Mandates, $stateParams){
      var ctrl = this;

      Customers.findOne({
        params: { id: $stateParams.id }
      }).then(function(customers) {
        ctrl.customers = customers;
      });

      Payments.findAll().then(function(payments) {
        ctrl.payments = payments;
      });

      Mandates.findAll().then(function(mandates) {
        ctrl.mandates = mandates;
      });
    }
  ]);
					

Store presentation logic in controllers and business logic in services

Don’t manipulate DOM in your controllers, this will make them harder to test. Use directives instead.

Do not use jQuery selectors

Tear down your directives

Subscribe to $scope.$on('$destroy', ...) to get rid of any event listeners or DOM nodes created outside the directive element

angular.module('adminExpandComponentModule', [])
  .directive('adminExpand', [
    '$window',
    function adminExpand($window) {
      return {
        restrict: 'A',
        scope: {},
        link: function adminExpandLink(scope, element) {
          function expand() {
            element.addClass('is-expanded');
          }

          $window.document.addEventListener('click', expand);

          scope.$on('$destroy', function onAdminExpandDestroy() {
            $window.document.removeEventListener('click', expand);
          });
        }
      };
    }
  ]);

Don't directly reference globals

That's what providers are for

Selenium is crap, so it can make protractor E2E test's flaky

Move towards Angular 2 sooner rather than later

ES6 modules, transpilation et al

Questions?