If you own or operate a web application, you may find weak spots in your business that you did not know about.
Web applications.
They come in two forms. A website presents content - the user reads it, consumes information, but does not work in it. For example a blog, news site, company presentation, documentation, other static content.
Then the second form - a web application solves a task. The user actively works with data - creates, uses, edits, decides. It has persistent state, requires user input, contains business logic and typically knows who the user is.
Unlike a traditional desktop application, a web application requires no installation, works on any device with a browser and is available at any time. The most common forms are e-commerce, internal business tools, CRM, CMS, HR systems, communication apps, booking systems, project management, educational platforms and many others.
The owner and operator is typically an entrepreneur or a company.
The risk of a bad start.
In the beginning you typically don't know exactly what you need, don't understand technology, make decisions based on price regardless of suitability and don't think about long-term results. If your business relies on software, chances are you chose the easy path with an off-the-shelf solution.
Off-the-shelf solutions like CMS, no-code/low-code platforms, ready-made e-shops, "Do it yourself" tools. Betting on the fastest and cheapest start looks like the right choice. It ensures low costs and quick launch. The number of websites built this way is enormous. Just look at the growth of these platforms and the number of their users.
Over time you hit the limits of the platform and have to adapt. Competitive advantage is nearly impossible. And if you turn to agencies or freelancers, it is very likely that you will get the final product built the same way.
The modern risk.
In recent years this reality is further reinforced by artificial intelligence tools and so-called "vibe coding".
"Vibe coding" means a developer gives instructions to an AI tool instead of writing code and accepts the result without deeper understanding of what is being created. Applications are built much faster, but the quality of the foundation continues to decline.
What it looks like in practice.
What we see most often: Complex, cluttered, unintuitive user interfaces that contradict business logic, blank pages or pages with error messages, payment limited to a single inconvenient method, "auto translate" instead of proper internationalization, obvious SEO problems, broken buttons and forms, lost, duplicated or incomplete submitted data or orders, wrong or missing event notifications, broken search, no way to integrate external services.
Behind the scenes - code quality, the need for manual intervention in things that should be automatic, problems with security, accessibility, backups, inability to extend and scale the application.
Long-term impact.
Poorly built software is not just a technical problem, it is a fundamental problem for the entire business. It slows growth, consumes energy and resources, prevents development, limits potential profit. You cannot respond to opportunities because the software won't allow it.
The realistic scenario doesn't have to be "the company goes under". More likely the company never reaches what it could have and slowly loses competitiveness. And that is perhaps the worst aspect of the whole problem - you don't know what you don't know. You have never experienced how it could work "properly", so you have no comparison.
You see the symptoms - development is slow, changes are expensive, something is always broken, but you don't connect it with the fact that the root of the problem is a bad decision you made xxx years ago. Instead you look for the cause elsewhere and the solution you choose is the same as back then.
There is also another way.
A better path and expectations.
There are several conditions this requires. The first is the entrepreneur or their representative as product owner. It is not enough to assign a project and wait for the result. You need to understand every feature you are building and the reasons why you are building it. Actively decide on priorities and continuously validate that what is being built matches your business vision. A random person cannot be the "product owner" on your behalf.
The second is custom-built software with a solid foundation. No compromise due to platform or template limitations. Every part of the system must exist for a specific business reason and the foundation must be built so it can evolve. The application may have limited functionality at the start, but it must be well-built and fully aligned with the business vision from day one. That is the only path that makes long-term sense.
You need to accept that a custom application is a long-term investment, not a one-time expense. The first working version takes months, the full vision possibly years. And that is not a flaw, it is a natural consequence of the application growing together with the business.
A web application is a living system that continuously evolves. Costs are significantly higher than an off-the-shelf solution and don't end at launch - operations, development and maintenance are ongoing items that never stop. Anyone who doesn't accept this from the start will sooner or later end up in the same situation as with an off-the-shelf solution. Just with a bigger investment behind them.
This is hard to digest, especially if you have never experienced how it can work properly. "Do it yourself" works slowly, with limitations, but it works. The pain is not great enough to justify a higher investment whose value you have nothing to compare against yet.
This path is therefore realistically only an option for those who have the initial capital and a clear vision, or who have already experienced firsthand what it means to build a business on a bad foundation and understood what it cost them.
Who is the "product owner"
A product owner is a persona who bears full responsibility for the product. It is not a project manager or coordinator - it is a person who understands the business, understands the users and actively decides what gets built, in what order and why.
In practice this means the product owner continuously communicates with the development team, validates what is being built, rejects what doesn't fit and sets priorities based on business value - not based on what is technically interesting or what the developer thinks would be nice to have.
If no one fills this role, the development team builds based on their own judgement. The result may be technically correct but miss the business mark. And that is usually discovered too late.
In a small business the natural product owner is the entrepreneur themselves. If they don't have the capacity, they can delegate this role to someone who knows the business well and has the authority to decide. But never to someone who merely relays requests between the entrepreneur and developers - that is not a product owner, that is a middleman.
Comparison of approaches
Standard, "free"
Better, "premium+"
Initial decision
price and speed
vision and foundation
Type of solution
platform, ready-made template
custom software
Role of the entrepreneur
requester, DIY developer
product owner who leads
Functionality
everything at once, poorly
less at first, but well
Architecture
limited by platform
built for growth
Code
hidden, foreign, unmaintainable
own, clean, extensible
Costs
low at first, grow hidden
higher from start, predictable
Development
slow, expensive, limited
natural, planned
Changes
expensive and slow
part of the process
Competitive advantage
nearly impossible
realistic
Dependency
on platform or vendor
own system, own knowledge
Technical debt
inevitable, invisible
consciously managed
Long-term result
stagnation, lost potential
business grows with the software
Performance and cost over time
Performance - Standard, "free"
Performance - Better, "premium+"
Costs - Standard, "free"
Costs - Better, "premium+"
The standard solution starts faster - performance grows, then quickly stagnates and begins to decline. Costs keep rising the entire time.
With the better solution it starts slower, but performance grows continuously, while costs gradually decrease.
We use for application development:
Frontend
JavaScript, TypeScript, Next.js
Everything the user sees and interacts with in the browser - interface, interactions, visual side of the application.
Backend
Node.js, Nest.js, DDD, CQRS, Event Sourcing
Application logic, request processing, business rules, communication with the database and external services.
TDD
Jest, Vitest, Playwright, unit, integration, e2e tests
Automated testing that verifies the application works correctly - at the level of individual functions, integration and complete user scenarios.
Database
PostgreSQL, MongoDB, Redis, Kafka, RabbitMQ
Storage, structure and management of application data.
API
REST, GraphQL, WebSocket
Interface for communication between frontend and backend, or with external services.
Protecting the application and data from unauthorized access, attacks and data leaks.
Deploy
AWS, Google Cloud, Azure, VPS
Environments and tools for deploying the application to production.
Performance
Caching, CDN, lazy loading, load balancing
Optimizing speed and scalability of the application under load.
Monitoring
Sentry, Grafana, Prometheus, logging, alerting
Real-time application health monitoring, catching errors and anomalies.
Case study.
What it contains, how it works and how much it costs to develop this web application.
This web application is built as a company presentation with interactive content and a contact form. Its goal is to offer services and make it easy for potential clients to get in touch.
It also serves as a demonstration of the basic building blocks of a modern web application - user management, authentication, database operations, multilingual support, form processing.
It is a full-fledged application with a backend, database, authentication and automated deployment. It covers the complete lifecycle - user interfaces, backend logic, automated testing and deployment. The result is a secure, tested and maintainable application with clean architecture that works reliably and can be further developed.
Frontend - User perspective.
Main page with content and navigation.
A page with a header, interactive content and footer, optimized for search engines (SEO) - contains properly structured metadata, titles and descriptions. The application is adapted for screen readers and assistive technologies.
Multilingual interface.
The application supports internationalization. Language is set automatically based on the browser, the user can switch it at any time. The choice is remembered for the next visit. The localization system is designed to easily add more languages.
Light and dark mode
The user can switch between light and dark appearance. The choice is saved and applied automatically on the next visit. The page icon changes based on the selected mode.
Error pages, i.e. 404 and 500.
If the user enters a non-existent address, a page is displayed with information and a link back to the main page. The same applies for unexpected application errors.
Sign in and sign out
The user can sign in using an account with an external provider. After signing in the interface changes - instead of the sign-in button, the user's name, avatar and a sign-out option are displayed. Authentication works via the standard OAuth protocol - it is possible to add any OAuth provider by adding the corresponding configuration or implement custom authorization logic as another method alongside external providers.
Contact form
A form with fields for name, email, project URL, description of needs and other details. The application confirms submission to the user or shows what needs to be corrected.
Notifying the user about important events
The user is informed about important events via popup notifications - for example when signing in, signing out or when a backend error occurs.
Backend application
What the Backend does.
Data and business logic are processed on a separate server. The backend communicates with the frontend through defined API endpoints - it is not publicly accessible.
Session management
On the first visit a session is created where user preferences are stored (language, theme). If the session expires, a new one is created and the user continues without interruption. This data can be further used for analyzing user behavior on the site, evaluating the most common preferences or targeting marketing activities.
Authentication
Sign-in is handled through an external provider using OAuth. After successful sign-in a JWT token is issued and user data is linked to the session. Every sign-in and sign-out is recorded with a timestamp.
Security
Requests are limited by a rate limiter with tiered limits based on endpoint sensitivity. Bot requests are detected and silently discarded. Every request is verified to belong to the sender.
Input validation
The server accepts only allowed fields - everything else is rejected. Auth data (name, email, avatar) cannot be overwritten through the preference endpoint. Language and theme values go through validation to prevent unexpected or unauthorized data from entering the system.
Contact form
The backend receives data from the form, validates it and stores it in the database. Requests identified as from bots are silently discarded without saving anything. The purpose is to protect the database from spam and ensure that stored data comes from real users.
Request tracing
Every request gets a unique trace ID. This ID is returned in response headers, so the frontend and developers can look up a specific request. It simplifies problem diagnosis - when an error is reported, it is possible to precisely identify what happened on the server.
Provider preflight check
Before redirecting to an external provider the backend verifies that the provider is available. If it is not, the user is not sent to a broken page.
Graceful shutdown
The server shuts down cleanly - it finishes in-progress requests and only then terminates the process. No data is lost and no connections are cut off.
How the application is built - technology, tests and deployment.
Monorepo
The project is organized as a monorepo - frontend, backend and shared code (types, constants, UI components) live in a single repository. The purpose is simpler dependency management, sharing code and configurations between projects and the ability to make changes across the entire application in one step, easier management of individual parts and build orchestration. The application uses a minimal number of external dependencies - this reduces the risk of security vulnerabilities, simplifies maintenance and updates and reduces the resulting application size.
Frontend
Next.js is a framework for React that provides server-side rendering, routing and performance optimization. React is a library for building user interfaces from components. TypeScript adds type checking, catching errors already during development. Sass extends CSS with variables, nesting and modularity, making styles cleaner and easier to maintain.
Backend
Node.js with a custom HTTP server. TypeScript, MongoDB as the database. JWT (JSON Web Token) for token management - allows verifying user identity without querying the database on every request. The architecture uses established design patterns: clean architecture, DDD (Domain-Driven Design - structuring code around domain entities and rules instead of technical layers), CQRS (separation of read and write operations - allows optimizing each operation independently), command, factory and middleware.
Testing
The application is tested at multiple levels. Unit tests verify isolated parts (configuration, logger, bootstrap) on the native Node.js test runner and using Jest with Testing Library. Backend E2E tests run against a real MongoDB - tests verify actual application behavior. Frontend E2E tests via Playwright simulate a real user in the browser - complete flow including language switching, themes, sign-in and form submission. Tests are part of the CI/CD pipeline - they run automatically on every build and if any test fails, the image is not created and deployment stops. Only tested code reaches production.
CI/CD pipeline
Each application has a multi-stage Dockerfile: dependency pruning, running tests, production code build and final minimal image. The backend is bundled into a single file, the frontend produces a standalone Next.js output. All operations (development, tests, build, Docker, deployment) are controlled via Makefile - a unified interface for developers and CI. A push to the main branch triggers a GitHub Actions workflow - builds Docker images, runs tests in a container, deploys via SSH to VPS (pulls the new image, restarts containers) and performs a health check after deployment.
How much it costs - cost estimate
What needs to be developed - work breakdown
Development includes project structure design and shared code setup, on the backend an HTTP server with middleware pipeline, session management, auth flow, JWT, rate limiter, bot detection, validation, persistence over MongoDB, error handling, graceful shutdown and tracing. On the frontend pages, routing, layout, all interactive components, server actions, cookie management, notifications, error pages, dynamic style switching by theme and localization. Plus unit and E2E tests for both parts including test helpers and mocks, and infrastructure - Dockerfiles, multi-stage build pipeline, CI/CD via GitHub Actions and deploy to VPS.
Team composition
An application of this scope can be developed by a single senior full-stack developer. When splitting the work, the ideal team is two people - a frontend developer and a backend developer, where one of them also covers DevOps (Docker, CI/CD, deployment). They do code review for each other. Graphic design (visual design) is assumed to be provided externally.
Estimated development time
For a single senior the estimated time is approximately 1 month. With two developers the time shortens to about 2 weeks.
An application of this scope represents hundreds of hours of work by an experienced developer. The final price depends on specific requirements and business logic complexity.
For reference - an application comparable to this case study typically starts at $5,000.
We will prepare a specific quote based on a consultation.
If you are planning work on your web application or considering building one from scratch, contact us. We build reliable and quality tools for your business.