Be warned! This post is a lengthy one and will take you approximately 20 minutes to read through, so bear that in mind if you're deciding to consume it.
Scrolling the web as a software developer we often come across funny text message screenshots, where fellow developers are asked by their friends, family members or semi-strangers to develop a killer mobile or web app for them, often because they think it is going to be a simple job.
I am here to tell you, that if you want that app to work, it is not going to be a simple job. Not if you expect your application to take off, and someone has laid the ground work for that.
Having worked in this field for over 15 years, I am going to try and describe everything that goes on during my normal development project and keep it as simple as possible for anyone to follow. It might get a bit technical, but I will try and adjust if needed.
The short point I am trying to make is there are a lot of choices that we have to make that impact the amount of work we have to do and it’s all dependent on the complexity of the problem we developers have been tasked to solve.
I will also try and keep this info package updated as I find mistakes in it, or discover new things.
Let’s start by covering what agile software development is, how I typically start a software project, what web and mobile development involves, to the trade-offs I have to make when selecting different technical solutions. All of this is to give any reader an idea where time is being spent and what choices we have to make.
Finally, I will share a case study from a project I completed recently that took over a year to complete.
Agile
I would like to start this brief into explaining what agile software development is, but before I can do that I have to explain the history behind it.
History
Agility was an idea that originated in the early 2000s from a group of established software developers / consultants, who had seen the failure in what was called the “waterfall development process”.
“Waterfall” consisted of making a huge plan upfront, having the customer sign off on it and then actual development could begin. The development phase often took from 6 months to over a year and typically ended with the realisation that the software did not solve the problem the customer needed. That was because the problem had evolved during that time, or because some problems were not discovered during planning. Nobody realized to talk to the customer during development. Instead it was decided that following the established plan was the key to success.
To fix this, a manifesto for software development was drafted that contained specific values and principles that developers should follow, which I will summarise:
- Developers should work in small steps and release working software often (nowadays daily or at most weekly) for customers or stakeholders to try out and give feedback on.
- Developers should collaborate closely with the customer to discover if we are building the right thing and correcting course / adjusting as we learn new things during this process, or what we gather from the feedback.
The goal is to satisfy the customer and to give them the software to try out as early as possible. It might even be possible to have actual users use that software from that first release, but it might not be that appealing.
The project triangle
When you are thinking about starting a web or mobile development project, you often want an estimation on two things:
- Cost
- Time
The thing is that these two are unknowns. They are relational to the amount and complexity of the requested features. Unless we have completed work like that over a hundred times, developers are unable to give an exact time (and thus cost) estimation on how long the work will take. We can just guess.
Sometimes people put together an estimate of hours that they will work on the project, and then hope that developers hit that goal. Most of the time they won’t.
We (developers) cannot know how much time it takes to do the work, so we can’t tell you how much it actually costs until we start working on the problem.
This is where agile software development will help you. Instead of an agreed plan, we should focus on collaboration.
Agile lowers risk and cost of being wrong

Agile software development tries to alleviate this uncertainty and lower the risk involved (and thus lowering cost) by breaking the work down into smaller, releasable, packages (or steps).
The idea is to work in small steps, release frequently, and get feedback on the work, so we can correct course as fast as possible and aren’t spending time building the wrong thing. Agility also enables the customers to pull the plug if they think the cost is running out of control, or development is not working out.
In the end you will have a piece of working software that you can use (as it was delivered as early as possible), and one that you can also continue development on with another party. You also didn’t have to pay a huge pile of money for a piece of software that doesn’t even work. You only paid for the work that was completed up until that point and because you have been reviewing and providing feedback on it in regular intervals, it should work as expected.
Software projects

So, most often software projects are developed using an agile software development method. At least mine, anyway. But how does a software project typically start?
Well, it varies from company to company. By a lot. However, I can tell you how I typically approach any project so I can get enough information to start working on it and minimize accumulating any hidden cost.
Problem
After introductions I will typically move the conversation into trying to figure out what the problem is that a customer hopes for me to solve. This can be as simple as:
Our website is outdated and we’d like a fresh, modern, design and also the ability to update the site’s content ourselves.
To more complex solutions:
We’d like to develop a point-of-sale (POS) system that we can tailor to our needs for improved work flow and not have to pay third party vendors a percentage
Often the discussion about the problem will lead to discovering the value that the job creates.
ROI
Value is not always, but quite often, monetary. Something that can be counted in dollars or euros saved, or gained. Other types of value be knowledge gained, boost in productivity, increase in customer satisfaction, etc.
Most of my clients want a monetary gain out of some product, so the goal is to discuss the value in terms of return on investment (ROI).
You invest some money for me to develop your application, and my goal is to enable you to get a return on that investment as soon as possible. If you do not have a plan on how you are going to get a return on your investment, you are simply going to lose money and nobody wants that.
Context
After the problem has been identified I will ask more questions to get a better understanding of the context. Some of them will affect the planning.
- What is the market for such a product (if developing one)?
- Can this problem be solved using existing tools on the market?
- Have you thought about marketing or advertising the product? What about licensing?
- What constraints are there ie. budget, data security, privacy, technical limitations?
- Is there a regulatory or a soft deadline?
- What do you expect the usage for this product or app to be at launch and later?
Once I have gained more insight into the problem, I can ask about the features. Depending on the size of the product, features can either be a simple list of things a website content management system (CMS) needs to have (and the website present), or I suggest we go through a slimmer form of user story mapping.
User stories

This step involves putting ourselves into the shoes of a user and thinking what the user needs to do with the product. This will give us insight into the features the product needs to have and in what order they should be built.
These features are simply the very skeleton we will begin to work with. We should not assume to be the actual user and instead gather feedback from actual users. As we gain that feedback, more stories might emerge, some stories might be dropped and some might change.
From user stories we will normally discover some non-functional requirements, which simply means the quality attributes, or architectural characteristics. They will drive technical decisions later.
User stories will then be prioritised to figure out what steps we need to take to make the product actually work for users.
MVP
Within this map of user stories we can also draw horizontal lines to carve out the minimum viable product (MVP). We can say that with the collection of these features we can release this product to the users. That is the point that the application will actually begin producing value and not be something that sits on a shelf.
That is often the initial goal. Once we have agreed on the goals, the constraints and the plan, we can start development.
Web and mobile development
Now that we have gone through the project plan and know what the problem is, and know that this is actually worth investing on, we can start development.
The most typical projects I do are split into three categories:
- Websites
- Mobile applications
- Web applications
This list is in order from smallest type of project, to the biggest. Sometimes these categories do overlap.
I will now break these different categories of projects down to explain what they involve. Do note that no project is ever similar to another. These descriptions contain some of the most common things I’ve come across as I’ve worked on hundreds of different projects.
Websites

Websites are normally the simplest form of project. Typically I work with smaller companies or individuals who don’t have the need or budget to hire a big design and software development company to do big user experience design and development for their website.
A website project consists of the two steps that can also be iterated over throughout the project:
- User Interface (UI) & User Experience (UX) design
- Web development
At the start of the project I will make it clear that I am no user experience design expert, but I will still try and embed this portion into the design work. I have done user experience design, read literature and worked with professionals, trying to study their ways of working, but I do not have formal education in this field nor do I work on it on a daily basis.
However, I do not have the experience or resource to set up UX testing with users or formulate user personas.
User experience design has (in my opinion) taken over in importance over user interface design. Users want a better experience over a better look. This is why I involve this into the work, even though I might not be the greatest expert in it.
In any case, once the initial UI/UX is done, I start development. At this point of the project I have already decided the following:
- The programming language. Most common: PHP and JavaScript (TypeScript)
- The content management system. Most common: Wordpress or Strapi
- The hosting plan. Most common: Smaller hosting provider over cloud provider.
- The database solution. Most common: Relational database (MySQL).
- Additional resources. This includes things such as email inboxes.
All of the things mentioned above will often surface in the early stages of the project and are based on the requested features. I will give out suggestions to the customer based on my experiences and they can give feedback on those.
In every one of these choices I try to be as cost effective as possible, and not suggest the most expensive solution out there. Normal websites have such low amounts of traffic that smaller hosting provides are capable of hosting them. Typically they offer a single server solution that includes both the ability to host the website code and a database to store data in.
In case we identify that the website is subject to high amounts of traffic, or has some features that require extra performance to complete, I will suggest other technical solutions.
This might include separating the user interface from the server side implementation and hosting that on a Content Delivery Network (CDN) which has multiple access points around the world, offering high availability to users. Also, in these cases most of the content on the site should be embedded statically onto the website and not fetched over the network.
It might also mean separating the database from the server, so it can be scaled individually and maintained separately. In this case the website can also be maintained separately.
These are all choices we have, but might not need. They are technical details that I have to think about when building a website. The more complex the problem, the more time needs to be spent to solve the problem with better solutions.
Mobile applications

In the previous section I mentioned that one option to website development is to separate the user interface from the server side implementation. This offers additional performance, but it increase the complexity of the project, because it means building two separate applications.
The user interface application for the web is more commonly called a “front-end application” and in a typical project is built using modern UI libraries such as React, Vue.js, Angular or Svelte, where the preferred language is TypeScript. These libraries offer an easy way to build reactive UI applications that automatically re-render when the contents of that application change.
What I have come to understand through my work, is that mobile and front-end web application development are very similar. Both are simply user interface applications that communicate with a separate system / application, which is located on a server and accessible over the internet. While the development platform, framework, language and ecosystem differ, the concepts are very similar.
The most notable difference between mobile and front-end web application development is the end result. The medium through which the application is made accessible to the user. This is either a mobile device or the browser on a computer, accessed via web address.
Mobile applications can of course be developed without the need for a server-side application (also called a “back-end application”), in which case the idea is to leverage the devices own capabilities (storage, camera, location etc.)
However, in most cases you do need that server side system to, for example, store some data that the user inputs on their device, so it can be accessed later.
In such a case you will need to develop two applications. One is the mobile application that simply talks to the second application, the server side system. This is simply because the mobile application runs on the users device.
The users device cannot run your back-end application. This system is the heart of your product, executing your business logic or maybe there to store some data on a database, so people can access it later, even from other devices. The user simply talks to it. It needs to be separated and secured by you. Anything the user puts in their devices can be accessed, read and even altered by the user.
In more cases than one, there has also been a need to access user inputted data by the people who run the product. In these cases the solution I will suggest is developing a third application, typically another front-end web application, that allows them access to that data. This allows them to access the data via a browser (computer or phone) and it has some hardened security so as to not allow regular users access to it.
While such capabilities could be added to the mobile application, it would restrict access to the data to only be available through a mobile device, and it would mean adding unnecessary complexity into the mobile application that is not needed to be there. It would also bloat the application size which would impact users negatively.
It does require your back-end service to cater both to the user, and the internal product team, so you won’t have to duplicate the code required to run the service. It is easier to separate this functionality within one back-end service, than it is to do it on the mobile application. And it does not affect regular users at all.
There are multiple choices you can make with mobile application development, and back-end application development, which I will explain further down this article in the section Development trade-offs and solutions. All of these are dependent on the requested features which impact time and cost of the project.
Web applications
Web applications are typically an extension to the two previous categories mentioned before (websites and mobile applications).
These types of projects typically involve building any of these types of applications:
- Websites
- Mobile applications
- Front-end applications (user interface applications)
- Back-end applications (server-side applications or systems)
There are times where front-end and back-end applications can co-exist within one application, where the back-end serves the user interface to the browser, but when you mix in mobile development, or have the need to individually scale or maintain the user interface, this is not an ideal solution.
A mobile application typically talks to a back-end application via an Application Programming Interface (API). When you already have the need to build a back-end application that can be communicated with through an API, it makes sense to write a separate front-end application as it offers clear separation, which enables better performance, individual scalability, maintainability and flexibility, even though it might take a bit more time.
Even simple websites can be built using a front-end application that serves the website to the user, but it simply communicates with a CMS using an API. This enables you, for example, to host your website statically, meaning the users can access it’s content at lightning speed. Even faster, if that static content is served through a CDN making it quickly accessible anywhere around the world.
This type of development is possible, but most of the time overkill for simple websites. Sometimes a simple Wordpress application with custom templating is needed to serve the site on a small hosting provider.
Back-end applications normally come in so many different varieties that I will not list them all. They run the logic on a separate server. They can be written in many different languages, hosted on many different places (including different cloud providers) and they can store data in a plethora of different databases or storage options. You can also add in all sorts of different blocks there to improve performance.
I will try and cover some of the trade-offs there in the next section.
Web application release process
A typical release for a website can be as simple as just uploading the code and database onto a live server manually. Often enough there is no need for further development. Content can be edited through the CMS and structural changes are not needed.
Web applications might require a bit more work to release. You might need to enter a server via a command line and execute some commands manually. Depending on the frequency of changes you might have to do this multiple times a day, and typically I would like to automate this. This means continuous delivery.
I prefer to use continuous delivery when-ever possible, meaning when ever I deploy changes to my code it can automatically be deployed to the users. It also means developing (or adding to a platform) a continuous integration and continuous delivery pipeline that automatically builds and tests my code, after which I can press a button and it gets installed onto a server and is accessible to users.
Sometimes setting these up is very simple, taking 5 minutes, but depending on the complexity it can take an entire day worth of trial and error. Some platforms are designed to support this type of pipeline and setting it up is a piece of cake!
This is typically an option more suitable when deploying software to a cloud platform, which is why I’ve taken some time and written a deployment tool for on-premise servers. In those cases I install my own application there that listens to changes on the version control system (VCS) and re-builds the application on the server when that happens. Typically it means when I change code and then commit those changes to a VCS, the changes will be live on some website in a matter of minutes.
Continuous delivery enables fast delivery of new features and fixes to users. It also validates that those changes work via automated testing, to make sure we didn’t break anything. Without continuous delivery, we would have to manually execute some commands on a server to enable those changes we made and this is wasted effort every time. We want to automate that.
Sometimes such automation is not necessary. It can be overkill. It really depends on the frequency of changes needed. This is why it needs to be done on a project basis, unless it is cheap (or free) to set up.
Mobile application release process

Mobile application release process’ can be similar to web application, but once you build and test your code, you are given an application file that must be uploaded to either Google Play or Apple App Store for review.
This review process includes looking over your application information you’ve entered on their platform as well as the application itself. The review can take up from a few hours to days, or even weeks.
The initial release in any app store also requires you to have in place a privacy policy, screenshots from your app, terms of use, set up geolocation and age restrictions, fill up information describing the app, among other things. These will all be reviewed.
This means the speed of which you are able to deliver new functionality to users is very much dependent on the whims of big companies that host those applications on their app store. Unfortunately there is nothing we can do about this.
This leads to bundling up features and fixes and then releasing a new version of the application, after it’s been tested to make sure there are no mistakes or errors present, because we are not able to release frequently. It is very much a manual step that takes time, and something that needs to be considered when starting a mobile application development project.
Summarizing
Websites projects can be simple to develop, or complex, depending on the need. Many things factor into this and I always hope to cover those needs early in the project as to not accumulate hidden costs.
Mobile applications are very similar to front-end web applications on the concept level, but often require a back-end application that they communicate with. This means developing two separate applications. In many cases there might be a need for a separate web application to access the data users have inputted to the system. This is of course something that depends on the problem at hand.
Web application projects can contain both website and mobile application development. Normally it involves building a web system that might have separation between the user interface and server-side implementation. Typically there is more complexity involved on the server side, which means weighing in more choices to keep cost down while not sacrificing quality.
Development trade-offs

All software development is about choices. Software architects are sometimes called people who sell options. Each option is a trade-off. You choose one perk over one disadvantage.
The things we have to think about when doing either web or mobile development are:
- Software architecture characteristics
- The programming language
- The ecosystem
- Data storage
- Platform
All of these things have to be thought about within the context of the problem we are trying to solve.
The thing I like to do with a bit more complex projects is to identify the architectural characteristics it has to have. These are sometimes found during user story mapping and will affect most technical decisions I have to make.
Characteristics of software architecture

All software exhibit some form of architectural characteristics. These are the "illities" of software architecture.
There are multiple different characteristics, but I will list a few of the most common ones I have to consider during comlex projects. Each of these will impact technical decisions I have to make during a project.
Scalability: The ability of a software system to handle increasing amounts of work or traffic without sacrificing performance or reliability. This will impact decisions such as separating the front-end application from the back-end application, what architecture to use on the back-end service and if there is a need of having a separate database server.
Security: The ability of a software system to protect against unauthorized access, data breaches, and other security threats. This often impacts decision to use a separate identity provider, to have the database server located on a separate server with hardened security and applying the principle of least privilege.
Performance: The speed and efficiency with which a software system can perform its intended functions. This impacts things such as separation of applications, how much hardware is required on the back-end services, what database option to use (relational or non-relational) and if caching is required.
Portability: The ability of a software system to run on different platforms, operating systems, and hardware configurations. This impacts decision to containerize applications to be run on any platform, and using proven tools that are available on multiple platforms and not using proprietary services locked to a specific vendor.
Some are so common to me, that I don’t even consider them separately. Instead always try to embed them in the software in one form or another.
Maintainability: The ease with which a software system can be modified or updated to fix bugs, add new features, or improve performance.
Testability: The ease with which a software system can be tested to ensure that it functions correctly and meets its requirements.
Usability: The ease with which users can interact with and use a software system.
Modularity: The ability to divide a software system into separate, independent modules or components that can be developed, tested, and maintained independently.
I am repeating myself, but there are more characteristics outside this list and they all affect the technical choices I make for any application. Some more than others.
Programming language
Once I have identified the quality attributes I need to consider when building the product, I can move on to selecting some of the bigger technical choices on the project. One of the most important ones is the programming language I need to work with.
There are a number of languages developers can choose from when developing either mobile or web applications.
When it comes to web applications developers will have a plethora of options to select from. You can use a single language to serve both the front-end application and back-end application (or combine these both to just one application), or separate these two by selecting a language you think is better for the problem at hand.
For mobile application development options are more constrained and will be influenced by the requirements. You need to ask yourself two big questions:
- Will this application be released both for Android and iOS
- Is application performance a top priority?
In case the first answer is a NO, then your options should be Java/Kotlin or Objective-C/Swift. These are native mobile application programming languages which offer the best performance.
If the answer was YES, and performance is something that is not the highest of priorities, then you can opt in for a hybrid framework and the languages that come with it.
The most popular ones here are Flutter and Dart, or React Native and JavaScript. What this enables is using one single codebase to release your application on both mobile platforms (Android and iOS). This also means not having to develop the same application twice using two languages.
These choices can also be affected by the ecosystem around the language, which I will talk about in the next section.
These are all trade-offs we need to think about. Some languages are simpler, while others have a bigger runtime attached to them. Some languages are more suitable for artificial intelligence, automation work and\or scripting, while others are better at handling huge amounts of network requests with short response times.
Ecosystem
Ecosystems are often tied to the selected programming language. It is not something you choose if you decide to go with a specific language, but it should affect your decision when selecting a language.
An ecosystem is beneficial for:
- Providing you with a wide range of tools and libraries that simplify the development of complex software. These tools and libraries provide ready-made functionality that developers can use to build their software quickly and efficiently.
- Collaboration and community. These communities provide support, resources, and opportunities to share knowledge and collaborate on projects.
- Standardization. Libraries and frameworks that promote consistency and best practices in software development. This standardization can lead to more reliable and maintainable software.
- Rapid development. Providing developers with the necessary tools and resources to quickly prototype and test their software. This ability to iterate quickly can lead to faster development cycles and more frequent software releases.
Web application development languages typically have semi-decent ecosystems around them. JavaScript is one of the best examples of a thriving ecosystem (maybe even hyper-driving).
Such hyper-drive does have it’s downsides. This can be seen in the form of developers relying too much on open source solutions (packages, libraries, frameworks) that the application will become dependent on them and require constant maintenance to keep up to date.
On the mobile side of things, native programming languages tend to have better package support to enable developers to use code that was written by other developers under open source licensing, enabling faster development. Hybrid frameworks and languages that come with them might be a bit more rough in this sense.
As an example, I implemented authentication for an application using Azure Active Directory (AAD, identity provider) and I had a choice to make. Either implement the flow myself, or use a package that was at the time of development, somewhat outdated, not maintained and having issues with the web view (browser inside the mobile application). There were no other options for open source packages. Luckily after a year the package was re-written and some issues I had with it were fixed.
Overall, active ecosystems are incredibly beneficial and tied to the language you decide to select for the application.
Platform
Selecting the platform to host your application is one of the most important things that will affect cost for starters and can hinder portability.
Portability can often be solved by containerization. Development of applications inside virtual containers, such as Docker, that can be run on almost any platform out there, with scalability.
Developing using cloud platforms such as Azure, Amazon Web Services (AWS) or Google Cloud Platform (GCP) is very tempting, as they offer the tools to host your services with minimal effort and you can get started quickly. While typically you can get away with under 500$ a year in running cost when deploying any application on a cloud platform, where you need a server and database, you might start to accumulate hidden costs if you’re not too careful.
On-premise servers and smaller hosting providers are often the cheaper solution, and very much an option when hosting a simple website, but you might not have access to the underlying virtual machine to set up anything you like. You also don’t have that much options in terms of scalability, as these smaller hosting providers don’t have automated tools to automatically scale up your servers when needed.
The decision to develop your application on a cloud platform, or using on-premise servers is dependent on the identified architectural characteristics. Does your application have to be scalable, flexible, available, maintainable or do you require more visibility and monitoring to it’s day to day workings? The cost is another thing to keep in mind. Both development and running cost.
And typically the thing that will cost you the most is data storage.
Data storage
Data storage involves many things. The most common type of data storage is a database.
One database for an application can hold very small amount of data, or very big. Typical website databases can be from megabytes, to gigabytes, where big monolithic web application databases can be measured in terabytes.
The amount of data you need to store will impact the decision on what type of data storage to use. Performance as an architectural characteristic is also something that you need to consider.
Some database types, such as NoSQL, might be more performant in some cases if you have identified all the access patterns to your data. On the other hand, relational databases are the default database type as they fit almost every use case.
Selecting the correct database type also affects usability of the system, as well as it’s maintainability.
On the subject of performance, you might also need a caching layer on your back-end services to host some part of your data to make it faster to access. This will impact your network request times. When your application can fetch the data from a next door cache, as opposed to asking the database to search for it, those seconds users would have to wait could now be milliseconds.
Databases and data caches however are only specific types of data storage. You might also need to store files. In these cases we have to look for either some form of an FTP, or an object storage. Object storages typically offer data storage solutions that can be calculated in terabytes, so they are a better solution. Also, these storages are typically only accessible through an API, and not through an FTP or SSH connection, making them a bit more safe.
Data storage can be the most costly thing you can run on a web application, depending on the architecture and platform of choice. A huge database that is poorly optimized has to have top notch hardware to compensate, which can cost up to thousands of dollars per month. Object storages can get filled up by various application and user logs, if they are not cleaned on a regular interval (hopefully automatically). An in-memory cache might become expensive if not run efficiently.
All of these things have to be considered when choosing the right data storage solution.
Summary
As you can see, there are multiple technical pieces into any application development that are trade-offs and need to be considered from multiple angles. Architectural characteristics typically define these technical needs:
- The needed software architecture defines the services needed, which can affect platform selection.
- Programming language and ecosystem.
- Data storage requirements.
All these choices have to be weighed in with the cost of running them and developing with them. Some choices are faster in terms of development speed, others are cheaper to run.
All and all, these all affect time and cost, not really the scope, of the project triangle.
Personal experience
As I stated before, I have been doing this for over 15 years now and I have mostly focused on web development. I started as a freelancer while I was still at school, playing around with Adobe Photoshop and designing websites. From there I moved to actually building the websites for free for various gaming communities, after which I got my first paying customers and it just grew from there.
8 years ago I got my engineering degree in computer sciences and started my full time journey into becoming a full time software engineer. I am now building large scale web and mobile applications with big tech companies that have millions of users and are running hundreds of applications in cloud platforms.
I’ve also decided to shift my focus away from just development and architecture, into helping teams with the development process and coaching teams into becoming better with agility.
As I’ve gotten more experienced, some of the projects I’ve taken on on the freelancer side have become more complex. Complexity also means more time and more cost. Projects run for longer, but that's not an issue.
I will finish this post later by sharing case study of a project I worked on for over a year, where we started development from a web application prototype, to developing a mobile application with a back-end application on the cloud, with a application to control the data presented on the mobile application and how it all came together.
Case study: Cashm8 - A point-of-sale (POS) system for small businesses
I was hired to build a point-of-sale (POS) system for a small restaurant business in 2021. During our initial discussions the customer told me that they were not happy with the idea of paying a provisional percentage to a point-of-sale provider for every sale they did using their applications. It affected product pricing. They wanted an in-house solution where they could also select the payment terminal they wanted to use at their cash registers.
We agreed that the first step would be to build a web application prototype that would be integrated to a payment terminal using a two-way interactive communication protocol.
Once the concept was confirmed by the prototype, development would move to mobile application development, back-end service development, building a web application for users to control their data and building all of this on top of a cloud platform for speed, scalability and security.
Phase 1 - Prototype
This project started with the idea that an in-house POS system could remove unnecessary provisional costs per purchase from the client operating in the restaurant business.
To test this idea, we built a quick web application prototype that would be integrated with payment terminals from a specific vendor. This payment terminal would use a specific connection type for communicating with the application, that ran on the browser.
I chose React (frontend development library) and Next.js framework as the base for the application to enable rapid development om said prototype. I also chose Material UI as a user interface framework, as it offered already established React components to build the interface with. Otherwise the work would take too much time.
Still, building the prototype took 2-3 months. Most of the time was spent testing the payment terminal integration with the customer as they didn't have a test device yet and I had to send requests to a device that was at the other side of the county.
Once all was done, we deployed it to an on-premise server and it was used to run day-to-day business there. The prototype ended up being a production viable application, but not without issues or some missing functionality. We’ve been fixing issues as they come up, and we even hit a few problems running the application on the on-premise server.
Phase 2 - Mobile app development
During the summer of 2021 I spent 40 hours going through an online course to learn Flutter and Dart. Flutter is a hybrid development framework created by Google that enables cross-platform application development. This includes platforms such as Android, iOS, Window and Mac OS.
Looking up information on Flutter I became convinced of it’s performance benefits as a hybrid framework. Typically with these types of frameworks you lose performance. With React Native this performance loss happens when the programming language used needs to talk to the native language via a so called “bridge”.
Flutter, however, uses it’s own renderer, which means it controls every pixel that gets drawn on a screen. It also compiles to native code and there is no bridge in between to translate one language to another.
In any case, I learned Flutter during the course of the summer and started building the skeleton for a mobile application that would succeed the web application prototype.
Setting up on a cloud provider
There were also additional requirements to the project as it progressed. The customer had very little time to maintain the original back-end service themselves, so we agreed that I would take ownership and develop a new version that would contain a lot more business logic, while improving security.
This included, for example, serving different cash registers with their assigned payment terminals, adding authorization and even serving data to users who want to access their payments and data through a user interface. We of course had to build the application for that interface.
The original back-end was located on an on-premise server, but scalability was something I thought about from the start. So instead of using a single server, I opted to the serverless route.
Serverless is an architecture that offers very good scalability for the back-end, on a function basis. It is also very fast to get started with, as you don’t have to worry about servers and software that runs your applications.
This drove us towards cloud platforms. This decision was reinforced by the idea that to boost security, user data should be located in the cloud provider’s identity service. This offered extra layers of security and a separation of the login process from our services. Authentication would also be automatically handled by the services on the cloud platform.
Continuous integration
To continue developing the application at a good pace, I wanted to establish an approach for continuous integration and continuous delivery. Any changes I commit to the code repository gets deployed to servers immediately after all tests and builds are determined to be working.
While setting up the automation takes a bit of time in the beginning, it removes a huge amount of manual steps that you need to complete each time you want to deploy changes to any environment that runs your code. So in the long run it saves a lot of time and removes the possibility of manual mistakes.
While continuous delivery is an approach, it is also a mindset of keeping your code always in a releasable state. This offers faster feedback and good stability.
Putting it together
So now we had three things tied together:
- An application programming interface (API) that was built on top of serverless computing
- A mobile application that talked to that API
- A user interface to display and control the data for the people who ran the business
It takes a full stack engineer to juggle three different types of applications at the same time, but if you manage to split your work into small steps, you can deliver value faster and without breaking anything.
Release
It took over a year to build the second version of this system and release the mobile application. Without making all the features available, it would not have worked. You cannot have a point-of-sale system if you do not have features for entities such as payment terminals, products, cash registers, payments, users etc.
I released a build of the mobile application for installation to android devices every time I made a significant change in it, so I could receive feedback on the work. Later we released it on Google Play , and decided to not release it on iOS at this time.
We have now, at the time of writing, released nearly 50 versions of the application and support two different payment terminal vendors. We have also released the application on phone devices, and not just tablets.
The latest addition of features is the creation and processing of food orders for the kitchen. A separate application was built for receiving orders from the application, and making it possible to track their progress. The time from order to completion can be tracked, and any food allergies are noted on the order.
Development continues in an iterative way. Customer accounts are still locked and free registration is not possible. We are still testing it and slowly opening it to new customers.