visit
As we’ve discussed in a , product development is hypothesis testing. This is especially true in the early stages of a company when you need to confirm or reject your hypothesis as quickly as possible. This process is then repeated until you (hopefully) reach product-market fit. To get there, your team needs to be able to work and build at a pace that allows for this constant and rapid iteration.
Monolist is the command center for engineers — tasks, pull requests, messages, docs — all in one place. or .Your company’s tech stack will immediately be a fundamental part of how your engineering team works and operates. This is even more important in a small company where the engineering team represents an outsize portion of the team as a whole.Many people will recommend to early founders that they use the technologies they know and write in whatever language they're familiar with. Although this is good advice, like all other decisions it should be weighed carefully. While ideally you're fully familiar with the stack you choose in order to move as fast as you can, you should also be putting some thought into how these choices will affect you and your engineering team moving forward. For example, it may not always be best to pick the brand new (and unproven) technology on the block when you need to scale quickly and painlessly.The overall goal can be summarized as this: minimize time spent on non-feature engineering work.
For every hour you or another engineer spend configuring, debugging, or learning a new system, that's an hour not spent iterating on the product to maximize learnings and value delivered to your users.Here are the things to aim for when choosing your startup's early tech stack.Well-known languages or frameworks
Technologies often come and go quickly in software development. However, there are those libraries that are nearly ubiqitous. These are the languages and frameworks that the majority of software engineers would be at least vaguely familiar with. Examples would be Rails or React, both incredibly popular libraries used and supported by a large number of people and companies. This also means they have large and healthy ecosystems surrounding them.Typed languages
Large refactors of core business logic are common when you're an early-stage company iterating often on your product direction. These are no longer nerve wracking when you always know what data you’re working with and when.Self (or well) documented code
While the concept of true "self-documenting code" is , it can still be valuable when not taken to an extreme. Write and architect your code so that its purpose is clear and its execution path is easy to follow. Leave clarifying comments when blocks of code become overly complex out of necessity. As mentioned above, typed languages also help a lot here.🙌 Our Recommendations
— The simplicity of Rails' , coupled with the easy to read and write language Ruby, means it's easy for most engineers to become comfortable working in Rails and shipping production features. Rails also continues to power many well-known, large-scale applications such as Shopify and GitHub.Caveat: Although Ruby is not typed by default, there is a new static type checker called .
— Defining your types and using TypeScript strictly results in code that’s easy to parse and safer to modify.A large community/ecosystem
If it even needs to be said, open-source is your friend. High numbers of users (downloads) and contributors are a good signal of a healthy ecosystem for an open-source library, meaning bugs should be resolved fairly quickly and new features will likely be shipped. A few quick (and imprecise) measures we use to quickly get a read:The number of stars a repo has on GitHubThe date of the last significant updateThe number of outstanding (and/or stale) issues and pull requests."Setup-free"
This one is fairly self-explanatory. I provide the quotations because I've yet to find a library that is truly and literally setup-free for anything beyond the most basic use case. However, it is still good to aim for libraries that will not require a large amount of someone's time to configure.None of this means, however, that you should always avoid the route that requires a little more work initially if it pays off in the long run. We'll talk more about that below in "Automate everything".🙌 Our Recommendations
— One of our picks again. The long history and large community around Rails means you can find a gem for practically anything your application could need to support. Many of them are even included in Rails itself. — Next brings a Rails-like simplicity to handling an isomorphic React application. Data fetching and page definitions are unified, while you get to continue using any React patterns or components you prefer.Share languages or frameworks
Sharing a single language or framework across multiple parts of your system can increase the options for code sharing. JavaScript is often the top choice in this sense, as it can be used for everything from your database ORM to your native mobile client.Build modularly
When multiple parts of your system are using the same core language or framework, it becomes increasingly advantageous to build modularly. While this always helps with separation of concerns and unit testing, it can now open up new ways to share and re-use code across your application.For example, maintaining and publishing all of your app state across multiple clients becomes much more manageable when you can use the exact same Redux code across web, iOS, and Android.There are limits to reusability, however, as complexity often grows exponentially in the same direction. It is important to keep that in mind as you still aim to achieve the first goal we discussed, "easy to understand".🙌 Our Recommendations
— React has become an incredibly popular framework choice to go alongside a universal JavaScript application. Many libraries exist to support code re-use across frameworks and platforms. — RN is one of those platforms that encourages code re-use with other React applications. Write your native mobile applications (iOS, Android) using your same modules in familiar architectures. — Another React-related library, Gatsby allows for easy creation and publishing of static websites using the same React files and patterns. Great for maintaining a scalable marketing site. — Lerna helps to more easily maintain a monorepo of inter-dependent JS packages. Easily bump while keeping versions in sync, as well as publish to NPM.🙌 Our Recommendations
— Terraform helps us to fully manage our cloud infrastructure in source-controlled and peer-reviewed code. This allows for consistency and self-documentation, while giving us much more confidence in our deployed systems. — Docker allows us to pre-define our various service environments (we have around 12) as reproducible and deployable containers. Again this allows for consistency, self-documentation, and confidence in our systems.