The NewStore development process
How we develop our product.
What’s your dev methodology?
It’s very lightweight. We don’t use Scrum. Our only ceremonies are retrospective and daily standups (where we go through the work in progress, not the people).
Given its values and practices, we cherish extreme programming. It’s not imposed but highly recommended. We build and operate following a DevOps culture (DevOps is not a job or a role but a culture!). We empower the teams to do what needs to be done. They build, they run, and they own it. They feel the pains, so they find the solutions. In my team (Selling), this fostered a culture of quality because if we didn't improve our practices, we’d be randomly awoken at night by noisy alarms. Nowadays, we are rarely paged, and we are never woken up.
We don’t do code reviews, create branches, have a separate QA team or QA stage, or do sprints or releases.
That’s quite reckless, no?
All those practices solve problems, and we have decided on other practices to solve those problems.
Ok, but what best practices do you have?
Before that, let me state that there are no best practices, only those that optimize work based on each one’s values. It doesn’t make sense to apply practice A or B if it’s imposed or you don’t share its guiding values and principles. We need to define them first.
Ok, then, what are your values?
We are economically responsible. We don’t want to use technology for fun or add the most features possible; we prefer solving the most impactful problems daily while minimizing cost.
Our primary drive is to bring value to the user; we are highly user-centric. We devote our energy to solving user problems rather than internal problems or processes. This commitment is reflected in our hiring process, backlogs, testing strategy, etc.
Many businesses depend on us, so quality, trust, and transparency are essential. Each company sees quality differently, so let me specify how we see it:
Quality isn't a stage; it's a continuous process. It’s integral to the development process and should not be considered an afterthought. It exists from the very beginning.
Quality is not an individual responsibility but a collective effort involving everyone in every decision. We don’t have a QA team.
Quality is never done and achieved because a product is a never-ending discovery, and most decisions involve trade-offs.
A key value is psychological safety. We aim for a self-feeding cycle of ensuring people feel good so they create high-quality work. This is achieved with a non-blaming culture, egoless discussions, collaboration, and leveraging technology to meet our needs, namely by building a fantastic safety net to prevent or mitigate human errors. We avoid the repetitive and error-prone task of manually testing everything. Instead, each team sees automated testing as a central mechanism for quality and liberating us for more meaningful work. They devise their strategy with various levels and phases (e.g., static checking, project tests, end-to-end tests) that automatically promote a build to go live or pinpoint a problem instead. A safety net mostly means an adequate testing strategy powered by automation, but it’s not limited to that (inspired by the Swiss cheese model).
What about principles?
Principles translate values into guidelines and policies. They have consequences in daily decisions and applied practices. Here are the most relevant examples:
We try to eliminate waste as much as possible (the first lean principle of lean development). It means maximizing the amount of work not done (processes, tools, product features, etc.). This doesn’t mean being lazy or neglecting work; it means doing the minimum necessary to get the job done while keeping options open.
The broken windows theory suggests that promptly addressing issues prevents more significant problems from developing (to prevent the normalization of deviance). For example, we fix the warnings in the editor, tests, etc. We put bugs, alarms, and support requests at the top of the backlog (I like to call it the “inbox zero” backlog). We analyze and fix the root causes for every support ticket, even if it takes much longer, as we don’t want them to resurface later.
Deadlines are rare because we deliver continuously, but if they happen, they lead us to negotiate scope, not quality. You never hear that we don’t have time for tests.
Developers don’t see themselves as just coders. We don't execute prescribed solutions. Instead, we investigate each problem ourselves (e.g., through user research) and try a solution as a team.
There are no internal demos. We work together, so we don’t need them. Instead, we do demos for customers and real users on concrete, small topics. Demos are done with actual software in production rather than presentations, videos, or mockups, which only create overpromising and anxiety. We prefer to deliver something small, get feedback, and act on it (iteratively and incrementally). We don’t work for internal stakeholders; no one inside the company tells us what the users want or how to achieve it.
Our tests document use cases without focusing on implementation details. They are usually high-level and capture user actions and flows. The test subject is never a function (we barely use mocks)—instead, it’s a vertical slice (i.e., a use case), a page/screen, or a user goal. We set up end-to-end testing of user journeys, especially critical ones.
Teams are value-stream aligned (e.g., Selling, and Store Operations) rather than tech stack-oriented (we don’t have frontend or backend teams). This optimizes autonomy and user centrism; there’s also less “generic code to fit all purposes.”
We prefer sync work (e.g., pairing) rather than hand-offs and async work. For example, we rarely create branches or do code reviews.
Wait. You don’t do code reviews?!
We don't believe in lone wolves coding alone in a basement, headset on, surrounded by pizzas. Most complex jobs outside software development are done by multidisciplinary teams working together and learning from each other, so we do the same here. The complex problems we face daily are rarely about technology; they are more about the domain, the users, and the trade-offs. Therefore, pairing is a key practice of our culture. The most common pairs are made up of developers, but it’s frequent that a developer pairs with a product manager or a designer (we don’t work for them; we work with them).
Typical code reviews are decontextualized and done after all the tough decisions have already been made and people have put in a lot of effort (and some emotional attachment). Our code reviews happen in real time; discussion leads to better results because of the constant validation. Pairing is also a key enabler of continuous integration and delivery (CI/CD). It’s one of the reasons why we always push to main.
Ask a programmer to review 10 lines of code; he'll find 10 issues. Ask him to do 500 lines and he'll say it looks good. ~ Giray Özil
Isn’t pushing directly to main too risky?
Pushing to main is possible due to some decisions that work well only when done together. There are many enablers of trunk-based development (pairing and having a good automated testing strategy help a lot), but a key aspect is TDD (Test-driven development). We do TDD as much as possible to ensure we do solely what’s necessary. TDD is an essential aid against generic or over-engineered code. It forces you to focus on the present needs; it discourages future-proofing because you’re supposed to implement only what the test says. TDD stops only when we deliver the user story, which means there’s something new that the user can experience. With TDD, you push only tested code. Only the code that passed all checks in the CI/CD is deployed to production. All this is automated.
Our practices taken together are mutually reinforcing. Adopting a few of these practices in isolation is risky. For example, we don't do trunk-based development without TDD, pair programming, and test automation.
Aren’t you just doing Kanban?
No, because the backlog is not a to-do list. It doesn’t contain tasks because tasks represent a project management approach or a factory line. We prefer a product management approach, where work is split and delivered by value. Our splitting does not optimize for work assignment; it optimizes for value sooner. The backlog is about the users and contains mostly user stories. Each user story is a simple sentence, a reminder of a user problem.
It’s all really user experience in one way or another. If the user is not experiencing it, then why do it? What’s the point? ~ Jason Gorman
On the other hand, unlike in Kanban, we don’t work in FIFO (first-in, first-out). The backlog is small and dynamic, and we reprioritize it daily as a team. Also, we don’t say: “We can’t do this now because it’s not in the sprint” because there are no sprints.
How frequent are your releases?
We don’t do releases. Every change is deployed directly to production because we have quality guardrails in place. We don’t accumulate work. All work must be visible soon after it has started. A story is only done when it’s live. We deliver new value multiple times a day.
Pairing and a solid testing strategy greatly help, but a CI/CD mindset is key to ditching the release approach. CI/CD is not about technology. It’s an approach to work where you reduce the surprises for everyone. This is why we put some effort into proper story slicing, although it happens daily rather than in a dedicated ceremony. The split occurs vertically, which means being able to deliver value (in opposition to splitting by technical nature). We tackle them one at a time by importance/impact. This brings many advantages like predictability, continuous adjustment, de-risking, promoting a culture of experimentation, embracing uncertainty, motivation, etc. The other enabler for constant delivery is that QA is part of the process from early on - our testing strategy enables many pushes a day without fear.
How do teams align to deliver value?
The teams are organized to leverage trust and autonomy. They’re empowered to do what it takes to get an idea realized and into our users’ hands. This implies no hand-offs; we have no design, frontend, backend, or QA teams. Instead, we have balanced teams with the necessary skills (developers, a product manager, and a designer in each team) to achieve it. We don’t have ceremonies like grooming. All is done within the context of the story. This way, there’s no gap between deciders and doers or deciding and doing.
Autonomy also means not being blocked by other teams or individuals (we don’t want to foster champions and heroes). A user story is a team concern; we don’t assign stories to people. We avoid single points of failure, so we prefer a flatter hierarchy. Managers exist to help and enable the teams rather than command them. The team doesn’t sit waiting for someone to solve something; they face the issues as their own.
Good process means no handoffs. The team picks up an issue to work on and does not start the work on any other issue until the one they started working on is solved and placed in customers' hands. That flow is not possible if there are inspection gates where half-completed work gets placed on a queue for some other team to inspect at some undetermined later time and approve or reject. ~ Alex Bunardzic
Don’t you protect the teams from the users and “the business”?
We do the opposite. There is no dichotomy between business and development teams because they are the same. We don’t need to protect the team from doing their jobs. Each team is in direct and continuous contact with the customers. We don’t optimize to please internal stakeholders.
How do you maintain your values and principles?
It’s about the people we hire. Ensuring quality becomes complicated when we hire the wrong individuals. This makes our hiring process crucial, and we are continually refining it. We don’t want to deceive anyone. Candidates get a taste of our daily practices, allowing them multiple opportunities to evaluate us. A wrong hire is more expensive than an unfilled position, so we must ensure we are aligned on values, principles, and practices.
If it isn’t a clear yes, then it’s a clear no. Essentialism
The hiring process includes a conversation with a Product Manager (in a way, acting as a customer), a pairing session mimicking real work, and a culture fit interview. The process reflects our commitment to working together, user-centrism, and applying TDD. The exercise lets us assess if we could work together rather than having a few evaluators watching candidates nervously code alone. Team members are in charge of most of the hiring process rather than some manager who will not work with the person. It’s about empowering the people who’ll face the consequences.



