Open to full-time & freelance work
Building AtlasLingua: From MVP to a Translation Platform Serving Real Users
|8 minutes read
This case study focuses on the engineering side of AtlasLingua: how the system evolved from a basic prototype into a live application handling daily traffic, real data, and ongoing maintenance. It covers the technical challenges, architectural decisions, and trade-offs involved in building and operating a full system as a solo developer.
Overview
AtlasLingua started as a portfolio project during my ALX Software Engineering program, with the goal of translating between English and Moroccan Darija. After the initial version was finished, I decided to keep working on it and turn it into a real product. Over time, it evolved into a production system used by real users, with ongoing improvements based on real usage and feedback.
Problem & Constraints
The main problem AtlasLingua aims to solve is translating between English and Moroccan Darija, a language that is primarily spoken, highly informal, and has many regional variations. Unlike widely supported languages, Darija lacks standardized grammar rules, consistent spelling, and large, high-quality datasets.
From a technical perspective, another major challenge was finding the right translation approach under limited resources. I experimented with different language models and translation strategies, but budget constraints meant I couldn’t test everything freely. This forced me to research carefully, compare trade-offs, and iterate to reach the best possible balance between accuracy, cost, and performance.
Finally, once the application was made public, accuracy expectations increased significantly. Users relied on the platform for real use cases, which meant translation errors, slow responses, or downtime were no longer acceptable. This pushed the project beyond a prototype mindset and required production-level thinking across the entire system.
Approach & Solutions
Throughout the development of AtlasLingua, I focused on making small, deliberate decisions instead of chasing perfect solutions. Given the limitations around data, cost, and model support for Darija, my approach was highly iterative.
Learning from the Darija communities
Before diving deep into model experimentation, I spent time researching existing Darija-focused technical communities. I found Darija Open Dataset and AtlasIA, which were both inspiring and extremely helpful. Their open-source datasets, guides, and discussions gave me valuable insight into how Darija is structured, written, and studied from a technical perspective. These resources helped shape many early decisions in the project.
Early model experimentation
In the first version of the app, I tested several major language models, including OpenAI and Gemini. I ran many translation tests, but the results were often poor when generating Darija. This was expected, as most large models are trained mainly on high-resource languages and have very limited Darija data.
Despite this, I always believed a better option existed. That led me to Anthropic Claude, which showed much more promising results in my early tests. I used it as the main translation engine and launched the app publicly. At that stage, translations were helpful most of the time, and early users confirmed that the product was already solving a real problem.
Iteration through real usage and feedback
For the first six months after launch, I continued refining the system prompt and closely monitored user feedback. Over time, real usage data clearly showed where the translations fell short - mainly spelling inconsistencies and writing variations that confused users.
To address this, I explicitly documented these edge cases in the system prompt and guided the model on how to handle them. This significantly reduced confusion and improved consistency in the output.
Input normalization for Darija
As the user base grew, I started looking for deeper optimizations. I closely followed new model releases and discussions in Darija developer communities. During several days of testing with newer Gemini models, I noticed something interesting: results improved when Darija was written in Arabic script.
This led to an important realization. While my users mostly write Darija using Latin letters, the majority of Darija content online is written in Arabic script - meaning language models understand it much better in that form.
I validated this by running controlled tests, and the difference was clear: Darija written in Arabic script was far more accurately understood by LLMs.
In the next major system update, I introduced a preprocessing step that converts user input from Latin-based Darija into Arabic script before sending it to the language model. This single change led to a significant jump in translation accuracy, and many users noticed the improvement immediately.
System Architecture
AtlasLingua is built as a client–server application with a clear separation between the frontend, backend, and data layers. From the beginning, I designed the system to stay simple and flexible, knowing it would evolve a lot after launch.
I chose my tech stack carefully, with a focus on flexibility, reliability, and long-term use. For the frontend, I used React.js because it is a good fit for building modern and interactive user interfaces, and it has a large ecosystem of libraries that help projects stay maintainable over time. When working on the UI, I wanted to be pragmatic and avoid spending too much time on custom components. For this reason, I used ShadcnUI to speed up development and keep more focus on backend logic, which is the most critical part of this project.
For the backend, I chose Python because it offers strong support for AI-related tools and libraries, which made it a natural choice for a translation system. I used Flask to build the API endpoints quickly while keeping full control over the application, since it is an unopinionated framework. For data storage, I used MySQL to handle structured relational data, and Firebase for features that require real-time updates, such as the community forum and notifications.
In addition, I integrated third-party services like Algolia for advanced search and SendGrid for handling email communication. Each tool was chosen based on a specific need, rather than forcing all features into a single system.
Deployment & Operating in Production
Deployment setup
AtlasLingua was first deployed on a DigitalOcean VPS, where both the frontend and backend ran on a single Linux server. The application stayed online for over 8 months with no downtime, serving real users every day.
As traffic grew, I monitored error logs and noticed API failures caused by server overload. To handle this, I upgraded the server hardware multiple times, which kept the system stable but increased operating costs. This phase taught me a lot about capacity planning, monitoring, and running a live system under real load.
Later, for cost and scalability reasons, I migrated to a split deployment. The backend API was moved to Heroku, while the frontend was deployed on Vercel. This setup reduced deployment costs by around 20% while maintaining the same level of performance and reliability. It also allowed each part of the system to scale independently and simplified ongoing maintenance.
Handling updates and changes
Because the platform is actively used, updates had to be rolled out carefully. I avoided large breaking changes and focused on incremental improvements that could be deployed without downtime.
This approach allowed me to ship fixes and improvements frequently while keeping the platform stable for users.
Operating a live system
Running AtlasLingua in production meant dealing with real operational concerns such as performance bottlenecks, unexpected input, and edge cases that only appear under real usage.
Performance & Optimization
Performance became increasingly important as AtlasLingua gained more traffic. I focused on improving performance when real usage data showed where the actual bottlenecks were.
Frontend performance
One of the main frontend issues was bundle size. Initially, the application was delivered as a single large JavaScript bundle that included code for all pages. Because the app does not use server-side rendering (SSR), this entire bundle had to be downloaded on the first load, which increased initial load time, especially for new users.
To fix this, I introduced route-based code splitting and lazy loading. This allowed only the code required for the current page to be loaded, significantly reducing the initial payload. As a result, the main bundle size was reduced by ~30%, and page loads became noticeably faster and smoother.
API performance
On the backend, I focused on keeping API responses fast and stable. I reviewed the full request flow and removed unnecessary processing so each request only did the work it really needed. I also paid close attention to the hosting environment, making sure the server hardware was strong enough to handle translation traffic without overload or slowdowns.
To improve the perceived experience on the frontend, I designed the UI to clearly show when data is loading or a request is being processed. I used modern patterns like skeleton loaders and subtle interactions so users always understand what the app is doing, even when a request takes time.
Measuring impact
Performance changes were validated using real usage data rather than assumptions. I paid close attention to page load behavior, session duration, and user interaction patterns to confirm that optimizations were actually improving the experience.
This data-driven approach helped avoid premature optimization and ensured that effort was spent where it mattered most.
Feedback and Iteration
Learning from real user data
Once AtlasLingua was public, real usage became the most valuable feedback loop. Users submitted text in ways I could not fully predict during development, which exposed edge cases and weak spots in the translation pipeline.
By reviewing failed or confusing translations, I was able to adjust prompts, model selection, and input handling in a targeted way. This data-driven approach made each iteration more effective.
User feedback
AtlasLingua includes several direct ways for users to share feedback. This feedback often highlighted translation issues, feature requests, and general improvement suggestions.
Because the platform serves a specific linguistic need, this direct input was extremely valuable. It allowed me to prioritize fixes and future features.
Learning from production behavior
Running AtlasLingua in production changed how I approach development. Features that worked well in testing sometimes behaved differently at scale or with real user input, which pushed me to think more carefully about edge cases, reliability, and long-term behavior.
Lessons from Failure
Community forum: a feature users didn’t need
I spent a significant amount of time building a community forum from scratch, including features like posts, comments, voting, and real-time notifications. From a technical point of view, it worked well and was fully functional.
After releasing it, however, almost no one used it. This made it clear that I had invested too much effort into a feature before validating whether users actually wanted it.
Looking back, a simpler MVP or even a basic feedback channel would have been a better first step. This experience changed how I approach major feature development: today, I validate demand early and expand features based on real usage, not assumptions.
Future Development
There are several areas where the platform can continue to evolve. One ongoing focus is further improving translation accuracy, especially for edge cases and less common expressions. This includes experimenting with better context handling, refining prompts, and evaluating newer language models as they become available.
Another area of interest is expanding language support. While the current system is centered on English and Darija, the architecture allows for adding additional languages in the future, particularly those that share similar challenges such as informal usage or limited resources.
From a system perspective, there is room to improve observability and automation. Adding deeper monitoring, better error tracking, and more automated deployment steps would make long-term maintenance easier as usage grows.
What I Learned
Working on AtlasLingua taught me lessons that go far beyond writing code. Building and maintaining a real production system forced me to think differently about software development.
One key lesson was the importance of iteration over perfection. Trying to solve everything upfront did not work. Shipping early, learning from real usage, and improving gradually proved far more effective than aiming for a perfect solution from the start.
I also learned how critical real users are to good technical decisions. Many assumptions I made during development were challenged once people started using the platform. Observing real behavior and feedback helped me focus on changes that actually mattered.
Another important takeaway was balancing trade-offs. Improving accuracy, performance, and reliability often pulled the system in different directions. I had to learn when to optimize, when to keep things simple, and when to accept practical limitations instead of over-engineering.
Finally, maintaining AtlasLingua over time taught me the value of ownership and responsibility. Supporting a live system changed how I approach design, testing, and deployment. I now think more about long-term maintenance, clarity, and stability than just feature delivery.