Airo Global Software

Think Beyond Future !

enter image description here

In this ever-changing IT world, knowledge and skills in all the latest technologies are priceless. Because there is such a high demand for mobile apps among users, their development will not be slowing down anytime soon. Global mobile app revenues will increase by more than $365 billion in 2023, according to Statista. That's just the tip of the iceberg!

As the number of users in the Apple Store and Google Play Market grows at breakneck speed, more and more businesses want a piece of the action by launching the next game-changing product that will take the market by storm. Do you have a great idea for a mobile app for your company? But how do you know which technology to use?

In this blog, we will compare two widely used development technologies: Flutter and React Native. Continue reading to find out which is best for your company.

What is Flutter?

Flutter is an open-source UI development toolkit that has already assisted thousands of businesses in creating appealing and user-friendly products. This UI software toolkit, released by Google in 2017, was designed to help developers create highly interactive cross-platform mobile apps with a single codebase.

Flutter is made up of two main parts:

A Software Development Kit (SDK) is a collection of tools required for app development, such as ready-made widgets and testing APIs. A UI library is made up of reusable UI elements such as buttons, sliders, and so on. To begin developing mobile apps with Flutter, you must first learn how to code in Dart. It is a client-optimized programming language used to create customized user interfaces for various platforms. The best mobile app development company in Kerala like Airo Global Software will help your business to achieve success through Flutter app development.

Apps Built with Flutter

Flutter has been used to create a number of innovative mobile apps. And many of them made significant changes in marketing, finance, e-commerce, health and wellness, and other industries. So, here are a few examples: Google Ads is an online advertising platform that allows you to track and visualize the results of your advertising campaigns.

Alibaba is a worldwide wholesale mobile marketplace that allows smartphone users to shop online. Birch Finance is a mobile app that aims to help people manage their personal finances in a more resource-efficient manner.

Coach Yourself is a fun mobile app that allows users to practice meditation and track their progress.

Airo Global Software, one of the best mobile app development service providers in Kerala will help you to build a user-friendly mobile app for your business.

What is React Native?

Facebook created React Native, an open-source mobile framework, in 2017. This framework is fantastic because it allows you to create native and cross-platform apps for platforms other than iOS and Android, such as Apple tvOS, Microsoft Universal Windows Platform (UWP), and others.

However, React Native has a lot more to offer developers. And now, let's take a closer look at the main benefits of this framework:

React Native has a wide range of native modules written in Objective-C and Java that improve operational performance in video playback and image editing. Mobile application development company in Kerala will help you build a beautiful frame work with react native.

Apps Built with React Native

Because of its seamless code deployment and simple debugging process, Facebook, Tesla, Bloomberg, and other well-known brands chose React Native over other frameworks. However, these are not the only companies that use React Native to build mobile apps. Of course, there are others: is a food delivery service that allows users to order meals from nearby restaurants and cafes.

SoundCloud Pulse is a music streaming service for singers, producers, and music fans; Townske is a community of locals who share stories about their favourite spots and places with visitors, and Airbnb is a rental marketplace for travellers and homeowners to make their experiences more memorable and enjoyable.

Dart vs. JavaScript as a Programming Language

Dart is a programming language used by Flutter to create mobile apps. Dart is a client-optimized language created by Google that ensures fast compilation to ARM and 64 Machine Code.

Dart has the following advantages in mobile app development: Highly optimized and customized user interfaces for each platform (iOS and Android), Quick changes in sourcing and reloading code.

In the development process, an effective AOT (Ahead-of-Time) compilation strategy is used.

The React Native framework is built on JavaScript. Statista data show that nearly 67.8 percent of developers prefer this programming language for creating mobile apps.

JavaScript programming has a number of advantages, including a low learning curve and a large developer community; it operates on the client-server side, which means that data validation can be performed on the browser itself rather than sending it to the server and it operates on the client-server side, which means that data validation can be performed on the browser itself rather than sending it to the server.

Testing Support: Flutter vs React Native

Testing has always been an important part of developing excellent mobile apps. Without this process, we rarely know which bugs in the software system should be fixed.

So, which has better testing support: Flutter or React Native?

Let's compare the testing capabilities of these two technologies in-depth to find a clue.

First, we'll look at Flutter.

Flutter has three main testing categories for measuring the performance of your app:

  • Widget testing is used to test a variety of widgets such as text, screen layouts, and buttons.

  • Unit testing is used to determine the correctness of a single method, function, or class.

  • The goal of integration testing is to see if all of the widgets and services that have been tested work well together.

As an added bonus, Flutter includes well-written documentation with useful information about automated testing processes and the testing categories mentioned above.

But what about the testing capabilities of React Native?

"Knowledge is power," as the old adage goes. As a result, it's critical to identify all potential pitfalls before releasing the app to the public. And this is where testing comes into play.

Developers use JavaScript testing frameworks such as Jest to test snapshots in order to deliver a high-quality cross-platform app. Furthermore, React Native, like Flutter, has automated unit and integration testing. The main distinction between them is end-to-end testing (E2E). This testing method assists developers in determining how the app will perform from the standpoint of the user on a specific device. React Native allows testing with the E2E method on Android and iOS platforms, whereas Flutter's iOS version has yet to be released.

Performance: React Native vs Flutter

Flutter and React Native both guarantee smooth and seamless app performance. However, there are some distinctions between these technologies. And now let us untangle them!

Flutter performance provides 60 FMS or 120 FMS on devices capable of 120Hz. Another useful feature of this framework is the ability to specify the rendering time for each UI and GPU thread. However, it is not limited to this capability. Let's go over some of Flutter's other advantages and why you should use it to build your next app.

You can create animations and widgets in record time. Furthermore, the app created with this framework mimics the native components of each platform. And it's possible because of Material Design and Cupertino widgets, which ensure that all app components look and interact properly on both Android and iOS platforms.

As a result, the approaches to app performance used by React Native and Flutter differ. React Native includes a hot reload feature that displays changes in your code in real-time. Another advantage of this framework is that it is not restricted to a specific IDE and can be developed in any text editor.

Flutter Setup vs React Native Setup

Flutter and React Native have well-written documentation for iOS and Android software installations. However, there are some distinctions between them, which we will discuss below:

The React Native guide is intended for developers who have completed the necessary setup for the Android and iOS platforms.

Flutter has a flutter doctor feature that allows coders to ensure effective app installation and configuration; React Native uses Expo CLI and React Native CLI to set the development environment, and Flutter has a flutter doctor feature that allows coders to ensure effective app installation and configuration. The Flutter setup guide includes information on iOS, Android, and Integrated Development Environment setups.

Flutter and React Native UI Components and API Development

The native component is a must-have in the mobile-cross platform development process. But why is it so crucial? The answer is that your app will not feel native if it lacks a native component.

To communicate with UIs that should be rendered, React Native employs JavaScript bridges. Additionally, Objective-C APIs and Java APIs are required for rendering on iOS and Android, respectively.

In contrast, to React Native, Flutter does not rely on the platform's APIs. It has a library of widgets that help developers create interactive user interfaces, and all necessary plugins are housed in a single toolkit. Flutter also has a canvas function Object() { [native code] } that generates nearly identical user interfaces for each mobile platform. Instead, in React Native, your app UIs will look different on iOS and Android platforms.

Development Time: Flutter vs React Native

It goes without saying that fast cross-platform mobile development is a gold mine for any business owner. The more app users you have, the more benefits you will receive. A similar rule applies to the process of cross-platform mobile development. Which of these technologies will triumph in the battle of quick yet high-quality mobile app development?

So, let's get started!

There is only one disadvantage to using React Native in this situation. Plugins and other required components are stored on external servers. For example, if you want to build a routing feature in your app, you should use React Navigation as a plugin.

Recap: Which is Better for Mobile App Development: Flutter or React Native?

In conclusion, both Flutter and React Native are excellent choices for mobile app development. However, there are significant differences between them, such as time and accessibility. Because Flutter is Google's UI toolkit, all essential development components are centralized. However, we cannot say the same for React Native. The majority of third-party libraries are hosted on external servers. It may take some time to locate the necessary components for your app. However, the React Native community is larger than the Flutter community. It means that developers who know how to code in JavaScript are more easily found than those who know how to code in Dart. In this way, React Native outperforms Flutter. Additional factors, such as app complexity and development goals, can influence your decision on which of these technologies to use. And it's up to you whether to use Flutter or React Native as a framework. Get in touch with LITSLINK if you're looking for a reputable React Native development business or Flutter development services. Our software professionals will happily assist you in determining the most effective strategy to scale your company. If you have any concerns or questions about the aforementioned topic, please contact us. Please do not hesitate to get in touch with us. Your digital partner will be Airo Global Software.

E-mail id: [email protected] enter image description here

Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile:

PowerApps is primarily a mobile and web app development platform. It enables "citizen developers" to access capabilities that were previously only available to high-end development tools. Furthermore, PowerApps is generally simple to learn. You can use it to quickly take control of your destiny as long as you make the right structuring decisions. Follow this guide to avoid unpleasant surprises.

What does the Power Platform for PowerApps stand for?

Power BI, PowerApps, and Flow are components of the Power Platform. Microsoft has been promoting this as a whole more and more. These three services provide tools for managing our digital world, where data reigns supreme and serves as the foundation of all enterprise processes. The following are their applications:

  • Power BI can be used to display and analyze data.
  • PowerApps allows you to act on and modify data.
  • Flow allows you to automate data.

How to Create an App Using Microsoft PowerApps?

Starting with the data source is the simplest way to build a PowerApps app.

  1. In this example, we'll begin with a SharePoint list containing consulting interventions:

  2. Next, in the PowerApps menu, select the "Create an app" option:

  3. This will take us to the PowerApps Studio, where we will find a fully functional canvas app created by the system:

Remember that these are only the default options. They conceal a much broader set of available options, configurations, and architectural options provided by PowerApps.

Step 1: Choose a PowerApps Environment

Within PowerApps, you can work with four different tools or environments, each with its own set of capabilities and roles.

  • Website for PowerApps

You'll start your PowerApps service journey on the website. This is where you can create new apps and manage existing ones.

  • PowerApps Studio

Here you will be able to design and adapt apps to your specific business needs!

  • PowerApps Mobile App

This useful mobile app is available for both smartphones (iOS and Android) and tablets (Windows 10). Regardless of the platform, the app provides a runtime environment in which you can execute all of your PowerApps apps. This includes both those that were shared with you and those that you designed and coded yourself.

  • PowerApps Admin Center

You can create and manage environments, DLP (Data Loss Prevention) strategies, and user roles using A list of user licences is available in the tenant.

Step 2: Choose a PowerApps Application Type

PowerApps allows you to create two types of apps:

  • Apps for Canvas
  • Model-driven applications

Canvas apps allow you to organize your interface freely and easily by positioning controls and fields in a "pixel-perfect" user experience. The main goal here is to apply your business knowledge and creativity to the design of the app. Canvas apps are designed to be lightweight or even disposable apps that can be designed and used in a matter of minutes.

Model-driven apps are built on top of the Common Data Services, which are used to help developers quickly create forms, processes, and business rules. They concentrate on heavier apps that are intended to be used frequently (multiple hours at a time).

There is also a "third" type of app that is technically a version of Canvas: SharePoint lists customized forms. PowerApps can be used to customize the standard SharePoint form from a SharePoint list. After selecting the "customize forms" menu, you will gain access to a PowerApps component called "SharePointIntegration."

This control is in charge of transferring user actions between PowerApps and SharePoint. It adds properties such as "new," "OnSave," and "OnEdit" that allow the app to respond when a user clicks or taps the "New" button, taps an item, or taps the "Edit All" button.

Step 3: Determine Your Storage Needs

Power Platforms, and more particularly PowerApps, are desired in a world in which information is king and the basis of any business process. Thus, when it comes to creating an app, selecting the right data sources is critical.

SharePoint lists and Excel spreadsheets are two of the most commonly used data sources, but there are over 200 data connectors available. PowerApps and Flow and Logic apps share connectors (the Azure service on top of which Flow is built). One of the platform's greatest strengths is the availability of connectors to the Microsoft world: Office 365, SQL Server, Azure, and so on, as well as connectors to external data sources such as Salesforce, Dropbox, and Google Drive.

A connector in PowerApps can provide data tables, actions, or both. Here's an example of how to use a data source to a "Lessons" table in PowerApps: Be aware that the data sources you choose will have an impact on the licences required to create and run your app. If you select or require a Premium source (such as Salesforce or Common Data Service), you will require a PowerApps P1 or P2 licence.

Step 4:Secure Your App to an Online or On-Premises Data Citation

PowerApps was built in the cloud and can connect to cloud data sources natively. However, it can also connect to on-premises data sources. In order for this to happen, you must set up an on-premises data gateway. This gateway is shared by several cloud apps, including the entire Power Platform (Power BI, Flow, and PowerApps), Azure Analysis Services, and Azure Logic Apps.

At the time of writing, the gateway supported the following data sources:

  • SharePoint
  • Oracle
  • SQL Server
  • Filesystem
  • Informix

Be aware that using on-premises data sources will affect the licences required to create and run your app. If you select or require a local data source, you will require a PowerApps P1 or P2 licence. Let's hope that these elements will help you create better PowerApps to meet your business needs. If you have any questions or concerns, please contact Airo Global Software through the email given below.

E-mail id: [email protected]

Are you thinking about creating a new app? Well, one thing is certain: you are not alone. Just stop there for the 5 minutes it will take you to read this blog before you start explaining how useful it will be. There are currently 2.2 million apps available on the Apple App Store and 2.7 million on Google Play. Furthermore, according to TechCrunch, the number of live apps on the Apple App Store will reach 5 million by 2020. You can probably guess where this is going. If you're thinking, "Hey, that's a lot of apps compared to what people actually use!" you're correct.

According to App Annie's research from last year, despite an increase in time spent using mobile applications, users only access an average of 30 apps per day, with only 9 of them launched on a daily basis. Those figures demonstrate how difficult it is to gain a competitive advantage and stand out among millions. So, who in their right mind would want to create yet another app? I'll explain who and how. Someone who understands how to create the next big hit app that people will actually use. Someone who does not stop with a brilliant idea for a user-friendly mobile app development company in Kerala, but instead focuses on stellar execution.

What exactly does a user-friendly app imply?

User-friendly means that the app is intuitive, easy to use, and simple for the customer and that the customer can rely on the product. It is simple to get started with the app and understand how to use it; high complexity is not beneficial to the user. Reliability is essential because an app cannot assist the user if it contains bugs and does not function properly. If you want a better app, go to the best mobile app development in Kerala.

User experience (UX) and user interface (UI) are also important (UI). UX denotes that the app was created with the customer's needs and expectations in mind. UI denotes that the app's interface is well-customized and simple to understand for the intended audience. So, how do you make your app "user-friendly"? Just keep in mind that it is all about the user, so keep it simple, solid, and useful before you begin developing!

How do create app user will love?

So, how do you create an app that users will enjoy? It's difficult to say because there are an infinite number of groups you can target, each with its own set of needs and expectations. You should hire the best mobile app development company in Kerala. To assist you, we have compiled a list of ten tips that will be extremely useful in developing a user-friendly mobile app!

Here are 10 fantastic tips for creating user-friendly mobile apps:

  • Make the app useful!

This is an important step in Kerala's mobile app development. An app must, first and foremost, be useful to the user in some way, such as saving them time, money, or making their life easier in general. Incorporate that user value into your elevator pitch as a good place to start. Is your company truly addressing a pressing issue for the public? Try to express it in a single convincing sentence. Try it on your friends, family, random people, and, most importantly, people in your target demographic. Inquire if they believe what your company has to offer makes sense.

  • Understand your users

This may seem obvious, but we see it far too often overlooked by app developers due to a lack of time and impatience: you must get people to test your app before it goes live. These cannot be people who were involved in the design or development of your product in any way. What will you be putting to the test? How they use your mobile app, whether it is intuitive enough and does not frustrate them. The mobile app development process in Kerala is one method for testing and gathering feedback.

  • Make sure onboarding is easy

Apps that require users to register in the first step are no longer available. Forcing people to go through this stage results in extremely high bounce rates. Remove any barriers that may prevent people from using the app by inquiring about their personal or credit card information before they begin using it.

If any of these things are required for your application, that's fine, but make sure users already like your app before asking them to commit and trust you.

For the best mobile app development services in Kerala, you should search for the best mobile app development company.

  • Use best practices of app development

With so many applications available and so few truly successful ones, it's wise to follow in the footsteps of those who have already achieved success. This does not have to mean imitating anyone; it simply means not repeating the mistakes of so many before you.

This is especially true in the case of mobile app design in Kerala. We all enjoy letting our imaginations and creativity run wild, but when it comes to apps, the design must be functional. This means that experimenting outside of a well-tested framework is rarely a good idea and can lead you and your business astray. Always hire a mobile-savvy designer and become acquainted with popular online guidelines such as Google's Material Design.

  • Avoid redirects

A good app should include everything a user requires to navigate it and solve his problem. As a result, linking or redirecting to external pages from your app is a bad idea.

If you can't include everything in your app, remember that giving the user fewer options is always preferable. Instead of providing several low-quality solutions, focus on perfecting your product's key functionality.

  • Design user touchpoints

Consider specific scenarios in which the user may want to use your app and plan accordingly. Push notifications are a great tool to experiment with from a technical standpoint.

People have mixed feelings about them, but this is only because many apps overuse or misuse this mechanism. However, when used correctly, push notifications will entice people to return to the product at precisely the time when they are most in need of it.

  • Integrate when possible

This can be summed up in a single phrase: "don't reinvent the wheel." If you require a payment system, a chatbot, or a file-sharing feature, use tools that people are already familiar with and that you can integrate into your product at a low cost.

By collaborating with high-quality systems that people already like, you are making it easier for them and improving your product

  • Make pretty things people want

While the primary function of design is to provide a good user experience, making your product look good should not be overlooked. When you launch your app through the Apple Store or Google Play, this is often tested: slick-looking apps tend to get more downloads.

People prefer to look at pretty things, so investing enough time and resources in great design will pay off. This is true for any industry, but it is especially true for "cool" apps related to entertainment, social networking, or trends.

  • Create a safe environment

With so many apps available, it's not surprising that we're hearing more and more about user data breaches. If you need users' credit card information, use reputable payment service providers like Stripe or Braintree.

If you are unsure about the security of your app, it is often safer to integrate a Facebook or Google login into your app because you are outsourcing your users' security to well-protected products. Users appreciate this practice because it eliminates the need for them to re-register and instead allows them to log in using their social media profile.

  • Grow your friendly app by listening to your users

As you are aware, technological progress is accelerating at an exponential rate. New operating systems open up new avenues for mobile apps to avoid previously infamous errors. Because smartphone screen sizes are constantly changing, you may need to adjust the layout of your product. User behaviour changes as well, which means that what worked perfectly yesterday may be extremely annoying to your users next month.

Continue to read and respond to your users' comments, encourage them to provide feedback, and incorporate their suggestions into the next version of your app. If you need mobile application services in Kerala you should trust Airo Global Software.

E-mail id: [email protected]

enter image description here

Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile:

You're not going to change my mind; I've been lying, err, doing estimations for over 15 years, and I've lied for the majority of them. And if I were a betting man, I'd wager a month's salary that you, too, have been lying. Either to your manager when they request your best estimates for a specific task, or to yourself if you believe what you're saying is correct. There is only one thing that has helped me come to terms with my estimations and turn them into something somewhat trustworthy and somewhat accurate: assumptions.

And today I'd like to discuss assumptions.

What exactly are assumptions?

Every time we estimate something, we run the risk of discovering unknowns along the way. For example, while estimating the time it will take to develop the UI code for a new feature, you don't know if the back-end will be ready to be integrated and tested alongside your code. Can you complete the UI without the back-end? That is an unknown; you can't be certain that what you do will work with the final version of the back-end until you have access to and use the real back-end.

How can you provide an estimate if you don't know what will happen with the back-end code in the future? You could contact that team and inquire about their timeline. You can then adjust your own timeline based on that. But what if your unknown is the result of an external dependency? What if you're in the process of estimating the development of a completely new project to be deployed in Azure? You can try to estimate the time the development process will take and use that to provide an idea of the project's end date. However, you are unsure whether your client will have the credentials ready for you by the start date. How can you ensure that they do? What will happen if they don't? Suddenly, your estimated end-date no longer holds true. Were you telling the truth?

That's the issue, the real issue with estimates:

you have no control over what happens around your project and how real-life will affect it. And if you try to estimate based on those conditions, you'll almost certainly end up lying unintentionally.

Every unknown increases the possibility of error in your estimate. The larger the project and the further in the future you estimate, the greater the error in your final number. How can you give an estimate that isn't completely erroneous?

Assumptions are the correct answer.

Making Assumptions in Your Estimates

Every time you discover an unknown in your future, it represents a possible branching of your current timeline.

Have you ever heard of the experiment known as Schrödinger's Cat?

Essentially, the thought experiment states that you will never know the outcome unless you look inside the box and crush all potential futures (in this case, all two of them) into a single possibility.

Assumptions are analogous to the opening of a box. Every assumption condenses all possible futures around it into a single one and eliminates the unknown:

  • "By the time the project initiates, all Azure certificates will be ready."
  • "By the time we begin operating on the UI, the back-end will be glad."
  • "The log file's dimensions will never overextend the 200Mb line."
  • "The API will be obtainable 99.9% of the moment."

This way, your projections are based on a "real" future. You've eliminated the unknown from your path forward.

You've figured it out!

Your estimates will change from "I'll be done in two weeks" to "I'll be done in two weeks as long as the following assumptions hold true." Your final number is now entirely dependent on those estimates, and if one of them is not met, your estimates are no longer valid. That's also fantastic. You have no control over the future, nor do you have any control over external entities. As a result, the only reasonable course of action is to assume what they will do and plan accordingly. You can't be blamed if they don't behave as you expected, and you can't be expected to forecast every possible future scenario. However, you could provide estimates for the most common ones, sort of like having a plan A, B, and possibly even C. But that's all there is to it; the list of potential problems is infinite, and you can't plan for every possible combination of them.

Just make sure that for each estimate you deliver, you write down your assumptions and include them as part of the estimate. That way, you're sending out a contract that says, "This is my estimate, and it only applies as long as my assumptions are correct; otherwise, the estimate must be reviewed and adjusted accordingly."

That is how a software estimate is made.

All estimates rely on assumptions. They assist you in providing reliable numbers while also establishing appropriate expectations between you and your stakeholders. As long as they agree with your assumptions, you're all on the same page when it comes to each other's expectations. What are your thoughts? Have you ever made an assumption? Are you opposed to them? If you have any about the above topic. Don’t hesitate to contact us. Airo Global Software will be your digital partner.

E-mail id: [email protected]

enter image description here

Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile:

This question can also be expressed as "Should I learn Java, Python, or JavaScript?"

To be completely honest, I was inspired to write this blog after reading Eric Von Reinhard's take on the same question in his article "The Best Programming Language to Learn in 2022? — Google Lead Developer Explains." In fact, I decided to write about it because I have a very different viewpoint on the subject, so please excuse the inspired title.

So, which one is it?

"No specific one," I say.

It makes no difference whether you start with C++, Java, Python, Javascript, or any other language. Learning a new language does not take long, and it should not be your top priority.

Programming languages are a means to an end (there I said it again!) and in practice, we tend to switch between them to get our work done.

I must admit that we have developed different "kinds" of programming languages in terms of how they are used over time. Some languages are used solely for markups, such as HTML or XML, while others are used solely for scriptings, such as shell scripts or bat scripts, and so on. Some are functional in nature, while others are not, and so on.

When switching from one "kind" to another, there may be some learning involved. Having a fundamental understanding of these "kinds" will significantly reduce the barrier to learning a new language.

Wait… So, what are we going to concentrate on?

The ability to address any given problem statement is, in my opinion, the most important skill to work on.

Can you create a web application if it's supposed to be one?

Can you improve the performance of your Android app?

You have a problem that a trained neural network could potentially solve — can you do it all?

Even if you've "never" done anything like it before! And whatever programming language is required to complete the task!

In the end, it'd all feel the same, so focus on learning new technologies, delving deeper into concepts that appear magical, and, at first, trying to explore many different genres until it all starts to look the same. Finally, choose something you're passionate about and dive deep!

Okay, but some specific suggestions would have been fantastic!

I have various recommendations for programmers at various stages of their careers.

If you are just starting to learn to code, I would recommend choosing a technology that interests you — it could be web, mobile (Android / iOS), game development, other app development, training ML models, building desktop apps, and so on.

The trick is to pick a technology and learn the relevant languages. If possible, learn by creating random software and having a good time doing it. If at all possible, continue to question how the various forms of magic you see are actually working.

Eventually, begin delving into more fundamental concepts abstracted by the libraries you're using, such as concurrency or multithreading, databases, graphics rendering, image processing, networking, and so on.

A programme written in any language is either directly compiled to assembly instructions or to intermediate byte-codes, which are then compiled to assembly instructions for the hardware to execute. If you accept this fact, the syntaxes of the various languages will begin to resemble one another.

A specific requirement, such as "increase every array value by one," can be handled in a variety of ways:

In Python:

y = [i + 1 for i in x]
## or
for i in range(0, len(x)):
 x[i] = x[i] + 1

In JavaScript:

for (var i = 0; i < x.length; ++i) x[i]++;
// Or
var y = => ++val);
// Or
var y = Array.from(x, val => ++val);

In Go:

for i:= range x {

All of these more or less compiles :

increment(int*, int):
 cmp     w1, 0
 ble     .L1
 mov     x2, x0
 add     x1, x0, w1, sxtw 2
 ldr     w0, [x2]
 add     w0, w0, 1
 str     w0, [x2], 4
 cmp     x2, x1
 bne     .L3

What's more interesting about this set of examples is that some of them result in array copy while others do not — and I'd recommend focusing on learning more about those types of issues and their impact on the programme.

If you are experienced and proficient in certain programming languages but feel you are missing out, I would still advise you to take a step back and consider the types of problem statements that excite you. Then consider what new means to an end you need to learn.

But it was so much fun that the time spent learning didn't seem like a chore. I'd suggest looking for such directions and starting to learn whatever it takes. If you have any doubt about the above topic. Don’t hesitate to contact us. Airo Global Software will be your digital partner.

E-mail id: [email protected]

enter image description here Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile:

On StackOverflow, the question "Why Spring is faster than Vert. x?" in its various variations is asked once a month on average. After all, Spring is still by far the most popular JVM framework, and many businesses rely on it. However, the Spring Framework is not well-known for its performance. Vert. x, on the other hand, is regarded as one of the best JVM frameworks. As a result, Vert.x is expected to outperform Spring in any benchmark. That, however, is not the case.

In this blog, I'd like to discuss the various causes of those counterintuitive results, as well as offer some suggestions for how to improve your benchmarking strategy.

To begin, what do we mean when we say a framework or language is "fast"? When it comes to web services, we don't talk about response time, also known as request latency. What we usually mean is a different metric known as throughput. Latency refers to the amount of time it takes to respond to a single request. Throughput refers to how many requests a server can handle in a given amount of time. Typically, within a second.

Let's look at where developers get the idea that Vert. x should be faster than Spring. A popular benchmark for web frameworks powered by TechEmpowered attempts to measure the throughput of various languages, runtimes, and frameworks using a few scenarios. Typically, the Vert.x framework performs admirably in these tests.

In the 20th round, for example, Vert.x is ranked 10th with 572K requests per second, while Spring is ranked 219th with 102K requests per second. This is truly impressive.

However, replicating those impressive results can be difficult at times, hence the title's question.

Let's try to figure out what the main flaws are with the benchmarking strategy.

When I say Spring, I mean the Spring Framework, not Spring WebFlux / Project Reactor, which works in a different way. In addition, I'll assume that the Spring application is running in a Tomcat container.

Vert.x is I/O focused

The Vert. x framework's ingenuity recognized early on that the bottleneck of most real-world applications is waiting for I/O. That is, it makes no difference how well your application is written, how clever the JIT optimizations are, or how cutting-edge the JVM GC is. The majority of the time, your application will be waiting for a response from the database or from a service written in Python or PHP 10 years ago.

Vert. x addresses this issue by placing all I/O work in a queue. Because adding a new task to a queue is not a particularly time-consuming operation, Vert. x can handle hundreds of thousands of them per second.

Of course, this is a very simplified explanation. There are multiple queues, context switches, reactive drivers, and a slew of other interesting features that I won't go into detail about. What I do want you to keep in mind is that Vert. x is designed for I/O.

Let's take a look at how Vert.x performance is typically measured:

app.get("/json").handler(ctx -> {     
   ctx.response().end("Hello, World!");

Let's compare the preceding example to the code from the Vert.x benchmark, which still performs quite well, with a throughput of 4M requests per second, but not as well as some other languages and frameworks:

app.get("/json").handler(ctx -> {     
       .putHeader(HttpHeaders.SERVER, SERVER)
       .putHeader(HttpHeaders.DATE, date)
       .putHeader(HttpHeaders.CONTENT_TYPE, "application/json")
       .end(Json.encodeToBuffer(new Message("Hello, World!")));

Can you spot the distinction? There is almost no I/O in the benchmark that most developers run. There are some because receiving a request and writing a response is still an I/O operation, but not much when compared to interacting with a database or a filesystem.

As a result, the benefit of using a reactive framework like Vert. x is diminished by that test.

Write a benchmark application that does some I/O work, such as writing to a database or reading from a remote service, if you want to see real benefits from a reactive framework like Vert. x.

Benchmarking with Low Concurrency

Concurrency is handled by Spring Framework by allocating a thread pool dedicated to serve incoming requests. This is also referred to as the "thread per request" model. When you run out of threads, your Spring application's throughput begins to suffer.

ab -c 100 http://localhost:8080/

To bombard our service with requests, we use a tool called Apache HTTP Benchmark. The -c flag instructs the server to run 100 concurrent requests at the same time.

You run this test on two services, one written in Spring and one in Vert.x, and there is no difference in performance. Why is this the case?

Unlike Vert.x, Spring Framework does not directly control the number of threads it employs. Instead, the container, in our case, Tomcat, determines the number of threads. Tomcat's default setting for the maximum number of threads is 200. This means that there shouldn't be much of a difference between Spring and Vert. x applications until you have at least 200 concurrent requests. Simply put, you're not emphasizing your application enough.

Set the number of concurrent requests higher than the maximum size of your thread pool if you want to stress your Spring application.

Benchmarking on the Same Machine

Let us return to how Vert. x works. I've already mentioned that Vert. x improves performance by queuing all incoming requests. When a response is received, it is also added to the same queue. There are only a few threads, known as EventLoop threads, that are busy processing that queue. The greater the number of requests, the busier the EventLoop threads become and the more CPU they consume.

What now happens when you run a benchmark on your computer? As an example:

ab -c 1000 http://localhost:8080/

The following is what will happen next. The benchmark tool will attempt to generate as many requests as possible while utilizing all of your machine's CPU resources. The Vert. x service will attempt to serve all of those requests while also attempting to use all of the available resources.

To maximize the performance of the Vert. x application during the benchmark, run it on a separate machine that does not share CPU with the benchmark machines.

This brings us to the following point.

  • The Spring Framework's Performance Is Excellent
  • I've been a huge fan of Vert. x for at least the last 5 years. But first, consider the throughput of the Spring application in the earlier-mentioned benchmarks.
  • Plaintext: 28K
  • JSON serialization: 20K
  • Single query: 14K
  • Fortunes: 6K
  • Multiple querie s: 1,8K
  • Data updates: 0,8K


As software engineers, we enjoy comparing the performance of our favorite programming language or framework to that of others.

It's also critical to use objective metrics when doing so. Measuring service throughput with a benchmark is a good place to start, but it must be done correctly.

Check to see if the test you're running is CPU or I/O bound, or if it has another bottleneck.

Also, run your benchmarks on a separate machine than the one that runs your application code. Otherwise, you might be disappointed with the results.

Finally, I've witnessed companies encountering throughput bottlenecks in their language or framework, and I've even assisted in the resolution of some of them. However, there are many successful businesses out there that may not require all of that throughput, and you may be working for one of them. Creating a good benchmark is difficult and time-consuming. Consider whether that is the most pressing issue you should be addressing. If you have any doubt about the above topic. Don’t hesitate to contact us. Airo Global Software will be your digital partner.

E-mail id: [email protected]

enter image description here

Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile:

I burned myself out in my first six months as a tech lead. It had always been a goal of mine to be a tech lead, but after accomplishing that goal, I spent some time regretting my decision.

I was putting in a lot more hours as a tech lead during the day and catching up on my ticket work at night. I wasn't sure what the role entailed, so I just did what I saw the previous tech lead do. I was totally unprepared for it.

That was five years ago, and in that time, I've served as a tech lead and engineering manager for three teams. With time, the experience became easier, and the expectations of a tech lead became clearer. There's no reason for new tech leaders to figure it all out on their own — here's my advice on how to be a better tech leader.

First, what exactly is a Tech Lead?

At different companies, the term "tech lead" can mean slightly different things. A team lead is a type of tech lead in which you are responsible for the day-to-day operations and delivery of a quality product from a development team but have no hiring/firing power.

The second type of tech lead is an engineering manager, in which you are a manager with hiring and firing authority as well as people management responsibilities such as regular performance reviews. These can sometimes be combined into a single role. I've also seen it as two distinct roles.

The third type of tech lead is the lead engineer, who is a senior member of the team who occasionally leads smaller projects but primarily in a technical capacity such as doing code reviews, developing a data model for a new project, or architecting the project.

This blog will concentrate on the first type of tech lead, also known as the team lead. Now that that's out of the way, here are some principles to guide your tech leadership.

  • Make Yourself a Shield for Your Team

Handle anything that may disrupt the team, such as responding to Slack users who may have questions about your team or upcoming projects, collaborating with internal support teams on escalated issues, and representing the team's interests in meetings as needed.

This saves the team's time by preventing other people (such as upper management) from making requests directly to your team's developers. This can cause them to become distracted and divert their attention away from important planned work. So your goal is to determine if this is occurring and to communicate clearly to those individuals that such requests must first go through the proper channels.

A lot of this work is really just triaging the issue or question at hand and directing to the appropriate resource.

  • Maintaining Knowledge of What Other Teams Are Working On

Meetings are one of those necessary evils that we like to complain about, but every now and then, some of those meetings contain useful information. In an ideal world, I'd get a five-minute recap of every meeting in which I'm not actively participating, but that's not going to happen.

They provide an opportunity to learn about what's going on in other teams, whether they're teams you work directly with or teams that are more distant from the work you're doing. You may overhear that a team is developing a new service, which gives you the opportunity to say, "Hey! My team is working on a similar project. Let's have a discussion about it!" Every now and then, that interaction saves you a quarter's worth of money.

  • Discussions with the team should be facilitated.

Have you ever been in a team meeting where most of the time is spent in silence, waiting for someone to speak up (especially in a remote setting)? "Should we explore this library?" someone might ask, to which crickets might respond. People are sometimes unsure of how to respond and are afraid of appearing stupid. It is your responsibility as a tech lead to facilitate the discussion with the team so that the team can own — and make — the decision. Assist people in gathering as much information as possible to aid in decision-making. You can request clarification or ask dumb questions.

Half of the time, other people have the same questions but are too shy to ask them because they don't want to be the one who asks a stupid question. You may need to rely on your developers in the early stages of your role. You won't know everything about the codebase, but you must be able to answer questions like "Is feature X possible?" We have the information in system Z." If you've been on the team for a while, you'll be aware of who has access to which parts of the codebase. They'll be the ones to point you in the right direction if you're new.

If you don't have enough information to make a decision, say so and let whoever needs the decision know when you'll be able to make it.

  • Maintain high standards and set a good example.

Don't waste time pointing out stylistic differences. Add a linter and/or a formatter to the project and direct the discussion to the tool. It's one thing for another developer to leave 15 nitpicky comments; it's quite another to ask if we should add a new linter rule.

Where possible, require code changes to be accompanied by unit tests, and track unit test coverage. 70 percent coverage is sufficient for me across the entire project.

Some scenarios are more difficult to cover with unit tests, but these are the exceptions. Unit tests are required for any business logic or unusually specific behaviour; this is the only way to prevent other developers from accidentally breaking code by removing code that they believe is no longer required.

  • Concentrate on the Big Picture

You have to pick your battles, and there are some minor decisions that aren't worth your time. I'd bite my tongue and move on if a developer implemented something in a procedural pattern when you wanted it to be more object-oriented.

These kinds of decisions don't really matter in the long run. What matters is that your team does not push broken changes into production. A few procedural snippets here and there will not derail production.

That is not to say that you should not provide feedback. Instead of the tech lead's personal preferences, it's sometimes more helpful to ask questions to ensure that their proposed solution meets the needs of the problem, such as "Did you consider X or Y?"

You should not instruct your developers on how to carry out their change (unless they are specifically asking for that feedback). If you do this too frequently, they may begin to feel more like code monkeys simply doing what the tech lead says.

By asking the right questions, you can sometimes coach them into a different solution, allowing them to own the idea and implementation more than you saying, "Build it this way." Sometimes you can't because their solution also meets all of the needs equally, and choosing between the two approaches is a matter of personal preference. In that case, don't sweat the small stuff and get on with your life.


As a developer, you won't often need these skills, but they will come in handy. As a result, new tech leaders typically face a learning curve as they figure out the people’s side of leading a team while balancing their own responsibilities. So, if you want to be a better tech leader in 2022, pay attention to the following:

  • Being a bulwark for your team Keeping track of what other teams are working on Facilitating discussions within your team
  • Maintain high standards and set a good example.
  • Consider the big picture.

If you have any questions about the above topic, please do not hesitate to contact us. Your digital partner will be Airo Global Software.

E-mail id: [email protected]

enter image description here

Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile:

Details on the new features and packages in CRA 5

The Creating React App (CRA) method is a fast way to scaffold a React project. The command npx create-react-app project name> can easily generate it. We can get the most recent packages and the execution environment for a React project with a single command. It is both convenient and efficient.CRA 5 was released on Dec 14, 2021. It has the following new features and new packages:

  • Support for Node 10 and 12 has been discontinued.
  • Enhancements to the Fast Refresh.
  • Package manager detection has been improved.
  • To improve compatibility with other tools, all dependencies were unpinned.
  • Tailwind support has begun.
  • Webpack 5, Jest 27, ESLint 8, and PostCSS 8 have been installed.

Let’s go through these details.

Install create new React App

create-react-app is a global command-line utility that allows you to create new React projects. The created projects use the most recent version of react-scripts, which is currently 5.0.0. CRA 5 no longer supports Node 10 and 12, and it now requires Node 14 or higher. Create-react-app will fail if the node version does not meet the requirement.

% nvm use 12
 Now using node v12.22.7 (npm v6.14.15)
 % node --version
 % npx create-react-app my-app
 npx: installed 67 in 3.482s
 You are running Node 12.22.7.
 Creating React App requires Node 14 or higher.
 Please update your version of Node.

The installation is complete after changing the node version to 17.

% nvm use 17
 Now using node v17.1.0 (npm v8.1.2)
 % node --version
 % npx create-react-app my-app
 Creating a new React app in /Users/jenniferfu/funStuff/my-app.
 Installing packages. This might take a couple of minutes.
 Installing react, react-dom, and react-scripts with cra-template...
 added 1375 packages in the 30s
 163 packages are looking for funding
  run `npm fund` for details
 Initialized a git repository.
 Installing template dependencies using npm...
 added 33 packages in 4s
 163 packages are looking for funding
  run `npm fund` for details
 Removing template package using npm...
 removed 1 package, and audited 1408 packages in 2s
 163 packages are looking for funding
  run `npm fund` for details
 6 moderate severity vulnerabilities
 To address all issues (including breaking changes), run:
  npm audit fix --force
 Run `npm audit` for details.
 Created git commit.
 Success! Created my-app at /Users/jenniferfu/funStuff/my-app
 Inside that directory, you can run several commands:
  npm start
    Starts the development server.
  npm run build
    Bundles the app into static files for production.
  npm test
    Starts the test runner.
  npm run eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!
 We suggest that you begin by typing:
  cd my-app
  npm start

Improve Existing Create React App with react-scripts, which includes scripts and configuration. The Create React App project can be updated by upgrading react-scripts to a specific version. To upgrade to the latest version, the official documentation suggests running the following command:

 npm, install --save react-scripts@latest

By issuing this command, we smoothly upgrade react-scripts from version 4.0.3 to version 5.0.0.

The following are the differences between package.json files:

We have upgraded the react-scripts version. Here are the distinctions between the CRA 4 package. json as well as the CRA 5 package json.

The differences appear to be minor. We can manually update the testing-library and web-vitals versions to match the versions in CRA 5.

TypeScript Version Upgrade

If you're using TypeScript, you can start a new project with the following command:

npx create-react-app --template typescript <project name>

The JavaScript CRA package differs in the following ways. json, as well as the TypeScript CRA package json.

TypeScript has been updated from version 4.1 to version 4.5 from CRA 4 to CRA 5.

Enhancements to the Fast Refresh

Fast refresh has been improved for the Hot Module Replacement (HMR) runtime, with the bailout behaviour described below:

  • If fast refresh is not enabled, reload the page manually.
  • If fast refresh is enabled and there are updated modules, rely on fast refresh to be error-resistant and skip the forced reload.
  • If fast refresh is enabled, no modules have been updated, and the status of the hot update is aborted or failed, perform a forced reload.

Improved Detection of Package Managers

npx create-react-app in CRA 4 If the yarn is installed, my-app will use it to install dependencies. Alternatively, a flag can be set to use npm:

npx create-react-app my-app --use-npm

In CRA 5, this behaviour has been modified. If the env variable npm config user agent is set to 'yarn,' the package manager will be yarn:

function isUsingYarn() {
  return (process.env.npm_config_user_agent || '').indexOf('yarn') === 0;

Otherwise, it is determined by how the command is executed:

yarn create-react-app my-app // use yarn
npm init react-app my-app // use npm
npx create-react-app my-app // use npm

Dependencies that aren't pinned

In CRA 5, the following react-scripts can be found in the installed package-lock.json:

"react-scripts": {
  "version": "5.0.0",
  "resolved": "",
  "integrity": "sha512-3i0L2CyIlROz7mxETEdfif6Sfhh9Lfpzi10CtcGs1emDQStmZfWjJbAIMtRD0opVUjQuFWqHZyRZ9PPzKCFxWg==",
  "requires": {
    "@babel/core": "^7.16.0",
    "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3",
    "@svgr/webpack": "^5.5.0",
    "babel-jest": "^27.4.2",
    "babel-loader": "^8.2.3",
    "babel-plugin-named-asset-import": "^0.3.8",
    "babel-preset-react-app": "^10.0.1",
    "bfj": "^7.0.2",
    "browserslist": "^4.18.1",
    "camelcase": "^6.2.1",
    "case-sensitive-paths-webpack-plugin": "^2.4.0",
    "css-loader": "^6.5.1",
    "css-minimizer-webpack-plugin": "^3.2.0",
    "dotenv": "^10.0.0",
    "dotenv-expand": "^5.1.0",
    "eslint": "^8.3.0",
    "eslint-config-react-app": "^7.0.0",
    "eslint-webpack-plugin": "^3.1.1",
    "file-loader": "^6.2.0",
    "fs-extra": "^10.0.0",
    "fsevents": "^2.3.2",
    "html-webpack-plugin": "^5.5.0",
    "identity-obj-proxy": "^3.0.0",
    "jest": "^27.4.3",
    "jest-resolve": "^27.4.2",
    "jest-watch-typeahead": "^1.0.0",
    "mini-css-extract-plugin": "^2.4.5",
    "postcss": "^8.4.4",
    "postcss-flexbugs-fixes": "^5.0.2",
    "postcss-loader": "^6.2.1",
    "postcss-normalize": "^10.0.1",
    "postcss-preset-env": "^7.0.1",
    "prompts": "^2.4.2",
    "react-app-polyfill": "^3.0.0",
    "react-dev-utils": "^12.0.0",
    "react-refresh": "^0.11.0",
    "resolve": "^1.20.0",
    "resolve-url-loader": "^4.0.0",
    "sass-loader": "^12.3.0",
    "semver": "^7.3.5",
    "source-map-loader": "^3.0.0",
    "style-loader": "^3.3.1",
    "tailwindcss": "^3.0.2",
    "terser-webpack-plugin": "^5.2.5",
    "webpack": "^5.64.4",
    "webpack-dev-server": "^4.6.0",
    "webpack-manifest-plugin": "^4.0.2",
    "workbox-webpack-plugin": "^6.4.1"

All versions rely on the caret dependencies, which means that these packages will use the most recent minor version.

Many packages in CRA 4's react-scripts, for example, pin to the exact versions.

CRA 5 removes the babel-loader, which was causing problems when using CRA with Storybook. Furthermore, CRA 5 unpins all dependencies for improved compatibility with other tools.

What else do you discover?

  • tailwindcss (^3.0.2) is the latest

    • Packages that are updated: webpack: (^5.64.4), jest: (^27.4.3), eslint: (^8.3.0), and postcss: (^8.4.4).

Tailwind Support

Tailwind is a CSS framework that includes classes such as flex, text-5xl, font-bold, text-green-500, and others. These classes can be combined to create any design, right in the markup.

Tailwind searches for class names in HTML files, JavaScript components, and other templates. It generates the appropriate styles and saves them to a static CSS file. Tailwind is quick, adaptable, and dependable — with no downtime. Tailwind support has been added to CRA 5.

Tailwind is normally set up and used in 5 steps. With the pre-configured CRA 5, only three steps are required:

Step 1: Set up the template paths.

Create the tailwind.config.js configuration file in the root directory:

module.exports = {
  content: [
  theme: {
    extend: {},
  plugins: [],

Step 2: Include the Tailwind directives in your CSS file.

Here's the src/index.css file:

@tailwind base 
@tailwind components;
 @tailwind utilities;

Step 3: Integrate Tailwind into React components.

Here's an example of a src/App.js file:

import './App.css';
 function App() {
  return (
    <  div className="App">
      <  h1 className="text-5xl font-bold text-green-500" >Create React App 5
export default App;

text-5xl sets font-size: 3rem and line-height: 1. font-bold sets font-weight: 700. text-green-500 sets color: rgb(34 197 94).

When we run the code, npm start, we can see that Tailwind styles have been applied to the text:

5th version of Webpack

Webpack is a module packager. CMJ, AMD, UMD, ESM, and other modules can be bundled.

On October 10, 2020, Webpack 5 was released, with the following major features:

  • Persistent Caching improve build performance.
  • Long-Term Caching has been improved with new algorithms and defaults.
  • Bundle size has been increased due to improved Tree Shaking and Code Generation.
  • Module Federation was introduced, allowing multiple Webpack builds to work together.

Webpack 5 is included with CRA 5.

Jest 27

Jest is a JavaScript Testing Framework that focuses on test creation, execution, and structuring. Jest is a popular test runner that works with projects that use Babel, TypeScript, Node, React, Angular, Vue, and other technologies.

  • On May 25, 2021, Jest 27 was released, with the following major features:
  • To update the failed snapshots during snapshot tests in watching mode, type u. The interactive mode can now be used to step through failed tests one by one. We can skip the failed test by typing, exit the interactive mode by typing q, or return to the watch mode by pressing Enter.
  • When compared to Jest 26, the initialization time per test file was reduced by 70%.
  • User configurations written in ESM are supported, and all pluggable modules can load ESM.
  • Text files that are symlinked into the test directory have been enabled, a feature requested by Bazel.
  • Transform is now asynchronous, which is a feature requested by esbuild, Snowpack, and Vite.
  • The default test runner has been changed from jest-jasmine2 to jest-circus, and the default test environment has been changed from 'jsdom' to 'node'.
  • The new Fake Timers implementation in Jest 26 becomes the default.
  • The done test callback cannot be called more than once, and calling done and returning a Promise cannot be combined.
  • A described block must not produce any results.
  • Jest 27 is packaged with CRA 5.

ESLint 8

ESLint is a tool for detecting and reporting patterns in JavaScript and TypeScript code. It performs traditional linting to detect problematic patterns, as well as style checking to enforce conventions. On October 9, 2021, ESLint 8 was released, with the following major features:

  • Support for nodes 10, 13, and 15 has been removed.
  • The coding frame and table formatters have been removed.
  • The comma-dangle rule schema tightens up.
  • Unused disable directives can now be repaired with --fix.
  • 4 rules have been proceeding in the eslint: recommended preset: no-loss-of-precision,


no-unsafe-optional-chaining, and

no-useless backreference.
  • The ESLint class has taken the place of the CLIEngine class.
  • The obsolete linter object has been deprecated.
  • The /lib entry point is no longer available.
  • ESLint 8 is included with CRA 5.

PostCSS 8

PostCSS is a style transformation tool that uses JS plugins. Autoprefixer, for example, is a popular plugin that applies CSS prefixes based on browser popularity and property support.

On September 15, 2020, PostCSS 8 was released, with the following major features:

  • It has a new plugin API that allows all plugins to share a single CSS tree scan. It speeds up CSS processing by up to 20%. It reduces the size of node modules, supports a better source map, and improves the CSS parser.
  • Support for nodes 6, 8, 11, and 13 has been removed.
  • It serves ES6+ sources from the npm package without the need for Babel compilation.
  • The rarely used postcss.vendor API has been removed, and CRA 5 is now packaged with PostCSS 8.


CRA 5 has arrived, bringing with it new features and packages. CRA 5 will be used in the newly created project. If you already have a CRA 4 project, upgrade it as described above.

Thank you for your time. I hope you found this information useful. If you have any questions, please do not hesitate to contact us. Your digital partner will be Airo Global Software.

E-mail id: [email protected]

enter image description here

Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile:

When we first start learning Angular, we learn that there are two types of directives: Attribute directives and structural directives. We will only look at Structural Directives in this section. This includes the ability to remove an element and replace it with something else, as well as the ability to create additional elements.

As you are aware, we must distinguish Structural directives from Attribute directives in code: Structural directives should be preceded by *: *ngFor, *ngIf. Actually, when I first read this, I thought the distinction was strange and even cumbersome. Let's see if we can figure out why we need this * for the structural directive.

We will implement three different structural directives throughout the article to help you grasp the main idea.

What is ng-template?

Before we go any further, let's make sure we're all on the same page and understand what ng-template is. Let's create a simple component using this element to see what Angular actually renders:

As you can see, we defined an ng-template with a span element inside the component template. However, we do not see this span in a browser. Doesn't it appear to be a waste of time? Wait a minute, of course, it's useful and serves a purpose.

What is ng-container?

Let's look at it again with a component creation:

We can see the content that we put inside the ng-container here, but the container itself is hidden. If you're familiar with React, you'll probably recognize the behaviour a fragment or abbreviation for it.

Connect ng-container and ng-template.

Actually, we can ask Angular to render content that we explicitly place inside of the ng-template. To do so, we must first complete the following steps: step 1: get a reference to ng-template in a component.

step 2: get a reference to a container (any DOM element) where we want to render ng-content. template's

Step 3: Render content in a container programmatically.

Step 1: we define a template reference #template for the ng-template element and gain access to it via the ViewChild decorator. (you can also ask for it using this: @Input('template', read: TemplateRef ) template: TemplateRefany>).

Step 2: In the template, define a container where we want to render a predefined template and get access to it in component:

We want to read it as ViewContainerRef. Keep in mind that we can use any DOM element for containers, not just ng-container, but it keeps our layout clean because Angular doesn't leave any ng-container feet in the layout.

Step 3: We'll only have access to the container and template during the ngAfterViewInit lifecycle, and we'll need to render a template in a container: We simply generated a view from a template and inserted it into the container.

Structural Directive

You may wonder why, rather than explaining structural directives first, I started with ng-template and ng-container. However, it is necessary to explain why we put * before these directives. And the answer is that when Angular sees *, it treats our template differently and adds the following elements: Angular encircles our template with the ng-template element. That is, if the ngFor directive was not implemented, we would see nothing. Angular also creates a placeholder space called embedded view, where the directive can decide what to insert inside of this empty view container, for example, inserting the content of ng-template in the specific time as we did above.

Example 1: Create your own ngIf directive. Assume that Angular does not have a built-in directive like ngIf and that we must create our own with the name customIf. Let's build it with the Angular CLI: ng g d directives/custom-if It automatically creates a custom-if.directive.ts file in the directives folder and declares it in AppModule:

  selector: '[appCustomIf]'
export class CustomIfDirective {
  constructor() { }

Because Angular does some work behind the scenes — wrapping our template in ng-template and creating a placeholder for any content — we can ask Angular to provide access to those elements in a function native code:

  selector: '[appCustomIf]'
export class CustomIfDirective {
     private template: TemplateRef,   
     private container: ViewContainerRef) { }

@Directive({ selector: '[appCustomIf]' }) export class CustomIfDirective { @Input() appCustomIf!: boolean; constructor( private template: TemplateRef,
private container: ViewContainerRef) { } }

If @Input is true, the final step is to render the template in a container in the ngOnInit method:

  selector: '[appCustomIf]'
export class CustomIfDirective implements OnInit {
  @Input() appCustomIf!: boolean;
     private template: TemplateRef,   
     private container: ViewContainerRef) { }
  ngOnInit() {
     if (this.appCustomIf) {   

Congratulations! You've carried out the first structural directive. However, I believe that implementing the custom ngFor directive would be more interesting. Let's give it a shot.

Example 2: Creating a custom ngFor directive.

Let us recall how ngFor is used:

< ul>
  < li *ngFor="let value of values; let index">
    {{index}} {{value}}
  < /li>
< /ul>

It may appear strange given that we know we can bind to directive only JS expressions that produce a single value. However, this one, which is used, generates multiple values, let the value of values. The first source of confusion may be that we attempt to map keywords with JS keywords that we use in conjunction with for...of, but it has nothing in common with this one. Angular has its own DSL language, but we can use any word we want. Let us proceed in chronological order.

First and foremost, the expression on the right side of directive ngFor is known as macro syntax. Let us try to describe its structure: In this case, context can be anything with which we want to render a template in the target container, but it must be set as an element along with values during iteration. Remember that we typically define a template type as TemplateRefany>, which is a type of context for our template.

Which name should we use to gain access to value in values is the more interesting part here. There are three parts:

  • The first part is the name of the directive (in our case, ngFor).
  • The second part is the name of the word before value (in our case, of).
  • The third part is the name of the word after value (in our case, of).

As I previously stated, you can use any word you want instead of, for example, iterate, and access to the value will be via @Input('ngForIterate'), which is also known as a binding key.

So far, so good, I hope. Let's get started with our customFor directive. As is customary, let's use Angular CLI to build scaffolding for a directive:

directives/customFor ng gd

  selector: '[appCustomFor]'
export class CustomForDirective {
  constructor() { }


To spice things up, let's define our microsyntax for the developing directive:

< ul *appCustomFor="let value iterate values; let index">
  < li>{{index}} {{value}}< /li>
< ul>

With the following decorator, we can gain access to values:

@Input('appCustomForIterate') items: any[]

We used the following API to render a template in a container:


and the method createEmbeddedView accepts the second argument, which is a template context:

this.containerRef.createEmbeddedView(this.templateRef, {
  '$implicit': '' // any value which we want
  index: 0 // any value which we want

Keep an eye out for the $implicit key, which in our case manipulates value for value in our expression. Let's take a look at how we might put this directive into action: import { Directive, Input, OnInit, TemplateRef, ViewContainerRef } from '@angular/core';

  selector: '[appCustomFor]',
 export class CustomForDirective implements OnInit {
  @Input('appCustomForIterate') items!: any[];
    private templateRef: TemplateRef<{'$implicit': any, index: number}>,
    private containerRef: ViewContainerRef
  ) {}
  ngOnInit() {
    for(let i = 0; i< this.items.length; i++){
    this.containerRef.createEmbeddedView(this.templateRef, {
        index: i,
        '$implicit': this.items[i]

Pay attention to the fact that I purposefully changed the key used in the built-in directive ngForinto iterate, so we can use this directive as follows:

< div *appCustomFor="let value iterate items; let i = index">
 {{value}} {{i}}
 < /div>

Example 3: Structural Directive-compliant custom carousel

Let's look at a more concrete example for production. Let us suppose we need to use Carousel. We must pass a list of images for the carousel to the directive, and the custom directive must display one current image with the option to move forward/backward.

< div *appCarousel="let image of images; let ctr = ctr">
 < img [src]="image" />
 < button (click)="ctr.prev()">Prev
 < button (click)="">Next
< /div>

Let's begin as usual by creating a directive with Angular CLI and injecting TemplateRef and ViewContainerRef into the function native code. Also, we need to get access to the value in the images variable, which we can do with a key binding @Input('appCarouselOf'):

import { Directive, Input, OnInit, ViewContainerRef, TemplateRef } from '@angular/core';
  selector: '[appCarousel]',
 export class CarouselDirective {
  @Input('appCarouselOf') images!: string[];
 currentIndex = 0;
    private templateRef: TemplateRef,
    private viewContainer: ViewContainerRef
  ) {}

So far, everything should be familiar. So, let's create a method that is in charge of template rendering in a container. Before we begin, keep in mind that the usage of this directive allows for the creation of images. In the template context, let ctr = ctr, we must pass two variables: $implicit maintains the current carousel image, ctr — controller in charge of image rotation

  selector: '[appCarousel]',
 export class CarouselDirective implements OnInit {
  // skipped for brevity
   this.viewContainer.createEmbeddedView(this.templateRef, {
        ctr: this,
        '$implicit': this.images[this.currentIndex]

And now we'll implement two methods that will be available in the controller: next and previous:

  selector: '[appCarousel]',
 export class CarouselDirective implements OnInit {
  // skipped for brevity
    this.currentIndex = this.currentIndex === this.images.length - 1 ? 0 : this.currentIndex + 1;
    this.currentIndex = this.currentIndex - 1 < 0 ? this.images.length - 1: this.currentIndex - 1;

The full implementation:

import { Directive, Input, OnInit, ViewContainerRef, TemplateRef } from '@angular/core';
  selector: '[appCarousel]',
export class CarouselDirective implements OnInit {
  @Input('appCarouselOf') images!: string[];
   currentIndex = 0;
    private templateRef: TemplateRef,
    private viewContainer: ViewContainerRef
  ) {}
   ngOnInit() {
    this.viewContainer.createEmbeddedView(this.templateRef, {
        ctr: this,
        '$implicit': this.images[this.currentIndex]
    this.currentIndex = this.currentIndex === this.images.length - 1 ? 0 : this.currentIndex + 1;
    this.currentIndex = this.currentIndex - 1 < 0 ? this.images.length - 1: this.currentIndex - 1;

If you have any doubt about Mastering Angular Structural Directives. Please Contact us through the given email. Airo Global Software will be your digital partner.

E-mail id: [email protected]

enter image description here Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile:

Every software developer with little experience understands the value of keeping things simple and stupid (KISS). You don't want to repeat yourself once you've learned how to use classes and functions, so keep things DRY. The goal of all of these principles is to reduce mental complexity in order to make software easier to maintain.

  • Don’t repeat yourself (DRY)

The DRY principle is at the heart of software development. Our code is organized into packages and modules. We eliminate functions. We try to make the code reusable so that we can hopefully maintain it more easily.

Benefits: Reduced complexity. The more code you have, the more maintenance you'll have to do. DRY usually results in less code. This means that for typical changes, you only need to make one adjustment.

Risk: When you do it too often, the code tends to become more complex.

Tooling support: There are programmes that can detect duplicated code. There is one for Python.

pylint --disable=all --enable=similarities src
  • You Ain’t Gonna Need It (YAGNI)

The realization that too much abstraction actually harms maintainability is referred to as YAGNI. I'm looking at you, Java developers!

Benefit: Reduced complexity. The removal of abstractions clarifies how the code works.

Risk: You will have difficulty extending your software if you use YAGNI too much and thus make too few abstractions. Furthermore, junior developers may tamper with the code in an unfavourable way.

Tooling support: None

  • Keep it Simple and Stupid (KISS)

KISS can be applied to a variety of situations. Although some solutions are smart and solve the problem at hand, the dumber solution may be preferable because it has less of a chance of introducing problems. This may occasionally be less DRY.

  • Principle of Least Surprise

Design your systems so that the location of feature implementation, as well as the behaviour and side-effects of a component, are as unsurprising as possible. Keep your coworkers informed.

Benefit: Reduced complexity. You ensure that the system's mental model corresponds to what people naturally assume.

Risk: You may need to break DRY in order to complete this task.

Tooling support: None. However, there are some indications that this was not followed:

You're explaining the same quirks of your system to new colleagues over and over.

You'll have to look up the same topic several times.

You feel compelled to document a topic that is not inherently difficult.

  • Separation of Concerns (SoC)

Every package, module, class, or function should be concerned with only one issue. When you try to do too many things, you end up doing none of them well. In practice, it is most visible in the separation of a data storage layer, a presentation layer, and a layer containing the business logic. Other types of concerns could include input validation, data synchronization, authentication, and so on.

Benefit: Reduced complexity: It's usually easier to see where changes need to be made.

There should be fewer unfavourable side effects to consider.

People can work in parallel without encountering a slew of merge conflicts.

Risk: If you go overboard on SoC, you will almost certainly violate KISS or YAGNI.

Tooling support: Cohesion can be measured by counting how many classes/functions from other packages are used. A large number of externally imported functions may indicate SoC violations. A large number of merge conflicts may also indicate a problem.

  • Fail early, fail loud

As developers, we must deal with a wide range of errors. And it's unclear how to deal with them, especially for beginners.

To fail early is a pattern that has helped me a lot in the past. That is, the error should be recognized very close to the location where it can occur. User input, in particular, should be validated directly in the input layer. However, network interactions are another common scenario in which error cases must be handled.

The other pattern is to fail loudly, which means to throw an exception and log a message. Don't simply return None or NULL. Exceptions should be made. Depending on the type of Exception, you may also want to notify the user.

Benefit: Easier to maintain because it is clear where functionality belongs and how the system should be designed. Errors occur earlier, making debugging easier.

Risk: None.

Tooling support: None

  • Defensive Programming

The term "defensive programming" is derived from the term "defensive driving." Defensive driving is defined as "driving to save lives, time, and money regardless of the circumstances around you or the actions of others." Defensive programming is the concept of remaining robust and correct in the face of changing environmental conditions and the actions of others. This can mean being resistant to incorrect input, such as when using an IBAN field in a database to ensure that the content stored there contains an IBAN. It may also imply making assertions explicit and raising exceptions if those assertions are violated. It may imply making API calls idempotent. It may imply having a high level of test coverage in order to be defensive against future breaking changes.

Three fundamental rules of defensive programming

  • Until proven otherwise, all data is relevant.
  • Unless proven otherwise, all data is tainted.
  • Until proven otherwise, all code is insecure.

"Shit in shit out" is an alternative to defensive programming.

Benefit: Higher robustness

Risk: Increased maintenance as a result of a more complex/lengthy code base

Tooling support: Check your coverage to see how much of your unit tests are covered. Try mutation testing if you want to go crazy. There is chaos engineering for infrastructure. Load testing is done.


The SOLID principles provide guidance in the areas of coupling and cohesion. They were designed with object-oriented programming (OOP) in mind, but they can also be applied to abstraction levels other than classes, such as services or functions. Later on, I'll simply refer to those as "components."

Two components can be linked in a variety of ways. For example, one service may require knowledge of how another service operates internally in order to perform its functions. The more component A is dependent on component B, the more A is coupled with B. Please keep in mind that this is an asymmetrical relationship. We don't care about the direction of coupling.

One module's high cohesion indicates that its internal components are tightly linked. They are all about the same thing.

We strive for loose coupling and high cohesion between components.

The principle of single-responsibility

"A class should never change for more than one reason."

The roles of software entities such as services, packages, modules, classes, and functions should be clearly defined. They should typically operate at a single abstraction level and not do too much.

One tool for achieving separation of concerns is single responsibility.

Tooling support:

I'm not aware of any automated tools for detecting violations of the principle of single responsibility. You can, however, try to describe the functionality of the components without using the words "and" or "or." If this does not work, you may be breaking the law.

The open-close principle

"Software entities... should be open to extension but not to modification."

If you modify a component on which others rely, you risk breaking their code.

The substitution principle of Liskov

"Functions that use pointers or references to base classes must be able to use derived class objects without being aware of it."

Benefit: This is a fundamental assumption in OOP. Simply follow it.

Risk: None

The principle of interface segregation

"A number of client-specific interfaces are preferable to a single general-purpose interface."

Benefit: It's easier to extend software and reuse interfaces if you have the option to pick and choose. However, if the software is entirely in-house, I would rather create larger interfaces and split as needed.

Risk: Violation of KISS.

The principle of dependency inversion

"Rely on abstractions rather than concretions."

In some cases, you may want to operate on a broader class of inputs than the one you're currently dealing with. WSGI, JDBC, and basically any plugin system come to mind as examples. You want to define an interface on which you will rely. The components must then implement this interface.

Assume you have a programme that requires access to a relational database. All queries for all types of relational databases could now be implemented. Alternatively, you can specify that the function receives a database connector that supports the JDBC interface.

Benefit: In the long run, this makes the software much easier to maintain because it is clear where functionality is located. It also aids in KISS.

Risk: Overdoing it may result in a violation of KISS. A good rule of thumb is that an interface should be implemented by at least two classes before it is created.

  • Locality Principle

Things that belong together should not be separated. If two sections of code are frequently edited together, try to keep them as close together as possible. At the very least, they should be in the same package, hopefully in the same directory, and possibly in the same file — and if you're lucky, they should be in the same class or directly below each other within the file.

Benefit: Hopefully, this means fewer merge conflicts. When you try to find that other file, you do not need to switch context. When you refactor that piece, you may recall everything that belongs to it.

Risk: Violating loose coupling or concern separation.

Tooling support: So far, none, but I'm considering making one for Python. Essentially, I would examine the git commits.

If you have any doubt about the above topic. Don’t hesitate to contact us. Airo Global Software will be your digital partner.

E-mail id: [email protected] enter image description here Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile: