Skip to content
Code Analysis with Dan Silivestru and Gord Tanner episode artwork

Apr 5, 2016 50 min

Code Analysis with Dan Silivestru and Gord Tanner

from JavaScript Archives - Software Engineering Daily Hosted by Pranay

“JavaScript as a language is evolving year over year with new implementations and new language features, and we need to make sure we stay on top of those.” Code analysis tools can help a developer understand code. One tool for code analysis is bitHound, which provides code and dependency analysis for NodeJS applications. On today’s The post Code Analysis with Dan Silivestru and Gord Tanner appeared first on Software Engineering Daily.

Episode details come from the podcast's RSS feed.

Embed this episode

Ready to play

Code Analysis with Dan Silivestru and Gord Tanner

0:00 50:07
of matches

Transcript Auto-generated, may contain errors

Code analysis tools can help a developer understand code. One tool for code analysis is Bithound, which provides code and dependency analysis for Node.js applications. On today's episode, we discuss how to use a code analysis tool, and we also talk about how to build one by breaking down the distributed architecture of Bithound's backend. This is a really interesting episode about a product that many developers are going to be using in the future, whether it's specifically Bithound or any code analysis tool.

This is the type of tool that will help developers save time and avoid dependency problems in the future, or security problems, all kinds of other problems. If you're a fan of Software Engineering Daily, we want to know how to improve. Please take five minutes to fill out our listener survey. There's a link to the survey in our newsletter and on our website.

We would love to know what you think. We want to know what you want to hear more of, what you want to hear less of. And as soon as we get enough respondents, we will stop hammering on the survey. But we really want to get a representative amount of data, and people still haven't really filled out the survey.

Many people have, but we want more. So we really want to build the best software podcast, so please respond to the survey. Bithound is a tool for Node.js code analysis. Gord Tanner and Dan Silvestri are the CTO and CEO of Bithound.

Gord and Dan, welcome to Software Engineering Daily. Thanks for having us. Good to be here. So this episode is about code analysis.

What does that term mean, code analysis? Well, code analysis in its most basic form is essentially programmatically breaking down the software that you're looking at. So taking the code, breaking down what's called an ASD or abstract syntax, and then being able to crawl that and try and expose a whole bunch of insights to help developers essentially do a better job. So that could be as simple as linting, making sure that stylistic guides are being followed.

And then there's more complex things like looking for duplicate code or complexity within various code branches, and it expands well beyond that as well. As developers, we give off lots of data while we are writing our code and when we're working on projects. And this data accumulates in GitHub repositories and across our test runs and when we open and close bugs. And as our data accumulates, it is building latent value.

And I think Bithound helps to expose some of that value. So give me an idea of the value of this type of information that we are giving off as we develop applications. Yeah, that's actually kind of the genesis of the idea for Bithound was looking at all this data that we do generate as we commit to our repositories, as we comment our code, as we open and close bugs and issue trackers, as we run our tests, as we release software and build software. There's just a lot of data that is created as we work alone and together and on teams.

And I came from the call center software industry where data is created in that industry. It's all about call wait times. It's all about how long people are on hold, how many people are converting to a sale from a call. So taking inspiration to that, I always wondered, are we at a point when we can start to use some of this information that we generate as developers to build better software and better software teams?

Cool. Okay, so you mentioned using an abstract syntax tree to evaluate some code or other information. Listeners may be familiar with the abstract syntax tree because it's something that we use to parse our programming languages so that we can evaluate them and actually run code. Give me an idea of how the Bithound product actually works.

What kind of work you're doing when you build an abstract syntax tree for somebody's code and what you're assessing when you evaluate that syntax tree? Right. So I think what Bithound does, it goes well beyond just parsing the ASD to gain information, like Gordon mentioned before, in terms of the amount of data that's generated. And Bithound tries to think of the code also in a historic sense, right?

So parsing the ASD allows us to look for blemishes in the code itself or structure issues. It's a much easier way to find things like the code and complexity. But then coupling that information with the historic information that we get generated by all of these developers and teams around us allows us to start assigning fragility sorts to files. Basically, how often are they attached?

For what reason? How many bug fixes are there versus actual work that's being done to give us kind of a bug-prone measure of those files? And when you take that and you couple it with the blemishes in the code, you can start assigning better severity sorts on whether or not something needs to be addressed based on how fragile that code is. So we think about Node.js or JavaScript code versus a language like Java.

I think of Java as a language that is better at catching your errors. And Java would be perhaps a language that – is it no? Not accurate? Okay.

Yeah, just because of exception handling and whatnot. How does that contrast with JavaScript? And why does it give rise to a need for a tool like Bithound? Well, JavaScript – I mean, I love the language that I'm sure it has as well.

There are probably a thousand different ways to write JavaScript, right? And there's good ways, there's bad ways. There are the good parts and the bad parts. And those do continue to evolve as the language itself evolves.

You know, JavaScript was designed in roughly 10 to 11 days. And I think one of the core needs for it was because they expected to have developers coming from all walks of life and all different past experiences. They need to be able to be written in various different flavors. So someone who's coming from, like, a C world or a Java world, you know, could actually relate to the language.

And so – and the language itself is dynamic, right? It's not static-typed. There are a lot of very simple mistakes that you can make, such as just a typo in a variable name. And the language won't stop you from doing that.

It will just make that thing global and let you keep running, which could result in some very interesting bugs and, you know, issues down the road. So I think with JavaScript, there's much more of a monitoring and, you know, need for conforming to standards and having these kinds of continuous checks on your code. Because very simple mistakes, you know, it being a non-compiled language but an interpretive language, makes it such that you will catch those issues, but you won't catch them until runtime. Which is probably, you know, in the scale of where's your highest cost to catch a problem?

You know, it's production, then at runtime, you know, and the cheapest one is when developers actually actively typing a keyboard. So we're talking about code analysis in the abstract, and a subset of code analysis is dependency analysis. Why is dependency analysis so important in Node projects? Well, actually, something we teased out as we dove deeper into working on BitHound as well as what our customers were doing.

We thought originally our focus was entirely on lane-to-code-style, like, static code analysis. But as we were working with our project and working with other people's projects, we started to notice that the need to keep track of dependencies was a problem that we were having and that everyone else was having. The Node ecosystem is an amazing place where there are literally thousands and thousands of different third-party components you can use to build up your project. And keeping tabs on them is quite a chore that sometimes gets put off the side as you're focusing on other issues.

And so as we were writing BitHound and writing the dependency analysis for BitHound, we found we were able to give our customers and our users the ability to have someone else watch that for them so they can focus on more important things. And have that ability to watch the dependencies for when they go out of date, when they have potential security advisories, when they're deprecated, or they can start to be unused. We give them the tools to detect that and to update accordingly. Let's get into the usage of BitHound.

So let's say I'm getting started with a project and I want to use BitHound. Let's say I'm the developer of AngularJS or GulpJS. I think these are both projects that use BitHound. But let's say I'm just getting started with one of these projects and I'm like, okay, I want to get started with BitHound.

I want this code analysis suite of tools. How do I get started and what is the onboarding process like? That's a good question. We try to keep it as simple as possible.

I mean, our customers, being developers and managers, CTOs, are busy enough, as it is, and having to configure a product before you even get a chance to get started with it is quite a chore. So really, you sign in or sign up for BitHound using BitBucket or GitHub, just your credentials, you're all locked in. You're instantly presented with a list of all of your projects, private and public. All you literally have to do is click the big green button that says Add a Project.

We instantly kick off analysis on it. We tie in webhooks so that we're aware of every new commit that comes in. And we integrate with your PR process so that as development continues to happen and as pull requests are being issued by your developers, BitHound can pass-fail those pull requests based on your criteria. So that's where things just get started.

And very quickly afterwards, you get one click at the Slack integration. We also have a CLI so you can integrate with your build system in case you want to start failing your builds. It should say a security vulnerability be detected on your dependencies or if complexity goes beyond a certain critical point. So you've mentioned these other code analysis tools like Linters.

So as we're discussing kind of a use case of somebody getting started with BitHound, compare their experience with BitHound, what that would look like versus how they would experience older tools like Linters or whatever other tools you're seeing people compare BitHound to. Absolutely. So, I mean, it's an important note. I think we actually recommend to all our customers that they have Linters implemented and configured for their local development environment.

What BitHound does is it takes all of these analysis results and merges them together and then augments them with other insights and other analysis that we do, such as understanding fragility of certain files, whether or not they're bug-prone, and the amount of work that happens on it normally. And what BitHound does is rather than you having to go to five different places or integrate multiple command line calls into your CI or your local environment and making sure that all of your developers have it all configured the exact same way, BitHound provides you with an instant dashboard that highlights the things that are most important for your team to address. So essentially generate these priority items, the things that you really should be looking at, and give your recommendations on how to fix them. And then beyond that, we have to integrate into your workflow so that essentially your team and yourself can continue to focus on what's really important, which is your features, your tight deadlines, and allow BitHound to essentially be your security blanket and making sure that the entire team is living with the same standards and the same styles and isn't getting themselves in trouble by accidentally shipping something that could put your product and your company at risk due to some security advisory or vulnerability access.

What we can do above and beyond industrial standard Linters is what we provide is context. Because we're running more than just Linters, we're running more than just like your standard run-of-the-mill analysis. We take all these data points that we're collecting and monitoring and bring them together for context as to what, like Dan said, what is most important, what Linters, what file do you need to look at, what dependency is currently the one you should focus on, which is just, that's what we can provide doing all the analysis and bundling together, which is quite hard with the standard tool stack for this. And in a typical workflow, when are people finding actionable information with BitHound?

Is it like I write some code, I ship it to the repository, I ship it to the repository, and my continuous integration tool kicks off, and then BitHound is somewhere in the continuous integration tests? Or how does that work exactly? BitHound is actually sitting quite a bit closer to the developer than that, right? So every time a commit goes in, BitHound goes to work on it, analyzes it, and then provides valid results.

And if anything is found, then a Slack message goes out, or if a developer didn't issue a pull request, then we can set pass or fail it. At the same time, the developers might not have done anything for the past week, but a new security vulnerability might have been detected on one of the dependencies that they have. So BitHound will proactively alert the developer and the entire team through either an email or a message into Slack or HipChat to alert you to the fact that you are now exposed due to a vulnerability. Okay, this is really cool.

So now I'm kind of starting to get it like, you know, as a developer, you're writing software, but the velocity at which software engineering is changing, just the environment around it, and the velocity at which security vulnerabilities get discovered, that is all increasing. So BitHound is just like this layer where it's constantly sniffing out problems that could occur. You can almost think of them as like metagame changes that are occurring in the software development ecosystem. Yeah, I think what's happening is we're approaching a point in time where there's more software being written.

It's more complex. It's being written faster and at volumes, which we were unprecedented even a few years ago. So we're hitting that inflection point where it's getting to the point where you have to analyze software, software. The human cost and brain space of keeping on tabs of all this is starting to approach an unmanageable level, and that's where services like BitHound, that's what we're jumping in to provide, the ability to alleviate some of that pressure you have on your already full day to keep on tabs of all this information coming at you.

That's right, and if I might add to that, we tend to think of our development team as being made up of our core developers and our team members themselves, right? So, for example, a team of five, we tend to think of ourselves and four other people that are building code. But if you're taking proper advantage of NPM and all these external third-party open-source modules, right, your team is actually potentially made up of hundreds and thousands of people, a lot of which you have embedded, and all hard, hard at work at getting those components to continue to evolve and fixing bugs and performance issues and all those kinds of things, we no longer have the ability to, as individuals, keep tabs on all of that without automating that process in some way or fashion. So now that we have an interesting idea of how BitHound works, I want to talk through an engineering problem that you guys have dealt with at BitHound.

So in order to understand the health of an individual project, you might have to do analysis on thousands of commits to a project. And so there's so many things to look at. So if BitHound servers are running and they're trying to analyze all these different projects, the analysis of thousands and thousands of commits and all these lines of text, I guess describe the challenges that are associated with this problem. It was an interesting problem, which starting day one, when we sat down and said, this is what we're going to build, I had a strong knowledge that this was going to be a distributed problem.

We couldn't sit in one process and monitor every commit that's coming in on every file. There's a CPU cost, there's a time cost, there's an I.O. cost that is involved for analyzing this. As we all know, we run our builds, we run our tests, we clone repositories, we run LinkedIn.

We know there's time. You can feel that in your own environment as you're working. So scaling that up to the scale of which we are, where we're analyzing thousands upon thousands of projects a day, like hundreds of thousands of lines of code, you can imagine that you can't do that in one process. So from day one, we broke out into a distributed model to have all of our tasks be defined in the smaller work sets that we could send out to random workers.

Describe the concurrency model a little more, the distributed model. What was the granularity of concurrency and how did you distribute that work? Well, yeah, concurrency, there are a few ways to do concurrency. There's the traditional shared memory model where you take some physical location on a computer in memory or RAM or even in a physical file and all your processes work together sharing it, thinking of passing the butter dish around at your kitchen table.

It gets kind of tricky when someone tries to grab a butter dish before someone else is done with it. So that usually is a more complicated way to do panel concurrency. You can end up with what are known as deadlocks or like... other similar cases.

Now, another case which we actually went with, which you know worked really well, was message passing, where rather than passing the butter dish, you pass messages about the state of the butter dish. So you can say, well, this analogy is starting to break down horribly, but rather than sharing a physical item, you're sharing messages and information about that item that people can do with what they will. So there's no, once I send a message out into the world, I don't care what happens about messaging. I'm not sharing something physical, I'm sharing information.

Okay, so you went with the message passing model. How did that fit around this problem statement of analyzing thousands of commits? It worked quite well. At first, there was a small problem, because obviously there is a butter dish in the way of your repository.

Like, we have to clone that somewhere. We have to have it physically located somewhere on disk. So that was kind of an initial issue. But once we had that in place, it's just a matter of we would build up messages about files that we want to look at or analysis we want to run, and just send those out.

And it worked really well with Node because of asynchronous I.O., the easy network stack. We chose 0MQ as a base messaging layer that allowed us to build a pretty flexible network and not worry about a lot of that networking hiccups as, okay, the server has to be up before the client connects, or what happens if we lose connection? All that was handled under the hoods for us. So we could just, especially as easy as it is to write to an event emitter in Node, code.

We could just fire events transparently in our code. And for all I know, it could be handled in my process, in a process next to me, controlled by a shared cluster manager, or in a completely different data center, or a completely different machine. So can you contrast that with how you would apply a message passing solution if you were working in Golang or Erlang, or one of these other languages that we hear more closely associated with message passing architectures? Now, a lot of those languages have a much more expressive concurrency set of primitives that you have available.

JavaScript bias major has one thread, so you're only ever doing one thing, where some of these other languages have the ability to do shared memory, shared state, a little more expressiveness around when you lock things, when you don't lock things. And Go with its Go routines has a really beautiful, expressive way of dealing with subroutines and subprocesses and message passing between them. So every language has its pros and its cons. I think what we got from JavaScript and Node was lack of choice, almost, I don't want to say.

We had kind of callbacks and asynchronous I.O., and we kind of lived in that small, small constraint box on how we can communicate. It also gives us a great opportunity to, pardon the pun, but dog food our own product, right? Because we're fully built in JavaScript, and it allowed us to really put Benhound as a product through its faces and make sure that we're building something that is providing value and is worthwhile for us, and that we can use on the other races. And not to mention, there are good reasons for just using Node otherwise.

You've said Node is a great language for glue code, almost like Perl in some ways. So what types of glue code, what types of scripting tasks do you find yourself using from Node? That's actually interesting. Because we're a massively distributed system, we've gone with the idea that failure is almost the normal rather than the exception.

Because we're dealing with hundreds of processes running across hundreds of machines, we have to expect that machines are going to die, that network's going to kick up, that disk space is going to run out, that all these exceptional cases that you can run on like your standard install end up being not so exceptional. So with the idea of glue code, a lot of our paths are essentially Node processes that are wrapped in an easy-to-use command line that we string together via shell scripting or via other Node processes. So it just worked really well with the concept of the Unix-style small tools where you have standard in, you have standard out. So you're just passing information between them, and you can build it in a way that one part failing doesn't cause the rest of your tool chains to fail out.

And the lack of having states associated with each one of these processes means that if they do die, and we never hear back from them, they just get recued, and they start working again, and the system essentially self-recovers. So in order to architect this distributed problem, you built a master-slave architecture. Describe how that master-slave architecture works, and maybe if you could give a small example of, you know, you've got a thousand, you've got a bunch of GitHub repositories, you've got a bunch of commits to evaluate on this architecture, how would the work be distributed up among this master-slave architecture? Okay, yeah, that was actually, it was interesting, because that's how we started.

We had like a main controller process that would grab a job such as analyze a repository. This controller would start off figuring out how many commits are in this repository, clone it down, figure out all the files that we would need to look at, and then send out those other jobs off to like worker processes. And we quickly found that as we were performance tuning this, it got, those workers would eventually need to split out jobs of their own. So there was never this concept of a master controller process anymore, that every single process needed to be able to spawn sub-processes back in the cluster to do their job.

So for an arcade... Is this still like a hierarchy? There is no hierarchy, actually. It's kind of a giant mesh-style network where you, anyone in the network, can just send out a message, or a group of messages, and have them all be processed and sent back.

So, for example, in our case of analyze a repository, first step, clone it, break it into the commits, send each commit out into a message, that commit can then further be turned into specific file tasks that get sent out, and so on and so forth. And it's a delicate balance of finding the granularity of the messages and tasks you want to work on versus the distribution of them. Because sometimes it's just faster to iterate over a list of 2,000 files rather than breaking them into bulk groups of 50 and distributing them. It's just a flexibility you kind of work with as you're playing with distributed systems.

Sure. And for this system, you built a module called Farm that is open-source. Tell me about Farm. Yeah, so Farm is kind of that base messaging layer we have in all of our worker processes.

It was an easy-to-use kind of DSL around the sockets of 0MQ and sending it all up. It was more of a thought exercise of opening source up just so we could talk about what we do so people can look at CD examples. I know we're using it, but I'm not sure if anyone else is. But yeah, it was just the ability to have that common module that all our processes can use and our other team members don't need to spend the amount of time that I do thinking about our network architecture or how to send these messages or what happens when one of them dies.

So it's a nice way, but one of the cool things that came out of it was the idea of our global event published subscribe system that was really interesting because we're all familiar with the event emitter node where it can publish and subscribe messages in your process. With Farm, which is what we were able to do, we built that into a global published subscribe. So every single service and process in our entire network can publish and subscribe messages across all machines. So we use it a lot for our analytics monitoring to kind of keep the state on the system to kind of go, okay, well, I've worked on this many tasks today.

Or we'll have a command called census, which we will fire out. We'll send a command line to census and it sends a message out to every single process and just ask them to fill out some information. They'll report back on like, this is what I'm currently working on. This is how many things I've done.

And we have a long form census result that comes back from every single worker that is currently in the system we can use for tuning or discovering workers that could potentially be in a condition where we need to restart them. When you launched BitHound initially, you went from having your distributed environment running on a laptop to a distributed environment running across hundreds of boxes. Describe the difference between BitHound as it worked locally and what happened when you launched it to production. Yeah, it's an interesting story.

We were developing with the thought of distribution. I remember it was the first JSConf we kind of came in and sponsored. And the system we kind of run on our laptops and a couple of our Linux dev machines we had. And we made a few assumptions about states so that that repository we cloned.

For example, like when we were working on your code, we don't keep any of your code. We just keep metadata about it. So we'll clone a repository, analyze all the metadata, and delete it. And as we were working on this, we were like, oh, I'll clone this.

And then all the other processes had the ability to go, oh, well, is the repository currently existing somewhere I can access? Yes. If not, how do we clone it? So if you imagine a repository coming in on your local machine, you clone it once, you have 10 workers, they're all on the same machine, all 10 of those can do the easy, although it already exists, I don't need to reclone it.

When you're going across hundreds of machines, which we work for our production environment in JSConf, that case of shared state, which we heavily assumed and worked nicely, all of a sudden every single project would clone hundreds of times, which you don't really get to experience until you start actually distributing the code. Certainly. That's an interesting story. So another thing I've heard you mention is that you use Vagrant to bridge the gap between your dev and prod environments.

And we have the founder of HashiCorp coming on the show in a couple weeks, so I'd love to hear more about Vagrant. Like, how do you use it? How does it bridge the gap between your dev and prod environments? What Vagrant gave us, so for those people who are just hearing this term, Vagrant is a simple way to build and provision virtual machines on your local dev environment.

So you can define in a simple file like three, four different machines, their roles, and some scripts to run to provision them. So the way we use Vagrant is, rather than developing on our MacBooks or our Linux dev machines, we use Vagrant to create three to four virtual machines that are then running the same OS as our production environment in the same configuration. And using the same scripts as when we're starting up a new instance in the cloud, we will run those same scripts over and over as we start up these virtual environments locally. And then that gave us a local environment running the like proxies in front, the same SSL, the same load balancers, the same situation where you have multiple workers that have been provisioned a certain way.

And it allowed us to hide all that from our developers. So our designer front-end developers upstairs can still work in an environment that is exactly like production on a smaller scale without having to spend their time realizing that configuring Mongo to allow remote connections needs a certain couple weird tweaks. And the whole idea was simplifying the onboarding process for new developers and existing developers and for keeping the parity between production and local development so that we're less surprised about how certain architectures work in the real world. So I'd love to talk a little bit more about the product high level.

So currently you're focused on Node.js. Do you plan to expand BitHound to other languages? Yeah, expanding BitHound beyond Node.js is definitely on our roadmap. We made a general commitment to both ourselves and our customers that we're going to continue to dive into Node.js and JavaScript to really be able to provide and expose very deep insights into what's going on.

I think we touched on it before, but it's not just static analysis inside of a dashboard, but it's really being able to divine enough information to provide context around the results that we provide so that the developers all the way through to project managers and CTOs can actually drive decisions and assign work based on the context surrounding the results. So once people are almost there at this point with BitHound, there's a couple more places to dive into. But then, yes, other languages, we're definitely on our roadmap. Do you see a light at the end of the tunnel in terms of the Node.js work?

Or is it where you implement one thing and you see five more things you need to do? I definitely think it's the latter. And it's not to say that BitHound is lacking, but the environment, the language, and Node itself, and with that, all of the things that are associated with it, such as NPM, continue to move forward at a break next pace. So JavaScript as a language is evolving year over year with new implementations and new language features that get implemented, and we need to make sure we stay on top of those.

As the whole ecosystem matures and as Node has truly become enterprise-ready, there are other considerations that go with that, everything from long-term support to just better practices in terms of how to manage all these massive amounts of third-party code that we're consuming on a daily basis. So I think if we did nothing but Node support, we'd definitely still have a workout for us for the next few years, for sure, just because of the speed at which the industry itself is moving. Well, you certainly put the hardest part first. I imagine once you get Node.js right, you kind of get the flywheel spinning, then you can be like, okay, well, let's go hire a Ruby expert, and then we can have somebody that does the Rails stuff.

And Ruby, as fast as it's moving, I get the sense it's moving slower than the Node.js community. So presuming that you have the best practices in place from the Node.js implementation, you'll be able to do the Ruby on Rails implementation much more easily. Yeah, that's correct. But I think it goes even beyond that.

I think one of the things that we've realized that we're really diving into this level of analysis is that a large percentage of the analysis that you do, to be able to gain the right context in terms of the insights that we provide to our customers, so they can know what actions to take, essentially actionable insights, are actually language agnostic, right? Like looking at a file to see, you know, how heavy is the churn on it, whether or not it's bug-prone, looking at the dependencies and where they're being used, and what does that mean from an impact to your project when we recommend that you upgrade a bigger dependency because there's security vulnerability, right? If it's used in one place, you know, maybe you're lucky, maybe it's a five-minute update. If it's used in a hundred places and you're more than two versions behind, right, so there's breaking changes there and a whole lot of touch points, maybe that's a week-long exercise.

So I think we wanted to make sure that we implemented, you know, that kind of depth of analysis inside GitHub, knowing full well that a lot of it is language agnostic, because that would give us an opportunity to later move on to other languages with the same depth of insight in a relatively short time span. You mentioned the term bug-prone. How do you identify bug-proneness in a line of code or a repository? The quick answer is magic.

Now, there's a lot of context that we add as we are working on projects. Right now, it's just kind of a little bit of, like, word-stemming matching on commit messages, tracing back to what issues are open and closed versus sentiment analysis of commit messages. We can kind of determine. Usually, there's keywords you'll use when you're fixing something versus adding a feature.

And then just using that in the context of all your projects and all your commits and all your files, you can kind of tease out the language the team would use to determine what they're fixing something versus if they're adding or tuning something. So what are the biggest challenges that you guys are working on at BitHound right now? I think, well, one of the biggest challenges is obviously just keeping up with the industry and the pace in which it's moving. But I think our biggest challenge as a company which we continue to work on is providing that context that we talked about, right?

It's essentially trying to get BitHound as a service and as a software program to try and perform the same job as you would expect a senior developer coming into a project, looking over the code, looking over the history, checking out the plane, to really understand what needs to be teased, what needs to be changed to get the project really moving forward smoothly. So the biggest challenge is really getting BitHound to work and act like a valued member of your team in terms of... insight and the context that wraps around that, rather than just being a dashboard with some numbers and some alerts. That's probably the hardest part is trying to get BitHound to act as a human software developer in its analysis.

I'd love to get some insight into the business of BitHound also. Do developers know that they want this tool, or do you have to put it in front of them and say, hey, this is an awesome thing, use it? I think the answer is a little bit of both. We talked to quite a few senior developers and working CTOs and VPNs where they're actually self-coding.

For them, BitHound serves the initial function of a validation of a gut feel. I always knew that was a problem in my code, now I have an objective third-party telling me about it. I've given them the added benefit of being able to align their entire team to deliver to the same standards and making sure that the more junior members of the team are aware of the impact of various actions that they take, such as, which dependencies do I include at what state? What does latching on to a deprecated dependency mean for us?

On the other end of the spectrum, we've had developers checking BitHound out, not really sure what it's all about, and then using it as a guide to improve themselves as developers because we expose things that when we're first starting out in this profession, not too many schools teach you about. There's some that we need to show the advantage of BitHound too, but once they see it, I think it becomes quite clear and they get very engaged. Then there's others that have been looking for a tool like BitHound for a while, knowing that it was a gap in their development process and their team dynamic. Did you guys bootstrap or did you raise money?

What's the foundational story? We raised money for this startup. We started off with the intent of bootstrapping, but we had had a successful exit prior to this. We built a company called Tiny Hippos, which was acquired by Blackberry.

As we went through talking to investors early on, which if there's any startups out there listening, please do that from day one of your company. That way you have a story that continues to evolve with your investors. You talk to investors even before you're actually ready to raise money. Absolutely, because that way, by the time you are ready to raise money, they already have a graph plotted, a storyline that they can lean onto.

They invest in lines, not dots. That's right, exactly. They invest in people and invest in teams. As we started talking to our investors, we had a bunch of very early commitments to invest right off the bat.

Part of it was our historical success. Others just really loved the idea and have personally felt the pain at some point during their careers that BitHound was trying to solve. We did raise two small seed rounds to figure out where we are today. Cool.

What's the future of BitHound? BitHound's goal and maybe even Reson Devo if you want to call it that is to be that indispensable solution and framework for companies to manage their entire software development process. Not just looking at the code and what it is and individual commits developers are doing, but really helping you manage everything from the very beginning of a project all the way through to deployment and continuous deployment and be able to give you deep insights not just into the code, but into the cadence of your team, the performance, what areas need to be improved, and just how can you better manage the software delivery process within your organization. One thing that has been coming up at an increasing frequency on this show is the build versus buy debate is becoming really interesting because there are just, like, you know, I think, Gord, you mentioned this, the pace of software is going so fast that there are just so many tools that you can buy that will improve your process, and it becomes this trade-off of like, literally, are you willing to pay some money to solve this problem quickly so that you don't have this problem anymore?

And it seems like it really is this evolution in how software engineering is taking place where you can just buy these components and they just do what you need them to do. Do you guys get that sense also, or is this kind of a trend that I'm imagining? It's actually kind of interesting because we had a customer kind of come to us as we were like, they're trying it out, and we were kind of saying, well, why don't you convert and get your credit card and start paying us? And there's a CTO of a startup, and he's like, well, no, I can just do this myself.

I can run a few scripts. I'm just going to put it in my seat. I don't really need this. And we're like, I said, okay, well, we're $59 a month at the lowest tier, which is the tier you are at if you were to pay.

How much time is it going to spend you to build and manage this system that would do what GoodHound does? And what is your hourly rate? Is your hourly rate less than a dollar a day for your developers? Maybe, yeah, you can save some money, but the reality is you sometimes forget that sending two, three, four of your developers for a week hack project to build an amazing code analytics solution costs you a lot of money.

After that week, you spent enough to have a five-year subscription for GoodHound. Exactly. On top of that, that's the initial build. There is a lot of effort involved with keeping up with the evolution of the language and everything else that goes with that.

So I think a lot of our customers are finding that it is remarkably more cost-effective to just engage with a service like GoodHound rather than building it internally. And we have talked to several companies and we've had some converts where we used to have our own set of command-line tools to attempt to do what GoodHound is doing. And it was constant maintenance. And the maintenance could just be updating all these MPM components, but switching over to GoodHound meant just clicking a green button and then a blue button, and then we were done.

And I imagine many of your customers are startups, technology companies, and there is this strange narrative in the business landscape these days that it is risky to be a business that is built on startups selling to other startups. And I think that this narrative kind of gets overblown and gets misinterpreted, but I'm curious to see, I'm curious if you guys interpret that as any sort of risk to the business or how legitimate you think that sort of narrative is, like, oh, we're due for this downturn that is going to lead to all these startups selling to startups crumpling. That's a great point. I think it's a startup you ought to yourself to really understand not just the market landscape and the competitive landscape, but who your customers truly are.

We all make assumptions early days in terms of who we think is going to buy a product. And then as you go through and start selling it, I think just like a diversified portfolio when you're investing your own money, you don't want to go all in high-risk, high-tech stocks. So you want to make sure that your product does appeal to the small to medium-sized enterprise that's established already at a minimum beyond just the startup world, and make sure that you have a legitimate path to get to enterprise, meaning the Fortune 1000 companies. And what are the value propositions that your product and product provide to entice the larger folks?

So a lot of startups start by selling two startups with a small enterprise because it's easier to do that whole automated conversion to pay. You don't need as much sales staff to pick up the phone calling. But understanding how your product can provide value beyond the small enterprise, even though it comes with longer sales cycles, it also comes with larger dollar figures, but it helps your company then be established and then survive any potential downturn in the startup system. Cool.

Well, that sounds like a good place to close off. Gord and Dan, thanks for coming on the show. This has been a really interesting conversation, spanning code analysis and investing and all this different stuff. And yeah, I'll be following your product closely.

I'll be following your product closely.

Frequently asked questions

How long is this episode of JavaScript Archives - Software Engineering Daily?

This episode is 50 minutes long.

When was this JavaScript Archives - Software Engineering Daily episode published?

This episode was published on April 5, 2016.

Can I download this JavaScript Archives - Software Engineering Daily episode?

Yes. Use the download control on the episode player to save the publisher-provided media file.