SlideShare a Scribd company logo
Kevin Ball @kbal11
NPM Shrinkwrap
Do Your Future Self a Favor
Kevin Ball
http://kevinball.com
http://twitter.com/kbal11
Kevin Ball @kbal11
The Problem
//package.json
{
“dependencies”: {
“express”: “~3”,
“rendr” : “~0.5”
}
}
Kevin Ball @kbal11
The Problem
> npm install
rendr@0.5.2 node_modules/rendr
…
express@3.20.2 node_modules/express
Kevin Ball @kbal11
The Problem
> npm install
rendr@0.5.2 node_modules/rendr
…
express@3.20.2 node_modules/express
Three months later, in production…
Kevin Ball @kbal11
The Problem
> npm install
rendr@0.5.2 node_modules/rendr
…
express@3.21.5 node_modules/express
Three months later, in production…
Kevin Ball @kbal11
The Problem
Three months later, in production…
Image: CC courtesy of nirufe on Flikr
Kevin Ball @kbal11
The Problem
//package.json
{
“dependencies”: {
“express”: “~3”,
“rendr” : “~0.5”
}
}
Kevin Ball @kbal11
The Problem
//package.json
{
“dependencies”: {
“express”: “3.20.2”,
“rendr” : “~0.5”
}
}
Kevin Ball @kbal11
The Problem
//package.json
{
“dependencies”: {
“express”: “3.20.2”,
“rendr” : “0.5.2”
}
}
Kevin Ball @kbal11
The Problem
And still…
Image: CC courtesy of nirufe on Flikr
Kevin Ball @kbal11
The Problem
Unless every NPM package uses exact
package versions, you don’t have
reproducible builds!
Kevin Ball @kbal11
The Solution
NPM Shrinkwrap locks down your entire
tree of dependencies to the current
installed versions.
Kevin Ball @kbal11
The Solution
> npm shrinkwrap
> git add npm-shrinkwrap.json
> git commit -m “Saving myself from strife
down the road”
Kevin Ball @kbal11
Questions?
Kevin Ball @kbal11
NPM Shrinkwrap
Do Your Future Self a Favor
Kevin Ball
http://kevinball.com
http://twitter.com/kbal11

More Related Content

What's hot

Five Meteor Dev Power Tools - 2015-04-06
Five Meteor Dev Power Tools - 2015-04-06Five Meteor Dev Power Tools - 2015-04-06
Five Meteor Dev Power Tools - 2015-04-06
Mike Seidle
 
Fluxish Angular
Fluxish AngularFluxish Angular
Fluxish Angular
Filip Janevski
 
AngularU Recap
AngularU RecapAngularU Recap
AngularU Recap
Frank Linehan
 
Expressjs from-zero-to-hero
Expressjs from-zero-to-heroExpressjs from-zero-to-hero
Expressjs from-zero-to-hero
Nicola Del Gobbo
 
Do things faster and better with WebAssembly - Sendil Kumar Nellaiyapen - Cod...
Do things faster and better with WebAssembly - Sendil Kumar Nellaiyapen - Cod...Do things faster and better with WebAssembly - Sendil Kumar Nellaiyapen - Cod...
Do things faster and better with WebAssembly - Sendil Kumar Nellaiyapen - Cod...
Codemotion
 
SPA Flask Vue
SPA Flask VueSPA Flask Vue
SPA Flask Vue
Vanessa Böhner
 
20150309 seven core principles of meteor
20150309 seven core principles of meteor20150309 seven core principles of meteor
20150309 seven core principles of meteor
Rick Wehrle
 
Dev with github enterprise
Dev with github enterpriseDev with github enterprise
Dev with github enterprise
Hiroshi Wada
 
Exactly once delivery is a harsh mistress - DevOps Days TLV
Exactly once delivery is a harsh mistress - DevOps Days TLVExactly once delivery is a harsh mistress - DevOps Days TLV
Exactly once delivery is a harsh mistress - DevOps Days TLV
Natan Silnitsky
 
Writing a npm module
Writing a npm moduleWriting a npm module
Writing a npm module
Harsh Joshi
 
Synch calling asynchadd
Synch calling asynchaddSynch calling asynchadd
Synch calling asynchadd
prathap kumar
 

What's hot (11)

Five Meteor Dev Power Tools - 2015-04-06
Five Meteor Dev Power Tools - 2015-04-06Five Meteor Dev Power Tools - 2015-04-06
Five Meteor Dev Power Tools - 2015-04-06
 
Fluxish Angular
Fluxish AngularFluxish Angular
Fluxish Angular
 
AngularU Recap
AngularU RecapAngularU Recap
AngularU Recap
 
Expressjs from-zero-to-hero
Expressjs from-zero-to-heroExpressjs from-zero-to-hero
Expressjs from-zero-to-hero
 
Do things faster and better with WebAssembly - Sendil Kumar Nellaiyapen - Cod...
Do things faster and better with WebAssembly - Sendil Kumar Nellaiyapen - Cod...Do things faster and better with WebAssembly - Sendil Kumar Nellaiyapen - Cod...
Do things faster and better with WebAssembly - Sendil Kumar Nellaiyapen - Cod...
 
SPA Flask Vue
SPA Flask VueSPA Flask Vue
SPA Flask Vue
 
20150309 seven core principles of meteor
20150309 seven core principles of meteor20150309 seven core principles of meteor
20150309 seven core principles of meteor
 
Dev with github enterprise
Dev with github enterpriseDev with github enterprise
Dev with github enterprise
 
Exactly once delivery is a harsh mistress - DevOps Days TLV
Exactly once delivery is a harsh mistress - DevOps Days TLVExactly once delivery is a harsh mistress - DevOps Days TLV
Exactly once delivery is a harsh mistress - DevOps Days TLV
 
Writing a npm module
Writing a npm moduleWriting a npm module
Writing a npm module
 
Synch calling asynchadd
Synch calling asynchaddSynch calling asynchadd
Synch calling asynchadd
 

Similar to Npm Shrinkwrap

Kubernetes rolling back
Kubernetes rolling backKubernetes rolling back
Kubernetes rolling back
linuxdady
 
Verified CKAD Exam Questions and Answers
Verified CKAD Exam Questions and AnswersVerified CKAD Exam Questions and Answers
Verified CKAD Exam Questions and Answers
dalebeck957
 
CertsOut Linux Foundation-CKA Dumps.pdf
CertsOut Linux Foundation-CKA Dumps.pdfCertsOut Linux Foundation-CKA Dumps.pdf
CertsOut Linux Foundation-CKA Dumps.pdf
JeannieHeldt
 
Kubernetes and its Infrastructure - a walkthrough from the paths of container...
Kubernetes and its Infrastructure - a walkthrough from the paths of container...Kubernetes and its Infrastructure - a walkthrough from the paths of container...
Kubernetes and its Infrastructure - a walkthrough from the paths of container...
niharikadhanik
 
Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Clinton Dreisbach
 
Cloud-Native Builds & Deployments in Bitbucket Pipelines
Cloud-Native Builds & Deployments in Bitbucket PipelinesCloud-Native Builds & Deployments in Bitbucket Pipelines
Cloud-Native Builds & Deployments in Bitbucket Pipelines
Atlassian
 
AWS re:Invent 2016: Amazon ECR Deep Dive on Image Optimization (CON401)
AWS re:Invent 2016: Amazon ECR Deep Dive on Image Optimization (CON401)AWS re:Invent 2016: Amazon ECR Deep Dive on Image Optimization (CON401)
AWS re:Invent 2016: Amazon ECR Deep Dive on Image Optimization (CON401)
Amazon Web Services
 
10 ways to shoot yourself in the foot with kubernetes, #9 will surprise you! ...
10 ways to shoot yourself in the foot with kubernetes, #9 will surprise you! ...10 ways to shoot yourself in the foot with kubernetes, #9 will surprise you! ...
10 ways to shoot yourself in the foot with kubernetes, #9 will surprise you! ...
Laurent Bernaille
 
Monitoring kubernetes with prometheus
Monitoring kubernetes with prometheusMonitoring kubernetes with prometheus
Monitoring kubernetes with prometheus
Brice Fernandes
 

Similar to Npm Shrinkwrap (9)

Kubernetes rolling back
Kubernetes rolling backKubernetes rolling back
Kubernetes rolling back
 
Verified CKAD Exam Questions and Answers
Verified CKAD Exam Questions and AnswersVerified CKAD Exam Questions and Answers
Verified CKAD Exam Questions and Answers
 
CertsOut Linux Foundation-CKA Dumps.pdf
CertsOut Linux Foundation-CKA Dumps.pdfCertsOut Linux Foundation-CKA Dumps.pdf
CertsOut Linux Foundation-CKA Dumps.pdf
 
Kubernetes and its Infrastructure - a walkthrough from the paths of container...
Kubernetes and its Infrastructure - a walkthrough from the paths of container...Kubernetes and its Infrastructure - a walkthrough from the paths of container...
Kubernetes and its Infrastructure - a walkthrough from the paths of container...
 
Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3
 
Cloud-Native Builds & Deployments in Bitbucket Pipelines
Cloud-Native Builds & Deployments in Bitbucket PipelinesCloud-Native Builds & Deployments in Bitbucket Pipelines
Cloud-Native Builds & Deployments in Bitbucket Pipelines
 
AWS re:Invent 2016: Amazon ECR Deep Dive on Image Optimization (CON401)
AWS re:Invent 2016: Amazon ECR Deep Dive on Image Optimization (CON401)AWS re:Invent 2016: Amazon ECR Deep Dive on Image Optimization (CON401)
AWS re:Invent 2016: Amazon ECR Deep Dive on Image Optimization (CON401)
 
10 ways to shoot yourself in the foot with kubernetes, #9 will surprise you! ...
10 ways to shoot yourself in the foot with kubernetes, #9 will surprise you! ...10 ways to shoot yourself in the foot with kubernetes, #9 will surprise you! ...
10 ways to shoot yourself in the foot with kubernetes, #9 will surprise you! ...
 
Monitoring kubernetes with prometheus
Monitoring kubernetes with prometheusMonitoring kubernetes with prometheus
Monitoring kubernetes with prometheus
 

More from Kevin Ball

Flexible UI Components for a Multi-Framework World
Flexible UI Components for a Multi-Framework WorldFlexible UI Components for a Multi-Framework World
Flexible UI Components for a Multi-Framework World
Kevin Ball
 
Modern javascript
Modern javascriptModern javascript
Modern javascript
Kevin Ball
 
Understanding the Nesting Structure of the Ember.js View Layer
Understanding the Nesting Structure of the Ember.js View LayerUnderstanding the Nesting Structure of the Ember.js View Layer
Understanding the Nesting Structure of the Ember.js View Layer
Kevin Ball
 
Intro to Javascript
Intro to JavascriptIntro to Javascript
Intro to JavascriptKevin Ball
 
Underscore.js
Underscore.jsUnderscore.js
Underscore.js
Kevin Ball
 
Omniauth: Future Proof Your Authentication
Omniauth: Future Proof Your AuthenticationOmniauth: Future Proof Your Authentication
Omniauth: Future Proof Your Authentication
Kevin Ball
 
Ruby 1.9 Fibers
Ruby 1.9 FibersRuby 1.9 Fibers
Ruby 1.9 Fibers
Kevin Ball
 

More from Kevin Ball (7)

Flexible UI Components for a Multi-Framework World
Flexible UI Components for a Multi-Framework WorldFlexible UI Components for a Multi-Framework World
Flexible UI Components for a Multi-Framework World
 
Modern javascript
Modern javascriptModern javascript
Modern javascript
 
Understanding the Nesting Structure of the Ember.js View Layer
Understanding the Nesting Structure of the Ember.js View LayerUnderstanding the Nesting Structure of the Ember.js View Layer
Understanding the Nesting Structure of the Ember.js View Layer
 
Intro to Javascript
Intro to JavascriptIntro to Javascript
Intro to Javascript
 
Underscore.js
Underscore.jsUnderscore.js
Underscore.js
 
Omniauth: Future Proof Your Authentication
Omniauth: Future Proof Your AuthenticationOmniauth: Future Proof Your Authentication
Omniauth: Future Proof Your Authentication
 
Ruby 1.9 Fibers
Ruby 1.9 FibersRuby 1.9 Fibers
Ruby 1.9 Fibers
 

Recently uploaded

AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
 
E-commerce Application Development Company.pdf
E-commerce Application Development Company.pdfE-commerce Application Development Company.pdf
E-commerce Application Development Company.pdf
Hornet Dynamics
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
Roshan Dwivedi
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
Google
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
NYGGS Automation Suite
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
Drona Infotech
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
Ayan Halder
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
Paco van Beckhoven
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Łukasz Chruściel
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
Alina Yurenko
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
Shane Coughlan
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
Max Andersen
 
AI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website CreatorAI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website Creator
Google
 

Recently uploaded (20)

AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
 
E-commerce Application Development Company.pdf
E-commerce Application Development Company.pdfE-commerce Application Development Company.pdf
E-commerce Application Development Company.pdf
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
 
AI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website CreatorAI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website Creator
 

Npm Shrinkwrap

  • 1. Kevin Ball @kbal11 NPM Shrinkwrap Do Your Future Self a Favor Kevin Ball http://kevinball.com http://twitter.com/kbal11
  • 2. Kevin Ball @kbal11 The Problem //package.json { “dependencies”: { “express”: “~3”, “rendr” : “~0.5” } }
  • 3. Kevin Ball @kbal11 The Problem > npm install rendr@0.5.2 node_modules/rendr … express@3.20.2 node_modules/express
  • 4. Kevin Ball @kbal11 The Problem > npm install rendr@0.5.2 node_modules/rendr … express@3.20.2 node_modules/express Three months later, in production…
  • 5. Kevin Ball @kbal11 The Problem > npm install rendr@0.5.2 node_modules/rendr … express@3.21.5 node_modules/express Three months later, in production…
  • 6. Kevin Ball @kbal11 The Problem Three months later, in production… Image: CC courtesy of nirufe on Flikr
  • 7. Kevin Ball @kbal11 The Problem //package.json { “dependencies”: { “express”: “~3”, “rendr” : “~0.5” } }
  • 8. Kevin Ball @kbal11 The Problem //package.json { “dependencies”: { “express”: “3.20.2”, “rendr” : “~0.5” } }
  • 9. Kevin Ball @kbal11 The Problem //package.json { “dependencies”: { “express”: “3.20.2”, “rendr” : “0.5.2” } }
  • 10. Kevin Ball @kbal11 The Problem And still… Image: CC courtesy of nirufe on Flikr
  • 11. Kevin Ball @kbal11 The Problem Unless every NPM package uses exact package versions, you don’t have reproducible builds!
  • 12. Kevin Ball @kbal11 The Solution NPM Shrinkwrap locks down your entire tree of dependencies to the current installed versions.
  • 13. Kevin Ball @kbal11 The Solution > npm shrinkwrap > git add npm-shrinkwrap.json > git commit -m “Saving myself from strife down the road”
  • 15. Kevin Ball @kbal11 NPM Shrinkwrap Do Your Future Self a Favor Kevin Ball http://kevinball.com http://twitter.com/kbal11