{ Simple Frontend }

How to improve your frontend projects

Learn how to set up strong foundations to improve both the speed and reliability of your frontend releases.

Jeremy Colin Jeremy Colin
Sep 18, 2025 - 6 min read
#Frontend#Platform

One of the greatest opportunity costs for frontend projects lies in their developer productivity setup. The way we develop software end-to-end, from our code editors to its integration and delivery, plays a huge part in our overall velocity. This effect becomes even more significant as your team grows.

You should have a streamlined developer experience where the right way is the easy way. This should be automatically enforced and codified both through a code editor with static analysis and Continuous Integration (CI) abstracting aways the burden of opinionated code style.

Code should reach production quickly while ensuring high reliability through automated end-to-end testing and alerting.

Setting up a new project: Ship Nothing

While setting up a new project can be satisfying, it can also be daunting. I recommend going live with your project on the first day.

Yes, you read that right. Obviously, that doesn’t mean finishing the project, but it does mean starting by setting up and deploying your project shell immediately, as explained in Ship Software That Does Nothing.

This article is packed with wisdom. The most interesting takeaways for me were:

  • It forces you to make many practical decisions early on, such as how you want your software deployed and where you want to host it.
  • It helps you automate your delivery process because you have no dependencies and nothing complicated yet.

It’s also about setting the right mindset from the start: “When you establish an automatic delivery pipeline before you have users, everyone becomes accustomed to frequent, minor changes.”

Rocket leaving launchpad successfully

The Developer Experience Foundation

Project Structure

The Too Long Didn’t Read here is that you probably want to have a monorepository for your frontend application where you organize your code by features.

For very large projects or multiple apps, you probably want to look at micro-frontends and I wrote a guide to help you decide on the recommended setup matching your goals.

Find out more in our docs.

Automate opinions

Code consistency will help developers ship faster: when all the code is consistent in terms of formatting and patterns, it is more familiar to both human and AI assistants and reduces cognitive overhead to understand and extend it.

The last thing you want is people arguing over styles and standards in code reviews or manually checking them so you should “codify” all these best practices and standards. That essentially means having enfoced Continuous Integration (CI) checks checking those. For example running prettier --check or eslint as part of your CI.

Bet on Static Analysis

No one wants to come back from a coffee break and see a build with errors which could have been caught earlier during their development workflow.

Build errors on continuous integration build

What we want is our code editor to say “hey don’t do this, that’s never going to work” or “nope, this is going to bite you later”.

And so I would strongly recommend having a strict TypeScript configuration and static analysis tools like ESLint. Yes, they’ve been known to be notoriously slow in the past but recently they’ve been flying. The last release of ESLint adds support for multithread linting and if you don’t need custom rules, Oxlint is an ultra fast alternative developing super rapidly.

I wrote a doc section on linting to help you get started quickly.

Unit test feedback loop

Setting up a strong foundation for unit tests with good mocking best practices will pay dividends later.

I believe we should not unit test everything but important user interactions triggering business logic actions or complex functions are often great candidates. This ensures your core business logic is protected, especially as you refactor code later on.

Modern Build Tooling

The last piece of a great developer experience is a great build tool for your local development. I cannot recommend Vite enough as it comes with all the good stuff included such as Hot Module Replacement.

Your development feedback loop should not exceed a few seconds from the moment you hit save and you definitely should not have to reload your browser window.

The Continuous Integration Foundation

Once you have nailed your local development setup, it’s time to setup your CI workflows.

One important principle here is to start simple and optimize later if needed. I have seen too many complex CI workflows where you forget what happens or that skip critical workflows because of invalid conditions.

Your CI is the guardian of your quality, ensuring automatically that incoming code adheres to the team practices and standards and is reliable. What you want to achieve is at least the automation of the following checks:

  • Code format compliance
  • No linting errors
  • No type errors
  • All unit tests passing

Ideally you also want to deploy branches from pull requests to a dedicated pre-production environment using the preview deployment pattern. Not only does it give developers and stakeholders like product or QA an environment where they can interact with the changes proposes, it also gives you an environment where you can run automated end-to-end tests.

Running automated end-to-end tests on pull requests builds has been one of the most impactful reliability pattern I have seen to ensure frontend projects quality. When done well, they assert that your core business functionalities are working after any new change is introduced. They should stay simple, fast and non flaky to provide value over time.

Your CI should act as a reliable feedback loop for your developers and ideally it should not exceed 10 minutes to run the entire checks suite. This is extremely important to avoid expensive context switching or delaying bug fix releases.

The Continuous Delivery Foundation

Continuous delivery will improve both your release pace and reliability:

  • It allows you to ship features faster and resolve critical bugs in shorter time.
  • With smaller changes being released independently, you can quickly identify the root cause should you introduce a regression.
  • It reduces the impact of your rollbacks, thus mitigating the risks associated with larger features delivery.

Ideally you are able to deploy every commit or you batch them into a “release train” that deploys every couple of hours or so.

I also recommend shipping unfinished features early to production under feature flags to avoid long lived branches and reduce deployment risks.

I explained how to achieve this setup while keeping high reliability in a blueprint article

The final piece of a safe continuous delivery is to have basic alerting in place for example with Sentry so that you are immediately informed when things are not working as expected and you catch issues before they are reported to you.

Pipeline from code to CI represented by a shield to production represented by a rocket