Delivering great software is more than typing code into an editor. This page describes how we approach software development and the skills we look for from anyone joining the team. This is our ethos, and it's an important part of both our hiring process and our day-to-day at Replicated.
We’re not building photo filters for 14-year-olds. We’re building a technical product that will be used by your peers (some of the best software engineers in the world). As a result, engineers at Replicated step up to take responsibility for more than writing code. Our engineers focus on delivering a product that they’d love using themselves.
It’s not possible to add security to a product after it’s built. Everyone on the team (product, engineering, automation) understands what it takes to build, support and maintain a secure product from the ground up.
Although we try our best to hide the inherent complexity of the Replicated platform behind an intuitive UI, that really only covers a third of the use cases. Just about everything at Replicated can be used via UI, API and CLI. That’s why we place a premium on informative, well-written documentation that aids our customers when they need it. We treat documentation as part of the product.
Even for complex products, the best code looks like it came from a single person rather than a collection of unique pieces stitched together. We share a unified approach to coding so it’s easier for any developer to jump into unfamiliar parts of the product and immediately add value.
Continuously adding small and unplanned refactoring means everybody is continuously relearning the codebase. We carefully consider and plan refactoring, and only pull the trigger when we all believe it’s the right decision.
Whenever possible, we use Replicated to build and deliver enterprise features into our products—no shortcuts allowed. This is a great opportunity to see what it’s like to be a Replicated customer.
Abstractions aren’t obvious until there’s at least 3 implementations. Creating shared libraries and abstractions around a block of code that’s used twice should be carefully considered. Testability or 3+ implementations are both valid reasons to create abstractions.
Creating abstractions and modularity “just in case” can result in a bad case of technical debt. We try to avoid predicting the future, and instead focus on writing code that just works.
When planning a solution, we consider all constraints when deciding what to deliver. Every project comes at an opportunity cost of the things we’re not working on, so flexibility is fundamental for both depth and speed of delivery.
Just because we can build something, that doesn’t mean we should. When possible, we opt for existing solutions that let us focus our valuable time on building differentiation into the core product.
You never know when you’ll need this to troubleshoot or review performance of a system. Every service should expose some metrics. We instrument everything, but have created dashboards to view the important data.
We love automated testing as much as the next software company, but we don’t test just for the sake of it. Unit tests and integration tests serve different purposes, so we test what we need to depending on the project.
We automate everything. Period. In fact, there aren’t even SSH keys on our servers—the only way to get code running at Replicated is to build into our automation pipeline.