3 steps to avoid malicious mobile apps

Today, everyone has smart phones, from children to elders. Smart phones contains a bunch of applications that increase productivity in real life. Human today may spend time with smart phones even more than with human. Smart phones become a part of life, an accessories, and maybe secrets holder of everyone. People put almost everything in their phone, from photo, identity to bank accounts. This habit makes smart phones top priority target for hackers in hacking campaigns, to steal secrets, or simply money. These hacking campaigns usually exploit users’s low awareness or low knowledge about mobile app security factors. Android & iOS, as default, provide many mechanisms to protect users from getting hacked but the weakest point in the system is always human psychology. “Amateurs hack machine, Professionals hack people“. If you are afraid of hacking, this post is for you. This post hopefully can guard your mind up to defense against one of the highest risk factors in Internet era: cybercriminal.

Most of cyber security incidents – aka get hacked – known in public begins from a very non-technical step and can be performed by anyone, named Social Engineering. Social Engineering is a type of manipulation where someone tricks people into giving away sensitive information, access, or money—by exploiting human psychology rather than hacking systems. To steal data from your phones, 99% of time, hackers need to trick you to install malicious applications. Malicious applications, once installed, will silently steal data and send back to hackers. So, just by acknowledging which app can be malicious, you already get you safe 99%. The rest 1% is involved to Zero Day exploitations, which are real hacking, require top-notch hacking knowledge and skills, but will not be mentioned in this post. For more understanding about Zero Day exploitations, you can subscribe here then the-tech-lead.com will inform you when there is any article available.

Here we back to How to know if a mobile app is malicious!

1. Double Attention on download source

As a golden rule for mobile applications, only download from trusted store which is PlayStore and AppStore. PlayStore and AppStore is pre-installed on any Android or iOS smartphones. For any applications, only download from PlayStore app (for Android phones such as Samsung, Pixel, Nexus, etc) and AppStore app(for iPhones). Do NOT install any applications outside these 2 official stores, regardless any reasons, urgency or who tell us.

For Android world, mobile applications are written in Java and Kotlin language, exported as APK files (file has extension .apk). This .apk files then be signed with digital signature of its owner – who registered as developer on PlayStore with their legal information. This process is essential as it can tell who actually behind an application, and if we has evidence about any malicious activities, we know who to sue. The information of who develop certain application can be found at section “App Support” under its logo.

APK files can be installed directly to Android phone via user’s explicit grant. Users can tap to .apk files stored in their phone (inside Download folder, or Document folder for example), a popup will display asking installing permission. If user grant it, the .apk will be installed. This process usually is for developers to test applications before submitting to PlayStore. For regular users, this process is an absolute indicator for a malicious application. So if someone, for any reason, tell you to do these steps manually, don’t trust them and report them to police asap. Typical trick flow is like so:

  1. You are on Social Network such as Facebook, seeing a post tell that install an application to get free 1000USD as a reward for its early users.
  2. You click on download link, your phone download it into Download folder
  3. You follow “installation guide” written next to download link, saying that you open Setting app, enable “installation app from unknown source”, then open Download folder, tap on APK file.
  4. Your Android phone show a popup telling you that APK is from unknown source, but according to the guide, it tell you just press Accept.
  5. Then the malicious APK is installed then it steal your data.

Similarly, on iPhone world, iOS applications are written in Swift and ObjectC language, and exported as .ipa file. IPA files can be installed via the App Store or through developer tools like Xcode. Usually, we can’t freely install IPA files unless the app is signed with a valid certificate or the iPhone is registered for development. But there is still a trick that hacker can trick users to install malicious IPA files: via TestFlight abusing. TestFlight is Apple’s official tool for distributing beta (testing) versions of iOS apps before they go public on the App Store. Developers use it to invite testers, collect feedback and fix bugs before release. TestFlight is legit—but it can be abused in social engineering attacks. Typical trick flow is like so:

  1. Someone impersonates a bank employee, call you, tell exactly your name, your address, and saying “Your bank account is in legal risk due to a transfer from criminal gang” or “Police is screening your account because they think you laundry money”, with urgent, serious, and a bit threaten.
  2. Then they sent you a link to install their internal iOS app to prove that you are innocent.
  3. You tap on that link, iPhone redirect you to TestFlight app because it is TestFlight invitation link and your iPhone does not have TestFlight installed
  4. Then you are told to tap on the link again, this time the fake application is installed to your iPhone, via TestFlight
  5. The fake app looks the same to bank’s official application so you have no doubt
  6. But the app then steal data from your iPhone, or trick you to fill username, password, even OTP and CVV number

2. Make sense of app permissions

When users smart enough to not install app from untrusted source anymore, hackers may use level 2 of malice: Camouflage. Typical hacking plan is like so:

  1. This time, hackers develop or purchase normal mobile application source code then publish via PlayStore and AppStore normally.
  2. Because it is normal, PlayStore & Appstore accepts and make it available.
  3. Then hacker send next updates for the normal application, with new features requiring some system permissions such as: read contact list, read call logs, read gallery, read GPS, etc…
  4. Hackers advertises that app with awesome features that can make outstanding outcomes, right in need of some users.
  5. Then with curiosity, users install the app, from PlayStore, or AppStore depends on their phone OS.
  6. The app requires user to grant quite a lot permission but users usually don’t care and don’t understand so just accept it.
  7. Then the app steal call logs, photos, location data, etc …, from the phone, thanks to user’s grant.

Both Android & iOS has default safeguard to protect user’s privacy. Every application, as default, can not access to sensitive data on smart phone. For example, if an application want to read some photos, developer – who is making that application – must register “Access Gallery” permission. Then whenever the application want to use this permission, the operating system (Android / iOS) will display a message asking users to grant that permission. When granted, application now can see photos in the phone. Similarly, other sensitive info such as call logs, GPS, and many more also requires user grant permission before the app can actually read data. To know an application want what permission, we can check right on PlayStore for Android app, and AppStore for iOS app.

How to check Permissions of Android application

Before installing:

  1. Open the app page on the Google Play Store
  2. Scroll down to “App info” → “Permissions”
  3. Tap “See more” to view full details
  4. Check what the app can access:
    • Location
    • Contacts
    • Storage
    • Microphone, etc.

After installing:

  1. Go to Settings → Privacy → Permission Manager
  2. Select a permission (e.g. Location)
  3. See which apps are using it
  4. You can:
    • Allow
    • Allow only while using
    • Deny

👉 Tip: Android also shows permissions during first use, so don’t just tap “Allow” automatically.

How to check Permissions of iOS application

Before installing:

  1. Open the app page on the App Store
  2. Scroll to “App Privacy” section
  3. Review what data the app may collect:
    • Location
    • Contacts
    • Identifiers
    • Usage data
    • etc …

After installing:

  1. Go to Settings → Privacy & Security
  2. Tap a category (e.g. Location, Photos, Microphone)
  3. Select the app
  4. Choose access level:
    • Never
    • Ask Next Time
    • While Using
    • Always (for location)

Review these permission carefully. Anticipates which features need it. If there is too much permissions comparing to expected features, it is a red flag.

Here’s a practical mapping of common Android & iOS permissions you’ll see on the Google Play Store, AppStore and the features that legitimately use them. This helps you judge whether a request makes sense.

Android Permissions & Legit Features use them

PermissionLegit FeaturesSuspicious If
Read Contact, Write ContactMessaging apps (find friends)
Contact backup/sync
Invite friends feature
Suspicious if a simple game or flashlight asks for this
Read Call Log, Read Phone StateCaller ID / spam detection apps
Dialer & call management
Suspicious if: unrelated apps request call history
Read SMS, Send SMSMessaging apps
OTP auto-fill
High Risk: can intercept verification codes
Recommend: NEVER download
Access Fine Location, Access Coarse LocationMaps & navigation
Ride-hailing / delivery
Weather apps (local forecast)
Suspicious if: calculator or offline app asks for precise location
Read External Storage, Media AccessUpload photos (social media)
File managers
Image/video editing apps
Suspicious if: app doesn’t handle files but asks access
Record AudioVoice messages / calls
Recording apps
Voice assistants
Suspicious if: no voice feature exists
CameraTaking photos/videos
QR/barcode scanning
Video calls
Suspicious if: app has no visual capture feature
Notification accessNotification managers
Smart reply apps
High risk: these app can read OTPs and messages,
Recommend: NEVER download
Accessibility ServiceScreen readers (for visually impaired)
Automation tools
High Risk: these app can control screen, read inputs, commonly abused in scams
Recommend: NEVER download

iOS Permissions & Legit Features use them

PermissioniOS Permission Name / KeyCommon Legit FeaturesSuspicious If…
ContactsContacts (NSContactsUsageDescription)Messaging, contact sync, invite friendsGame or simple app requests it
Location (GPS)Location (NSLocationWhenInUse / Always)Maps, ride-hailing, delivery, weatherApp doesn’t need location
Photos / MediaPhotos (NSPhotoLibraryUsageDescription)Upload images, editing appsApp doesn’t use images/files
CameraCamera (NSCameraUsageDescription)Photos, video calls, QR scanningNo camera-related feature
MicrophoneMicrophone (NSMicrophoneUsageDescription)Voice calls, recording, voice inputNo audio-related feature
BluetoothBluetooth (NSBluetoothAlwaysUsageDescription)IoT devices, wearables, accessoriesApp has no hardware/device interaction
NotificationsNotifications (UNUserNotificationCenter)Alerts, messages, remindersSpammy or excessive notifications
TrackingApp Tracking Transparency (ATT)Ads personalization, analyticsApp unrelated to ads asks for tracking
Local NetworkLocal Network (NSLocalNetworkUsageDescription)Smart home, device discoveryNo local device interaction
Motion / FitnessMotion (NSMotionUsageDescription)Fitness apps, step trackingApp unrelated to activity tracking

Simple rule to evaluate permissions

When you are considering to install a new mobile application:

  • Anticipate what functions that app may have,
  • Check the Permissions that app requires
  • Then ask yourself: “Does this feature really need this permission?

If there are permissions that is not aligned with expected functions:

  1. Then slow down, don’t rush to install for whatever reason.
  2. Find alternative applications, compare Permissions among them.
  3. If you not sure but want to check the app, use Emulators to test it first. Emulators is virtual smart phones and can be created via tools such as Genymotion, VirtualBox and a few others. Emulators is isolated environment and do not contain your data.
  4. If you know any experts in cybersecurity field, ask them for advise.

3. Monitor phone’s performance

Welcome to the level 3 of malice: Zero Day Exploitation

Thanks to strictly review process of AppStore and PlayStore, most of malicious mobile app is banned. But optimism is not a recommended character in cybersecurity field. Zero Day is vulnerabilities that is unknown by public, even among experts, and in fact, they are weaponized by many governments as a national strength.

Android & iOS itself is softwares. Softwares might have bugs and security holes. These vulnerabilities is actively hunted by experts in cybersecurity industry and sponsored by governments. Once a Zero Day is discovered, it becomes a secret weapon for cybercriminal groups to attack or infiltrate system on over the world. Mobile app is not immune. If there is some vulnerabilities in operating systems, here is Android or iOS, then it will be the target for level 3 of malice.

Although it is rare, but it still a case for us – regular users – to keep an eye on. After install an application from Google Play Store, or AppStore, pay attention on device performance:

  • whether it get slower,
  • or hotter,
  • or get lagged
  • or any abnormal behaviors.

Vulnerabilities has many forms, it is hard to explain on a single post here but many of its form create a lot workload on device, as a try to exploiting, so it may make the phone slower, hotter, or lagged.

Example: a well-known Spyware

One of the most well-known cases of this level 3 of malice involves commercial spyware: Pegasus, developed by NSO Group. This spyware has successfully stolen sensitive data on user’s phone often without any visible permission prompts. The trick flow is like so:

  1. NSO Group Deliver Pegasus via app or link. Target users receives a message that trick them to install the app. The app looks absolutely normal since it require minimal permissions.
  2. Once installed, Hidden zero-day exploit triggers. The app, or content inside it, exploits an unknown vulnerability in Android.
  3. Privilege escalation: The exploit gains deeper system access than normal apps should have and bypasses Android’s sandbox protections.
  4. Silent data access: then NSO Group can access Messages, Camera / microphone, Location without user’s awareness

This attacks are extremely expensive and used for targeted surveillance, not mass scams. Once the exploit method is discovered, it can be quickly patched by developers behind Android & iOS system. But the problem is it really hard to discover.

There isn’t just one single CVE for Pegasus. It has used multiple zero-day vulnerabilities over time, often chaining several together. Here are some of the most well-known ones:

Notable CVEs linked to Pegasus campaigns

1. FORCEDENTRY exploit chain (2021)

  • CVE-2021-30860
  • Affected: iOS (Apple devices)
  • Type: CoreGraphics / PDF parsing vulnerability

What it did:

  • Delivered via iMessage (no user interaction needed)
  • Exploited how the system processed malicious image/PDF data
  • Led to full device compromise

👉 This was one of the most advanced zero-click exploits ever discovered

2. WhatsApp exploit (2019)

  • CVE-2019-3568
  • Affected: WhatsApp on Android & iOS
  • Type: buffer overflow in VoIP call handling

What it did:

  • Attacker placed a WhatsApp call
  • Even if you didn’t answer → exploit could trigger
  • Installed spyware silently

3. Chrome sandbox escape (used in chains)

  • CVE-2020-6418
  • Affected: Google Chrome (Android)

What it did:

  • Used as part of a chain to escape browser sandbox
  • Combined with other bugs to gain deeper access

4. KISMET (suspected chain, 2020)

  • No single confirmed CVE publicly disclosed
  • Targeted iMessage (iOS 13)

What it did:

  • Zero-click exploit (no interaction)
  • Predecessor to FORCEDENTRY

To understand more about these CVE in the future, please subscribe so when the-tech-lead.com post any, you will be informed. Each of CVE deserves a long post itself.


How to save $99/year when build app on iOS

If $99 per year is dust to you then this post is not for you 🙂

If it is not, then please take a look !

A fact is that it will cost $99 per year to be able to publish mobile applications to AppStore. For any indie developers that is at the first step of publishing their app, this cost might cause some hesitation.

In case that your application is simple, which is not depends system level APIs such as GPS, File System, Bluetooth, Background Activities or Push Notification, it is possible to make use of PWA feature that is supported by Safari browser which always available on iOS and MacOS.

PWA stands for Progressive Web App. It is a web app, but can be installed into smart phones like a mobile app. Simply put, instead of accessing via a web browser like Safari or Chrome, users can find an icon on their phone, tap it and open the app. This experience makes it feel like it is a mobile app, but under beneath, it opens a browser session and render HTML, JS, CSS code. Although the feel when using PWA app is not as smooth and optimized as when on mobile app, it is acceptable for simple tools, content-first applications, or admin dashboards.

I will take one of my favorite PWA application, Meme Express, as an example. Meme Express is a meme editor that I am using on my Macbook and iPhone whenever I want to make a meme. This meme editor is built with Flutter framework. It has a native app on PlayStore for Android, and a PWA version for the rest of OS including: iOS, MacOS, Window and Linux, essentially, any device can run a browser.

How is PWA version of Meme Express made ?

Framework

Align with mobile first design, Flutter is in used. For simple tools, Flutter is a perfect cross-platform solution, when we can write code once then port to iOS, Android, WebApp, Window and Linux application.

Deploy

For Android version, it is published via Playstore normally, at here: https://play.google.com/store/apps/details?id=com.ease_studio.meme. Unlike other cross-platform framework that utilize in-app web view to mimic mobile app, Flutter ports application to a native Android app.

For iOS version, Flutter can port app to native iOS code as well. But because 99$/year is not an option here, PWA version comes as a rescue.

To publish a PWA version, a hosting server is required. A hosting server requires monthly cost. Luckily, Github Page allow us to deploy a web app from a repository for free and it can be accessed via URL username.github.io/app-name , for example with Meme Express, it is https://ease-studio.github.io/meme-pwa/ . Github Page also allows to map a domain name to it. For example here, https://meme-express.io.vn/ actually points to https://ease-studio.github.io/meme-pwa/ .

Make it Installable

To make a web app installable, aka make it a PWA app, a file manifest.json is added. manifest.json structured is defined at: https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Manifest.

Install PWA app

Below is a demonstration of installing an PWA app to an iPhone, taking Meme Express as an example. Simply put:

  1. Open Safari go to https://meme-express.io.vn/
  2. tap “Share” icon
  3. tap “Add to Home Screen”

How to compete with generative AI as a software engineer ?

Before the decade of AI bursting, software engineering is mostly about writing code that realize requirements. Software Engineers, at some extent, act like a translators between human languages and computer language. This translation today can be accomplished by many generative AI products in seconds and from my observation, generated code has pattern even better than code written by most of developers. It is understandable when companies begin laying off employees that does not match existing AI. It is just a cost optimization – vital part of every business – and also a coldest truth of this life, might be !

What is generative AI good and not good at ?

Recall the flow that each software engineer has to do daily is:

Receive requirements -> Review current state of source code -> Define a target state of source code -> Retrieve information from documents of related tools, libraries and solutions -> Pick solutions -> Actually write code -> Aligning new code to existing code -> Deploy -> Testing -> Measuring results -> Read error messages -> Debugging.

Some steps of this flow is done better by generative AI, and some is better by human:

StepsDescriptionWinner and Why
Receive requirementsto capture goals, constraints, acceptance criteria, performance, security needs, and stakeholders’ expectations.Human
Reason: human are better at eliciting ambiguous needs, negotiating trade-offs, and asking the right follow-ups with stakeholders. AI can help by summarizing long requirement documents and suggesting missing or inconsistent points.
Review current state of source codeto read codebase, architecture, tests, docs, build scripts, dependencies, and CI config.Human + AI
Reason: AI can quickly index, summarize files, find patterns, risky hotspots, and generate dependency graphs. But humans provide domain knowledge, historical context, and recognize subtle intent (business logic, quirks, trade-offs).
Define a target state of source code to design the desired architecture, interfaces, data flows, APIs, and acceptance criteria for the new state.Human + AI
Reason: AI can propose multiple concrete design options, highlight trade-offs. Humans must pick the option that fits non-technical constraints (policy, team skill, product strategy).
Retrieve information from documents of related tools, libraries and solutions to find API docs, migration guides, best practices, configuration notes.AI
Reason: AI can extract key steps, call signatures, breaking changes, and produce concise examples from long docs much faster than manual reading. Humans validate and interpret edge cases.
Pick solutionsto select libraries, patterns, and implementation approaches considering performance, security, license, team skills.Human
Reason: human decision-makers must weigh organizational constraints, long-term maintenance, licensing, and political factors.
Actually write codeimplement features, refactor, add tests, update docs.AI
Reason: AI excels at generating boilerplate, test stubs, consistent code patterns, and translations across languages.
Aligning new code to existing codeensure style, APIs, error-handling, logging, and patterns match the codebase; maintain backward compatibility.Human + AI
Reason: AI can automatically reformat, rename for consistency, and propose refactors to match patterns; humans confirm that changes don’t break conventions tied to tests or runtime behaviors.
Deploypush to staging/production, run migration scripts, coordinate releases, rollback plans.Human
Reason: Humans must coordinate cross-team tasks, business windows, and incident response. AI/automation is excellent at packaging, CI/CD scripts, and repeatable deployment steps.
TestingRun the application locally and manually verify that new changes behave as expected.Human
Reason: Manual testing relies heavily on intuition, product knowledge, and human perception (e.g., UX feel, layout issues, unexpected delays, weird state transitions).
Measuring resultsmonitor metrics, logs, user feedback, testing results, and define success signals.Human + AI
Reason: AI can detect anomalies, summarize metrics, and surface correlations. Humans decide what metrics matter, interpret business impact, and choose next actions.
Read error messagesanalyze stack traces, logs, exceptions, and failure contexts.Human + AI
Reason: AI quickly maps errors to likely root causes and suggests reproducible steps. Humans provide context (recent changes, infra issues) and confirm fixes.
Debuggingreproduce issues, step through code, identify root cause, fix and validate.Human
Reason: AI speeds discovery (identifying suspicious diffs, suggesting breakpoints, generating reproducer scripts), but complex debugging often needs human insight into domain rules, race conditions, and stateful behaviors.

How to compete with generative AI to secure the career as a software engineer ?

Similar to the Industrial Revolution and Digital Revolution, where labors is replaced by machines, some jobs disappeared but new jobs got created. And at some extent, AI, is just another machine, huge one, so, essentially, we are still in the Revolution of Machine era.

The answer for this question is that we need to work on where this huge machine cannot. So far, at the moment of this post, what we can do to compete with AI in software development are:

Transit to Solution Architect

As AI becomes strong at writing code, humans can shift upward into architectural thinking. A Solution Architect focuses on shaping systems, not just lines of code. This involves interpreting ambiguous requirements, negotiating constraints across teams, balancing trade-offs between cost, performance, security, and future growth. AI can propose patterns, but only a human understands organizational politics, legacy constraints, domain history, and long-term impact. By moving into architecture, you operate at a layer where human judgment, experience, and foresight remain irreplaceable.

Become Reviewer / Validator

AI can produce solutions quickly, but it still needs someone to verify correctness, safety, and alignment with real-world constraints. A human reviewer checks assumptions, identifies risks, ensures compliance with business rules, and validates that AI-generated code or plans actually make sense in context. Humans excel at spotting hidden inconsistencies, ethical issues, and practical pitfalls that AI may overlook. Becoming a Validator means owning the final approval — the role of the responsible adult in the loop.

Become Orchestrator

Future engineers will spend less time typing code and more time coordinating AI agents, tools, workflows, and automation. An Orchestrator knows how to decompose problems, feed the right information to the right AI tool, evaluate outputs, and blend them into a coherent product. This role requires systems thinking, communication, and the ability to see the entire workflow end-to-end. AI is powerful but narrow; an Orchestrator provides the glue, strategy, and oversight that turns multiple AI capabilities into a real solution.

Study Broader knowledge

AI is good at depth — consuming a specific library or framework instantly — but humans win by having breadth. Understanding multiple domains (networking, security, product design, compliance, UX, devops, data, hardware) allows you to make decisions AI cannot contextualize. Breadth lets you spot cross-domain interactions, anticipate downstream consequences, and design better holistic systems. The more wide your knowledge, the more you can see risks, opportunities, and real-world constraints that AI cannot infer from text alone.

Expertise in task description

In an AI-driven era, the most valuable skill is the ability to turn a messy idea into a clear, precise, constraints-rich task. This includes defining scope, edge cases, success criteria, and architectural boundaries. AI is only as good as the instructions it receives — so those who excel at describing tasks will control the quality of AI output. Humans who master problem framing, prompt engineering, and requirement decomposition gain leverage: they make AI more accurate, faster, and more predictable than others can.

Business Analyst

The heart of value creation lies in understanding the business, not writing the code. AI cannot replace someone who knows market dynamics, user behavior, budget constraints, prioritization logic, risk tolerance, stakeholder psychology, and regulatory boundaries. A Business Analyst bridges the gap between technology and real-world value. They decide why a feature matters, who it serves, how it impacts revenue or cost, and what risk it introduces — areas where AI can help, but not replace the human nuance needed.

Pentester

Security is one of the hardest domains for AI to master fully because it requires creativity, unpredictability, street knowledge, and adversarial thinking. A pentester does more than run scanners — they exploit human behavior, spot surprising vulnerabilities, and think like an attacker. Humans who understand security fundamentals, threat modeling, social engineering, and advanced exploitation techniques will stay in demand. AI helps automate scanning and code analysis, but a creative pentester stays ahead by understanding motives, tactics, and real-world constraints.


Essentially, it is to use AI as a super-assistant
that can write code very well
to realize our intentions.

How to avoid Merge Conflicts in software development

Beside Ambiguous Requirements, Tight Deadline and Unstable Legacy Codebase, Merge Conflict is another light fear that annoys and disrupts developers the most while making software.

From a fact of how Merge Conflict might appear in this post that long-live branches should be avoid as much as possible to mitigate chance of conflict, here are some guidelines to help any software teams deal with this fear.

User Story based Task Description

Human brain is designed to consume story, not ambiguity. In software development, User Story is short, simple description of a feature or requirement told from the perspective of the end user. It’s a fundamental element of Agile and Scrum methods — meant to capture what the user wants and why, without prescribing how developers should implement it. A user story usually follows this format: As a [type of user], when [something happen], user want [some goal] so that [some reason] . For example: As a registered user, I want to reset my password so that I can access my account if I forget it. This helps teams understand who needs something, what they need, and why it matters.

Depends on how big the goal user want is, a User Story can be splitted into simpler stories. We don’t have to write an essay in task description because we are not at school. Clarity is the top priority when writing tasks descriptions, so don’t think, just tell stories.

When a User Story is simple enough, a task stemmed from it can have a small scope of change with limited effect of codebase, and in predictable way. Small scope of change in a task helps to mitigate chance of conflicts. Even conflicts happen, resolving them can be easier because it happens in fewer places.

Merge/Rebase daily, resolve early

When tasks are defined well and scope of change is limited, the branch now can be short-live which is okay for Rebase tactic. Depend on preference of history commit tree, Merge or Rebase both is okay. The recommended practice here is to do it daily: merge main branch into new branches, or rebase new branches onto main branch. This practice helps to early aware of possible places might cause conflicts so that we can adjust coding tactic or sync up with other developers about what changes are made.

FIFO Merging

It is obviously right when prioritize tasks but do not apply priority to the order of merging code because it can turn some branches into long-live one when higher priority tasks keep being merge first. When a task is put on progress, your Kanban board for example, and when it is in Done column for example, it should be merged asap regardless priority of its task. What is completed first should be merged first, (First-In-First-Out order) . To achieve this state, utilize any tool to automatically do so is highly recommended. Of course, completion of a task here includes testing phase as well.

When a task is well defined with limited scope in User Story format, and somehow it gets stuck and turn into long-live branch, we need to review its necessity:

  • If we don’t need this feature anymore, so discard the task and close the branch.
  • If we still need this feature, but it contains risky changes, and it is why no one dare to merge it to main branch, so it is time to make simplier stories from the risky parts. Don’t let task being stuck. Keep feature branches short-live.

Commit with Task ID

Commit message is encouraged to describe what changes are but there is nothing to force or ensure that consistency. This depends on how good a developer can explain things. So to make it simple and scalable, it is recommended to begin a commit message with Task ID, for example: #1234 fix things , so whenever anyone wonders why a commit is added, they can trace back to related task description and let the User Story explains.

Long-live branches as Microservices

For any reason that a branch is planned to be long-live, such as when making a challenging feature that inevitable requires long time of development, consider to turn this big part into Microservices. Microservices architecture can keep new code in separated repository, which in turn, can mitigate risk of conflicts with existing main branch. Main system can communicate to this new Microservices in any kind to get things done without worrying about large changes from new features. The new Microservices can have its own tasks board with its own User Stories, and User here, is the Main system.

Time is money, so Don’t waste development time for resolving merge conflicts !

Store datetime as ISO 8601 instead of timestamp

Like any programmer, I used to use Date for storing date time values on database, until I suffer with bugs related to timezone and DST (Daylight Saving Time). The most common symptom is the date fields, such as created_date or updated_date, often display 1 day prior to what it is set before: Let say an admin set the created_date to Jan 1st 2025 00:00:00 clients somehow see value Dec 31 2024, 23:00:00 .

I tried putting browser timezone information into adjusting timestamps but then I noticed that the code base became more complex and the bug still can’t be fixed when DST (Daylight Saving Time) happens. The bug will happen when:

  • most of databases use integer representing microseconds (or timestamp) to store datetime data
  • users locate in many countries with different timezones
  • Daylight Saving Time happens with no fixed schedule

Then I realize the power of standard: ISO 8601, is that it can be used to store date time values in plain text and still be sortable. Storing datetime as format YYYY-MM-DD HH:mm:ss at UTC, (or any format instructed in ISO 8601) can remove all headaches when using timestamp but also remain sorting & filtering capabilities. The only downside, is the frontend part and backend part has to make sure date time data is sent and received in ISO 8061 format instead of integers, and this conversion is simple enough and can help avoid days of debugging.