Put more resources into upgrading an old code base with new features or rebuild from scratch? As with the decision of whether to replace an old vehicle, the answer may hinge on a combination of the quality of the initial code base, how well the code has been maintained in the intervening time, and how much software technologies have advanced.
This decision point is often the motivation for our clients' request for a code audit. Our code audit can provide an objective analysis of the ease with which your code can be enhanced, to help you to make the right choice about how to best move forward. We will also provide you with estimates of the cost for us to help you to implement either option.
Our software code audit will proceed in a holistic way, not just analyzing discrete code segments but extracting and evaluating the underlying architecture, with a focus on the forms of evolution that you foresee in the feature set and usage of your software system.
What a code audit can achieve
Code can be evaluated in quite a few ways. In our code audits, we consider the following:
- Correctness: Buggy code will become even harder to correct as you add features that interact with each other and additional potential sources of trouble arise. We will help you to take stock of what sort of test coverage you currently have and what would be involved in improving it.
- Security: With incidents of hacking in the news on a regular basis and tolerance for them rapidly decreasing, you have the potential to comfort customers by following best practices or to enrage them by falling short. We will identify the red flags that you need to be aware of.
- Performance: You want, of course, for a growing user base to benefit from and rely upon your system. But there may be hidden inefficiencies that will surface to cripple your system at the worst possible time—the moment when you are first in the spotlight. Our code audit will reveal problems while you have the time to make a relaxed and deliberate judgment of how and when to address them.
- Maintainability: Your code is continuing to evolve and so are the third-party components upon which it relies. Was your code written with an eye towards how it might grow, or were you just looking to extinguish the fire at hand? If the latter, we can identify what refactoring would make it more robust.
- Compliance: Ensure compliance with any regulations to which you are subject and achieve any required certification. Regulations and certifications may be specific to an industry or apply horizontally across a technology. Whether compliance is mandatory or enables you to stay ahead of your competition, and whether you have already been flagged as failing to comply or you are being proactive, we can identify what is needed to get you where you need to be.
To make progress in any of these areas, the first step is always to determine where you currently stand. Any of them are worth investigating for their own sake, but as you begin a new project, you have a special opportunity and responsibility to consider what improvement might be necessary and how the enhancements will impact each area. These areas are not independent, but rather problems in one area will tend to propagate to others. For example, out-of-date libraries may no longer be updated with security patches. And occasional system crashes that seem harmless may provide points of entry to attackers who can recreate the crash at will, either to provide access to sensitive information about the code or data or to prevent the normal use of the system (a form of denial-of-service attack).
How we address code you wrote vs code others wrote
Our code audit will consider both the code you have written and code that you have used or modified.
Your own code
Of course, you are attached to the code that you developed (even if you know that it has flaws). Sometimes it takes somebody from outside your firm to talk straight with you about what is right and what could be done better. Clear, crisp code is easy to understand and maintain, and thus is more likely to be correct and efficient. We will encourage you to write code following the DRY principle (don’t repeat yourself!). When the same or similar code appears in multiple locations it must be maintained in those multiple locations. It is quite likely, unfortunately, that one but not another instance will be updated with some improvement. You may have places in your code that are at risk of this, or even some where it has already occurred. We check whether you are using the features provided by your programming language to abstract commonalities in how your code deals with different situations, or let you know if your programming language is holding you back
Your code should not just be well-tested, but also complemented with a set of tests that can be run at will to verify its continued correctness. We can help you with whatever stage of maturity you may be at in this process. There are various testing tools and methodologies; we prefer that of OWASP (the Open Web Application Security Project). We can recommend tools for maintaining and executing tests, help you to decide what tests should be the highest priority to put in place and help you to write them, or determine which parts of your code are being ignored by your current test suite or what other forms of tests would be useful.
Integrated components and customizations
Today, an increasing proportion of most software systems comprise a multiplicity of third-party or open source packages. Wherever your system leverages such code, we will pay close attention, whether it is in the form of libraries or frameworks. Libraries are generally made up of code that you call to achieve some result. Frameworks spread themselves out more widely across your system, heavily influencing its architecture. A framework will organize and call your code. Are you using the right libraries and frameworks, or are there others that are better maintained or more powerful? Are the components still maintained, and are your versions up-to-date, or at least still supported? We’ll let you know. We can provide you an inventory of what code you are relying on, whether it is out-of-date, and by how long.
Programmers have considerable leeway in working with either form of component, but especially frameworks, so there are proper and improper ways integrating components with your own code. Doing it wrong can lead to introducing problems related to any number of the issues listed above. At a minimum, it will make your code harder for trained professionals to understand and modify. Doing it right demonstrates your own professionalism to all your collaborators, including new hires.
Using components is complex enough, but you may well have had reason to customize the behavior of one or more components. Ideally, you were able to write code that could operate on top of the component, extending its functionality. Even in this case, you are subject to errors when upgrading to new releases of the component that do not maintain backwards compatibility. Perhaps you decided that extending the component would have been too difficult or not possible at all, and so you directly updated the component’s code. The ability to do so is an advantage of using open-source software, but it has its costs. Our code audit will consider the various possibilities and recommend an appropriate course of action. Has a component been customized, and if so will those customizations preclude updates? These factors will influence the decision of whether to upgrade your code or rebuild it on a stronger foundation. We can estimate the difficulty of updating customized component code and can help to isolate your customizations to make the process of maintaining that code in the future less onerous.
How we address various aspects of your system
Our code audit will analyze your system from head to tail.
Front end
The front end is often particularly complex because of the many interacting technologies involved. Here, we’ll review your selection of frameworks (such as JQuery, Bootstrap, Angular, and/or React). There may be a framework that you have not considered that would be better suited to the needs of your application than those you are currently using. We love reusable components and will review or encourage your use of a methodology such as BEM (block-element-modifier), SMACSS (Scalable and Modular Architecture for CSS), or OOCSS (Object Oriented CSS). BEM, in particular, provides an abstraction over the DOM that allows you to operate at a higher level across JavaScript, CSS, and HTML. CSS preprocessors such as SCSS (Sassy CSS) or Less (Leaner Style Sheets) can also make it easier to maintain your front end by compiling more intuitive and compact expressions of your design elements into standard CSS. They may also support defining operational functions, such as lightening or darkening design elements, that can be applied in disparate contexts. Our code audit may recommend that you use one or more of these, or if you are already using any of them, may recommend that you use them differently, to fully leverage their power. Using the right tools will make it easier to maintain your code and less likely that inconsistencies in style will arise among your design elements. They can also reduce the size of your code, so that it downloads more quickly. But tools, even well-used, are not a substitute for planning which abstractions to represent or for the smart use of language features. Many front-end technologies continue to include features for the sake of compatibility that would be best avoided. We will review your front-end code and point out areas where changes would serve you well.
Database
We will review your database structure to verify its design quality, including that it is appropriately normalized. A more normalized database uses less space, is less prone to inconsistencies, and often outperforms a less normalized one. We may well suggest changes for reasons of performance, security, or maintainability. Do you have the right indexes in your database? Too few indexes will make queries run slower than necessary, but too many will take up excessive space. Are the proper constraints specified on attributes, including keys, and indexes to enforce data integrity and avoid inconsistencies? We’ll let you know. We will also check for the appropriate use of advanced database features. These include data types for customized data representations, views to abstract and enforce business as well as security rules that cut across tables, and database triggers that can enforce more complex integrity constraints by running procedural code in response to particular events.
Back end
As with the front end, we will take inventory of the outside components used. In this case, those are likely to include web frameworks, ORMs (object-relational mappings) for abstracting access to the database, template definition languages for generating client HTML, and others. Web frameworks may be based on architectural patterns such as variants of MVC (model-view-controller). We will verify that you are appropriately distributing your code within such frameworks, or if not recommend adjustments. The components may also include higher-level platforms such as Magento for ecommerce or a content management system such as WordPress or Joomla. Based on your choice of languages (statically or dynamically typed) we will review to what extent you are conforming to best practices in its use.
Let us audit your code
Find out why our US-based customers have found this service to be so worthwhile. We can evaluate your code for the sake of all your stakeholders who depend upon it every day. We can also evaluate your code to determine whether it is up to new demands that you intend to put upon it, including extending it with enhancements. Rather than a question of whether you are contemplating such enhancements (most likely you have dozens in mind) we suspect that that it is only a matter of how much time until you will need to put those ideas into action. When you need to move, make sure that you are building on a solid foundation rather than compounding previous errors. Whether you eventually upgrade your code base or rebuild from scratch, we’ll give you the confidence to move forward decisively, with understanding of its strengths and weaknesses and with a clear vision of what you will achieve.