Back Arrow
From the blog

Starting as a Professional Frontend Developer

In this article, I want to share not just impressions, but real experience of "surviving" in a commercial project. This is an honest story of what to be prepared for if you're looking for your first job.

Yakov Shevcov

Frontend Developer

Hey! I'm a frontend developer at ByteMinds. It's been six months since I joined the team and first encountered real production code.

Before this, my experience consisted of pet projects and courses where everything was usually "sterile." In this article, I want to share not just impressions, but real experience of "surviving" in a commercial project. This is an honest story of what to be prepared for if you're looking for your first job.

The Stack: Expectation vs Reality

When I was studying, I thought projects picked one modern framework (like React) and everything was strictly built with it. In the "ideal world" of tutorials, that's exactly how it works.

Reality: In commercial development, it's different. Right now I'm working on projects managed by CMS platforms (Umbraco and Optimizely). These systems are built on .NET, where most of the frontend is rendered server-side through Razor templates (CSHTML).

In this architecture, React isn't the "king" of the entire project. It's used selectively - as isolated components or blocks with complex logic that get embedded directly into Razor templates. The result is that on a single page, you might have several isolated React applications coexisting alongside markup that uses plain JavaScript scripts where needed. It turns out the ability to quickly switch between a framework's declarative approach and imperative vanilla JS is a crucial skill for "real combat."

Typical project situation: a page renders through Razor, you're tweaking card markup and adding simple logic with vanilla JS, and on the same screen there's an isolated React component handling something complex - filtering, state management, async requests. Within a single task, you constantly have to switch between these approaches and choose the right tool for the specific problem, rather than trying to force everything into React for the sake of "architectural purity."

The Codebase: Not "Bad Code" but a History of Decisions

A junior's first shock is legacy code. At first, it seems like the people who wrote this never heard of design patterns. But over time, understanding dawns: the codebase is a history. Some decisions were made in a rush before a release, others were driven by specific client requirements that changed three years ago.

Navigating these layers of different eras is an art in itself. That's where modern tools and colleagues come in handy.

AI as a Co-pilot: My Experience with Cursor

For me, Cursor has become an indispensable accelerator. I use it for pragmatic tasks where it's more efficient than manual searching:

  • Context and navigation: It's great for understanding which files contain scattered logic and how components relate to each other in a massive project.
  • Routine and boilerplate: Generating TypeScript types for an API or scaffolding a component structure - tasks that AI handles like a pro.
  • Risk assessment: Before refactoring, you can ask: "Where is THIS used, and what will break if I delete or change it?"

Writing complex business logic? I wouldn't trust it with that yet, to be honest. AI is like an intern who works really fast but can confidently spout nonsense. So you still have to check every line of code.

Colleagues

Asking colleagues questions is one of the fastest ways to figure out a task. They often have context that isn't in the code: why a particular solution was chosen, what was tried before, and where the hidden pitfalls are.

These discussions not only save time but also help develop your "gut feeling." Gradually, you start to understand better where the real risks are and where you need to dig deeper, versus where you can accept the existing solution and move on.

In commercial development, this is critical: it's not just about writing code, but doing it safely for the project. Talking with colleagues accelerates your onboarding and helps you start thinking in the context of the product, not just an individual task.

Design and Communication

In pet projects, you're your own client. In commercial work, mockups are the foundation, but life throws curveballs. For example, a mockup shows 3 tags on a card, but the backend sends 7, and suddenly your layout starts to "dance."

It's important to understand that design isn't always the ultimate truth. Often, designers themselves see their work more as an aesthetic direction rather than a strict final result. They don't always know 100% what real content and in what quantities will come from the backend.

At that moment, responsibility falls on the developers. We're the ones who see the real data and have to decide how to display it as closely to the design as possible without breaking the UX. If in doubt, it's best to go to the designer and clarify their intent. But over time, you develop a feel for the boundaries of flexibility: where you can adapt the solution yourself, and where sign-off is crucial.

This approach teaches you to be more than just "hands" - it teaches you to be an engineer who thinks about the user and the product, and tries to solve a problem before it surfaces in production.

Sometimes You Have to Make Trade-offs

Things Don't Always Go to Plan: The Carousel Case

One of the most memorable moments was a task to implement a block that was a hybrid of a marquee and a regular slider. The designer kindly provided mockups with animation, approved by the client.

The requirements:

  • Two rows of slides moving in the same direction, but at different speeds.
  • Continuous movement (like a news ticker, linear flow), not slide-by-slide.
  • Looped movement.
  • Overall controls: autoplay on/off, next/previous slide.
  • Slides are clickable cards.

The Technical Struggle

Initially, the project already used the Swiper library and had dozens of sliders implemented with it, so I decided not to add new dependencies. But, as it turned out, standard Swiper is designed for flipping through slides, not for linear flow (surprising, right?). To "squeeze" it to meet our needs, I had to search for hacks.

I found a configuration that turns the slider into a marquee:

typescript
const swiperDefaultOptions: SwiperOptions = {
  modules: [Autoplay, FreeMode],
  autoplay: {
    delay: 0,
  },
  freeMode: {
    enabled: true,
    momentum: false,
    momentumBounce: false,
  },
  loop: true,
  slidesPerView: "auto",
  spaceBetween: 24,
  speed: 4000,
};

// Initialization
this.swiperTopCarousel = new Swiper(this.refs.topSwiper, {
  ...swiperDefaultOptions,
  speed: Number(this.refs.topSwiper.dataset.speed) || swiperDefaultOptions.speed,
});

And of course, a bit of CSS magic was needed. For smooth scrolling and predictable behaviour:

css
.swiper-wrapper { transition-timing-function: linear; }

Seemed to work fine, the hack solved everything, but...

  • Janky loop when dragging. This became the main pain point. Because the slides had different widths, Swiper didn't calculate the "seam" point of cloned slides correctly. Visually, it looked like a jerk: the container would suddenly jump back to loop the animation. A possible fix would have been to calculate slidesPerView precisely, but for the sake of responsiveness, we needed the auto value. The solution: we had to take away the user's ability to drag the slider. Harsh? Yes, but navigation buttons were still available.
  • Stop on click. Clicking a slide would stop Swiper's autoplay. I never fully figured out why. People online who'd implemented this hack suggested disableOnInteraction: false and pointer-events: none on the container. But that didn't work for us – the cards needed to be clickable.

The Solution: Compromise and a Second Library

I realised I was trying to force Swiper to do something it wasn't designed for. The ideal candidate seemed to be Splide. It has a built-in type: 'loop' mode with proper slide cloning, which solves the jerking issue. And the AutoScroll module smoothly moves the entire strip:

typescript
const baseOptions = {
  type: 'loop',
  autoWidth: true,
  gap: gap,
  arrows: false,
  pagination: false,
  drag: false, // disable drag, rely on autoscroll
  clones: clones
};

this.topSlider = new Splide(this.refs.topSlider, {
  ...baseOptions,
  autoScroll: {
    speed: 0.4,
    pauseOnHover: false,
    pauseOnFocus: false
  }
});

this.topSlider.mount({ AutoScroll });

Now came the dilemma: the project already had dozens of carousels using Swiper. Rewriting them all would be unjustifiably time-consuming and risky. Leaving the Swiper hack meant not delivering the task with the required quality.

In the end, I made the tough call: to add Splide as a second library specifically for this case. Yes, it increases the bundle size. But in this situation, it was the only way to achieve truly smooth animation without writing a custom solution from scratch.

When making such decisions, it's important to base them not just on code "beauty" and universality, but on the component's importance to the product. This carousel was the main visual feature of the case studies page and grabbed attention on first visit. Since the component directly impacted the first impression of the design, we decided not to compromise on the visuals.

Lesson learned: sometimes it's better to sacrifice bundle size for a solid UX and a stable solution, rather than maintaining fragile hacks in a critically important part of the interface.

On Estimates and Responsibility

Estimating tasks is pretty stressful at first. You allocate a certain amount of time, and you work towards it, but one unexpected carousel can eat up a good chunk of it due to unforeseen technical nuances.

This taught me that an estimate isn't just a number the project should be ready for. It's always about planning for risks, even when it seems like there couldn't possibly be any. Now I always try to build in a buffer for researching existing code and unexpected circumstances.

Conclusion

Over these six months, I've understood the main thing: commercial frontend isn't just about writing code in the latest React. It's about the ability to work with what's already there, to negotiate, and to find a balance between "beautiful code" and a working business. It's harder than it seems in courses, but also more interesting and varied. In the end, I'd highlight these key takeaways:

  1. Proactivity matters more than knowledge: If a task isn't clear - ask. It saves hours of wandering.
  2. Ideal code is sometimes the enemy of the product: In reality, you sometimes need to compromise to get a feature working stably and on time.
  3. Respect for Legacy: Instead of criticising "crappy" code, focus on improving it safely.
  4. Soft skills are key: Being able to explain your thoughts and accept feedback in code reviews makes you grow faster than just memorising syntax.

These were just the first six months. Real production is a noisy, non-linear thing, and school doesn't prepare you for it. But it's precisely in this chaos that you build the skills that make you a real developer.

It's easy to start working with us. Just fill the brief or call us.

Find out more
White Arrow
From the blog
Related articles

Speeding Up Layout from Figma with MCP and Cursor

Liya Vasilkova

In this article, I'll show you how to leverage the full power of AI assistants in the design implementation process, using the duo of Cursor IDE and an MCP Server as an example.

Frontend

Setting Up a Frontend Build for HTML Email Templating with MJML

Dmitry Berdnikov

In this article, we'll break down two key stages: first, we'll create a repository for email templating, and then we'll configure local test sending via SMTP.

Frontend

gRPC for Testers: Quick Start After REST

Vasil Khamidullin

This article will help you understand gRPC basics, how it differs from REST, the structure of .proto files, and most importantly- how to test gRPC services using Postman.

QA

Understanding CORS: A Practical Guide

Bair Ochirov

In this article, I will briefly answer questions about why the CORS policy was created, how it works, why a simple action like "setting a header on the backend" might not be enough, and what secure patterns to choose for the frontend.

cors
sop

How I Started Writing Unit Tests for Vue Components - Part 2

Dmitry Simonov

So, it's been a year since the last article, and a lot has changed. In this one, we're going to talk about integrating with Mock Service Worker (MSW).

vuejs
Vue

Performance Issues in Web Services: A Practical Guide to Identification and Resolution

Dmitry Bastron

Performance is not a feature to add later, but a core requirement as vital as security. This guide provides a structured approach to building performance into your web services from the start, ensuring they are fast and scalable by design.

Development
WebDev

Setting SMART Goals for Digital Product Success

Andrey Stepanov

This quick guide helps you define clear objectives and track progress effectively—ensuring every milestone counts.

Development

Building Teams for Digital Products: Essential Roles, Methods, and Real-World Advice

Andrey Stepanov

A digital product isn’t just about features or design—it’s about teamwork. In this article, we break down the essential roles in digital product development.

Development

Goals in Digital Development: How to Launch a Digital Product Without Failure

Andrey Stepanov

Essential tips for creating a development team that works toward product goals, not just tasks.

Development

How to Become a Kentico MVP

Dmitry Bastron

Hi, my name is Dmitry Bastron, and I am the Head of Development at ByteMinds. Today, I’d like to share how I achieved Kentico MVP status, why I chose this CMS, and what it takes to follow the same path and earn the coveted MVP badge.

Kentico

How can a team lead figure out a new project when nothing is clear?

Maria Serebrovskaya

Hello! My name is Maria, and I am a team lead and backend developer at ByteMinds. In this article, I will share my experience: I’ll explain how to understand a complex project, establish processes, and make it feel like "your own".

Development

How I Started Writing Unit Tests for Vue Components

Dmitry Simonov

In this article, we’ll take a look at how you can start testing Vue components.

Vue
vuejs

Inspecting raw database data in Xperience by Kentico

Dmitry Bastron

This article is a cheat sheet to inspect what's going on with the imported data by Xperience by Kentico Migration Toolkit, resolve some CI/CD issues, and on many other occasions!

Kentico

Learnings from using Sitecore ADM

Anna Bastron

Let's try to understand how the ADM module works, its limitations, and tactics for optimising its performance.

Sitecore

Your last migration to Xperience by Kentico

Dmitry Bastron

The more mature Xperience by Kentico products become, the more often I hear "How can we migrate there?”

Kentico

5 Key Software Architecture Principles for Starting Your Next Project

Andrey Stepanov

In this article, we will touch on where to start designing the architecture and how to make sure that you don’t have to redo it during the process.

Architecture
Software development

Assessing Algorithm Complexity in C#: Memory and Time Examples

Anton Vorotyncev

Today, we will talk about assessing algorithm complexity and clearly demonstrate how this complexity affects the performance of the code.

.NET

Top 8 B2B Client Service Trends to Watch in 2024

Tatiana Golovacheva

The development market today feels like a race - each lap is quicker, and one wrong move can cost you. In this race, excellent client service can either add extra points or lead to a loss due to high competition.

Customer Service
Client Service

8 Non-Obvious Vulnerabilities in E-Commerce Projects Built with NextJS

Dmitry Bastron

Ensuring security during development is crucial, especially as online and e-commerce services become more complex. To mitigate risks, we train developers in web security basics and regularly perform third-party penetration testing before launch.

Next.js
Development

How personalisation works in Sitecore XM Cloud

Anna Bastron

In my previous article, I shared a comprehensive troubleshooting guide for Sitecore XM Cloud tracking and personalisation. This article visualises what happens behind the scenes when you enable personalisation and tracking in your Sitecore XM Cloud applications.

Sitecore

Server and client components in Next.js: when, how, and why?

Sergei Pestov

All the text and examples in this article refer to Next.js 13.4 and newer versions, in which React Server Components have gained stable status and become the recommended approach for developing applications using Next.js.

Next.js

How to properly measure code speed in .NET

Anton Vorotyncev

Imagine you have a solution to a problem or a task, and now you need to evaluate the optimality of this solution from a performance perspective.

.NET

Formalizing API Workflow in .NET Microservices

Artyom Chernenko

Let's talk about how to organize the interaction of microservices in a large, long-lived product, both synchronously and asynchronously.

.NET

Hidden Aspects of TypeScript and How to Resolve Them

Dmitry Berdnikov

We suggest using a special editor to immediately check each example while reading the article. This editor is convenient because you can switch the TypeScript version in it.

TypeScript

Troubleshooting tracking and personalisation in Sitecore XM Cloud

Anna Gevel

One of the first things I tested in Sitecore XM Cloud was embedded tracking and personalisation capabilities. It has been really interesting to see what is available out-of-the-box, how much flexibility XM Cloud offers to marketing teams, and what is required from developers to set it up.

Sitecore

Mastering advanced tracking with Kentico Xperience

Dmitry Bastron

We will take you on a journey through a real-life scenario of implementing advanced tracking and analytics using Kentico Xperience 13 DXP.

Kentico
Devtools

Why is Kentico of such significance to us?

Anastasia Medvedeva

Kentico stands as one of our principal development tools. We believe it would be fitting to address why we opt to work with Kentico and why we allocate substantial time to cultivating our experts in this DXP.

Kentico

Where to start learning Sitecore - An interview with Sitecore MVP Anna Gevel

Anna Gevel

As a software development company, we at Byteminds truly believe that learning and sharing knowledge is one of the best ways of growing technical expertise.

Sitecore

Sitecore replatforming and upgrades

Anastasia Medvedeva

Our expertise spans full-scale builds and support to upgrades and replatforming.

Sitecore

How we improved page load speed for a Next.js e-commerce website by 50%

Sergei Pestov

How to stop the decline of the performance indicators of your e-commerce website and perform optimise page load performance.

Next.js

Sitecore integration with Azure Active Directory B2C

Dmitry Bastron

We would like to share our experience of integrating Sitecore 9.3 with Azure AD B2C (Azure Active Directory Business to Consumer) user management system.

Sitecore
Azure

Dynamic URL routing with Kontent.ai

We'll consider the top-to-bottom approach for modeling content relationships, as it is more user-friendly for content editors working in the Kontent.ai admin interface.

Kontent Ai

Headless CMS. Identifying Ideal Use Cases and Speeding Up Time-to-Market

Andrey Stepanov

All you need to know about Headless CMS. We also share knowledge about the benefits of Headless CMS, its pros and cons.

Headless CMS

Enterprise projects: what does a developer need to know?

Fedor Kiselev

Let's talk about what enterprise development is, what nuances enterprise projects may have, and which skills you need to acquire to successfully work within the .NET stack.

Development

Fixed Price, Time & Materials, and Retainer: How to Choose the Right Agreement for Your Project with Us

Andrey Stepanov

We will explain how these agreements differ from one another and what projects they are suitable for.

Customer success

Sitecore Personalize: tips & tricks for decision models and programmable nodes

Anna Gevel

We've collected various findings around decision models and programmable nodes working with Sitecore Personalize.

Sitecore

Umbraco replatforming and upgrades

Anastasia Medvedeva

Our team boasts several developers experienced in working with Umbraco, specialising in development, upgrading, and replatforming from other CMSs to Umbraco.

Umbraco

Kentico replatforming and upgrades

Anastasia Medvedeva

Since 2015, we've been harnessing Kentico's capabilities well beyond its core CMS functions.

Kentico

Interesting features of devtools for QA

Egor Yaroslavcev

Chrome DevTools serves as a developer console, offering an array of in-browser tools for constructing and debugging websites and applications.

Devtools
QA

Activity logging with Xperience by Kentico

Dmitry Bastron

We'll dive into practical implementation in your Xperience by Kentico project. We'll guide you through setting up a custom activity type and show you how to log visitor activities effectively.

Kentico
This website uses cookies. View Privacy Policy.