Header image

Explore all articles in Tech Stack

Knowledge

Others

Tech Stack

+0

    Level Up Your Code: Transitioning to Validated Environment Variables

    Validated Environment variables play a critical role in software projects of all sizes. As projects grow, so does the number of environment variables—API keys, custom configurations, feature flags, and more. Managing these variables effectively becomes increasingly complex. If mismanaged, they can lead to severe bugs, server crashes, and even security vulnerabilities.  While there’s no one-size-fits-all solution, having some structure in how we manage environment variables can really help reduce mistakes and confusion down the road. In this article, I’ll share how I’ve been handling them in my own projects and what’s worked well for me so far. My Personal Story When I first started programming, environment variables were a constant source of headaches. I often ran into problems like: Misspelled variable names.Failure to retrieve variable values, even though I was sure they were set.Forgetting to define variables entirely, leading to runtime errors. These issues were tricky to detect. Typically, I wouldn’t notice anything was wrong until the application misbehaved or crashed. Debugging these errors was tedious—tracing back through the code to find that the root cause was a missing or misconfigured environment variable. For a long time, I struggled with managing environment variables. Eventually, I discovered a more effective approach: validating all required variables before running the application. This process has saved me countless hours of debugging and has become a core part of my workflow. Today, I want to share this approach with you. A Common Trap in Real Projects Beyond personal hiccups, I’ve also seen issues arise in real-world projects due to manual environment handling. One particular pitfall involves relying on if/else conditions to set or interpret environment variables like NODE_ENV. For example: if (process.env.NODE_ENV === "production") { // do something } else { // assume development } This type of conditional logic can seem harmless during development, but it often leads to incomplete coverage during testing. Developers typically test in development mode and may forget or assume things will "just work" in production. As a result, issues are only discovered after the application is deployed — when it's too late. In one of our team’s past projects, this exact scenario caused a production bug that slipped through all local tests. The root cause? A missing environment variable that was only required in production, and the conditional logic silently skipped it in development. This highlights the importance of failing fast and loudly—ideally before the application even starts. And that’s exactly what environment variable validation helps with. The Solution: Validating Environment Variables The secret to managing environment variables efficiently lies in validation. Instead of assuming all necessary variables are correctly set, validate them at the application’s startup. This prevents the application from running in an incomplete or misconfigured state, minimizing runtime errors and improving overall reliability. Benefits of Validating Environment Variables Error Prevention: Catch missing or misconfigured variables early.Improved Debugging: Clear error messages make it easier to trace issues.Security: Ensures sensitive variables like API keys are set correctly.Consistency: Establishes a standard for how environment variables are managed across your team. Implementation Here’s a simple and structured way to validate environment variables in a TypeScript project. Step 1: Define an Interface Define the expected environment variables using a TypeScript interface to enforce type safety. export interface Config { NODE_ENV: "development" | "production" | "test"; SLACK_SIGNING_SECRET: string; SLACK_BOT_TOKEN: string; SLACK_APP_TOKEN: string; PORT: number; } Step 2: Create a Config Loader Write a function to load and validate environment variables. This loader ensures that each variable is present and meets the expected type or format. Step 3: Export the Configuration Use the config loader to create a centralized configuration object that can be imported throughout your project. import { loadConfig } from "./loader"; export const config = loadConfig(); Conclusion Transitioning to validated environment variables is a straightforward yet powerful step toward building more reliable and secure applications. By validating variables during startup, you can catch misconfigurations early, save hours of debugging, and ensure your application is always running with the correct settings.

    09/07/2025

    537

    Knowledge

    +2

    • Others
    • Tech Stack

    Level Up Your Code: Transitioning to Validated Environment Variables

    09/07/2025

    537

    Knowledge

    Others

    Tech Stack

    +0

      Build Smarter: Best Practices for Creating Optimized Dockerfile

      If you’ve been using Docker in your projects, you probably know how powerful it is for shipping consistent environments across teams and systems. It's time to learn how to optimize dockerfile. But here’s the thing: a poorly written Dockerfile can quickly become a hidden performance bottleneck. Making your images unnecessarily large, your build time painfully slow, or even causing unexpected behavior in production. I’ve seen this firsthand—from early projects where we just “made it work” with whatever Dockerfile we had, to larger systems where the cost of a bad image multiplied across services. My name is Bao. After working on several real-world projects and going through lots of trial and error. I’ve gathered a handful of practical best practices to optimize Dockerfile that I’d love to share with you. Whether you’re refining a production-grade image or just curious about what you might be missing. Let me walk you through how I approach Docker optimization. Hopefully it’ll save you time, headaches, and a few docker build rage moments 😅. Identifying Inefficiencies in Dockerfile: A Case Study Below is the Dockerfile we’ll analyze: Key Observations: 1. Base Image: The Dockerfile uses ubuntu:latest, which is a general-purpose image. While versatile, it is significantly larger compared to minimal images like ubuntu:slim or Node.js-specific images like node:20-slim, node:20-alpine. 2. Redundant Package Installation: Tools like vim, wget, and git are installed but may not be necessary for building or running the application. 3. Global npm Packages: Pages like nodemon, ESLint, and prettier are installed globally. These are typically used for development and are not required in a production image. 4. Caching Issues: COPY . . is placed before npm install, invalidating the cache whenever any application file changes, even if the dependencies remain the same. 5. Shell Customization: Setting up a custom shell prompt (PS1) is irrelevant for production environments, adding unnecessary steps. 6. Development Tool in Production: The CMD uses nodemon, which is a development tool, to run the application Optimized your Docker Image Here’s how we can optimize the Dockerfile step by step. Showing the before and after for each section with the result to clearly distinguish the improvements. 1. Change the Base Image Before: FROM ubuntu:latest RUN apt-get update && apt-get install -y curl && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \ apt-get install -y nodejs Use ubuntu:latest, a general-purpose image that is large and includes many unnecessary tools. After: FROM node:20-alpine Switches to node:20-alpine, a lightweight image specifically tailored for Node.js applications. Result: With the first change being applied, the image size is drastically reduced by about ~200MB.  2. Simplify Installed Packages Before: RUN apt-get update && apt-get install -y \ curl \ wget \ git \ vim \ python3 \ make \ g++ && \ curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \ apt-get install -y nodejs Installs multiple tools (curl, wget, vim, git) and Node.js manually, increasing the image size and complexity. After: RUN apk add --no-cache python3 make g++ Uses apk (Alpine’s package manager) to install only essential build tools (python3, make, g++). Result: The image should be cleaner and smaller after removing the unnecessary tools, packages. (~250MB vs ~400MB with the older version) 3. Leverage Dependency Caching Before: COPY . . RUN npm install Copies all files before installing dependencies, causing cache invalidation whenever any file changes, even if dependencies remain unchanged. After: COPY package*.json ./ RUN npm install --only=production COPY . . Copies only package.json and package-lock.json first, ensuring that dependency installation is only re-run when these files change.Installs only production dependencies (--only=production) to exclude devDependencies. Result: Faster rebuilds and a smaller image by excluding unnecessary files and dependencies. 4. Remove Global npm Installations Before: RUN npm install -g nodemon eslint pm2 typescript prettier Installs global npm packages (nodemon, eslint, pm2, ect.) that are not needed in production, increasing image size. After: Remove Entirely: Global tools are omitted because they are unnecessary in production. Result: Reduced image size and eliminated unnecessary layers. 5. Use a Production-Ready CMD Before: CMD ["nodemon", "/app/bin/www"] Uses nodemon, which is meant for development, not production. Result: A streamlined and efficient startup command. 6. Remove Unnecessary Shell Customization Before: ENV PS1A="💻\[\e[33m\]\u\[\e[m\]@ubuntu-node\[\e[36m\][\[\e[m\]\[\e[36m\]\w\[\e[m\]\[\e[36m\]]\[\e[m\]: " RUN echo 'PS1=$PS1A' >> ~/.bashrc Sets and applies a custom shell prompt that has no practical use in production After: Remove Entirely: Shell customization is unnecessary and is removed. Result: Cleaner image with no redundant configurations or layers. Final Optimized Dockerfile FROM node:20-alpine WORKDIR /app RUN apk add --no-cache python3 make g++ COPY package*.json ./ RUN npm install --only=production COPY . . EXPOSE 3000 CMD ["node", "/app/bin/www"] 7. Leverage Multi-Stage Builds to Separate Build and Runtime In many Node.js projects, you might need tools like TypeScript or linters during the build phase—but they’re unnecessary in the final production image. That’s where multi-stage builds come in handy. Before: Everything—from installation to build to running—happens in a single image, meaning all build-time tools get carried into production. After: You separate the "build" and "run" stages, keeping only what’s strictly needed at runtime. Result: Smaller, cleaner production imageBuild-time dependencies are excludedFaster and safer deployments Final Optimized Dockerfile # Stage 1 - Builder FROM node:20-alpine AS builder WORKDIR /app RUN apk add --no-cache python3 make g++ COPY package*.json ./ RUN npm install --only=production COPY . . # Stage 2 - Production FROM node:20-alpine WORKDIR /app COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app ./ EXPOSE 3000 CMD ["node", "/app/bin/www"] Bonus. Don’t Forget .dockerignore Just like .gitignore, the .dockerignore file excludes unnecessary files and folders from the Docker build context (like node_modules, .git, logs, environment files, etc.). Recommended .dockerignore: node_modules .git *.log .env Dockerfile.dev tests/ Why it matters: Faster builds (Docker doesn’t copy irrelevant files)Smaller and cleaner imagesLower risk of leaking sensitive or unnecessary files Results of Optimization 1. Smaller Image Size: The switch to node:20-alpine and removal of unnecessary packages reduced the image size from 1.36GB, down to 862MB. 2. Faster Build Times: Leveraging caching for dependency installation speeds up rebuilds significantly.Build No Cache:Ubuntu (Old Dockerfile): ~126.2sNode 20 Alpine (New Dockerfile): 78.4sRebuild With Cache (After file changes):Ubuntu: 37.1s (Re-run: npm install)Node 20 Alpine: 8.7s (All Cached) 3. Production-Ready Setup: The image now includes only essential build tools and runtime dependencies, making it secure and efficient for production. By following these changes, your Dockerfile is now lighter, faster, and better suited for production environments. Let me know if you’d like further refinements! Conclusion Optimizing your Dockerfile is a crucial step in building smarter, faster, and more efficient containers. By adopting best practices: such as choosing the right base image, simplifying installed packages, leveraging caching, and using production-ready configurations, you can significantly enhance your build process and runtime performance. In this article, we explored how small, deliberate changes—like switching to node:20-alpine, removing unnecessary tools, and refining dependency management—can lead to.

      08/07/2025

      642

      Knowledge

      +2

      • Others
      • Tech Stack

      Build Smarter: Best Practices for Creating Optimized Dockerfile

      08/07/2025

      642

      pros and cons of using react native in web app development

      Knowledge

      Others

      Software Development

      +2

      • Tech Stack
      • Web

      Pros and Cons of Using React Native in Web App Development

      As a seasoned React developer navigating the dynamic landscape of web app development, the choice of frameworks can significantly impact project outcomes. React Native, originally designed for mobile app development, has increasingly found its way into the realm of web applications. Let's dissect the pros and cons of employing React Native in web app development with a straightforward lens. Pros of using React Native **1. Cross-Platform Development:** React Native's hallmark is its ability to facilitate cross-platform development. This is a game-changer for web apps seeking a unified codebase for both desktop and mobile experiences. The advantages are evident in projects like Facebook's own Ads Manager, where a shared codebase expedites development and maintenance. **2. Reusable Components:** The component-based architecture of React Native isn't just for show. It promotes code reusability and consistency across different parts of your web app. For instance, a custom UI component developed for a specific feature can seamlessly find its way into other sections, ensuring a uniform look and feel. **3. Familiarity with React:** For developers well-versed in React, the transition to React Native for web app development is remarkably smooth. The ability to leverage existing knowledge and skills in JavaScript and React principles expedites the learning curve, fostering a more efficient development process. **4. Community Support:** The React Native community is robust, offering a plethora of resources, libraries, and third-party tools. For web app developers, this translates into an abundance of solutions and best practices readily available. A supportive community ensures that challenges are met with collective knowledge and innovation. Cons of using React Native **1. Limited Access to Native Modules:** While React Native provides access to a wide array of native modules, it may lack support for certain platform-specific features. For example, if your web app requires intricate functionalities deeply rooted in native capabilities, relying solely on React Native might present limitations. **2. Web-Specific Performance Challenges:** React Native, initially designed for mobile environments, may not seamlessly translate to optimal performance in web browsers. Rendering complex UIs and handling animations can pose challenges, as the framework's strengths lie more in the mobile app domain. **3. Learning Curve for React Native Web:** Despite React Native's familiarity for React developers, adapting it for web app development involves a learning curve. Navigating the nuances of React Native Web, the library extension for web applications, might require additional effort. This could potentially impact development timelines. **4. Limited Ecosystem for Web:** While React Native boasts a mature ecosystem for mobile development, its offerings for web app development are relatively nascent. Developers might encounter scenarios where specific web-related functionalities are not as well-supported or documented as their mobile counterparts. Navigating the Decision Scenario 1: Building a Cross-Platform App with Unified Codebase Consider React Native for a project where a cross-platform web app with a unified codebase is a priority. For instance, an e-commerce platform aiming for consistency across desktop and mobile interfaces could benefit significantly from React Native. Scenario 2: High Dependency on Platform-Specific Features If your web app heavily relies on platform-specific features or demands high-performance graphics, consider evaluating alternatives. Directly using native frameworks or exploring hybrid solutions tailored for web might be more suitable. Scenario 3: Leveraging Existing React Skills for Web Development If your team is well-versed in React and wishes to leverage existing skills for web app development, React Native becomes a pragmatic choice. This is particularly relevant for projects where a rapid development cycle is crucial. Conclusion: In the nuanced landscape of web app development, React Native brings both advantages and challenges. Its cross-platform capabilities and code-sharing benefits can be instrumental in specific scenarios, while considerations such as performance optimization and access to native features must be weighed. Ultimately, the decision to use React Native for web app development hinges on project requirements, development goals, and the unique characteristics of the application. A pragmatic approach involves assessing the strengths and limitations outlined here, aligning them with the project's needs, and making an informed decision that best serves the development objectives.

      14/01/2024

      4k

      Knowledge

      +4

      • Others
      • Software Development
      • Tech Stack
      • Web

      Pros and Cons of Using React Native in Web App Development

      14/01/2024

      4k

      react components and architecture in reactjs development services

      Knowledge

      Others

      React

      +2

      • Software Development
      • Tech Stack

      Understanding React Components and Architecture in ReactJS Development Services

      React has emerged as a powerhouse, thanks to its component-based architecture. If you're a newcomer or someone looking to deepen your understanding of React components, you're in the right place. Let's break down the fundamentals of React's component-based architecture in plain and simple terms. What Are React Components? At its core, React is all about components. But what exactly is a component? Well, think of a component as a reusable building block for your user interface. It's like LEGO bricks for web development. Each component represents a specific part of your application's UI, encapsulating its functionality and appearance. Read more about React Component Lifecycle phases. There are two main types of components in React: Functional Components and Class Components. Functional components are concise and focused solely on rendering UI, while class components have additional features like state and lifecycle methods. In recent versions of React, the introduction of Hooks has made functional components the preferred choice for many developers. The Component-Based Architecture Now, let's dive into the heart of React's magic—its component-based architecture. Unlike traditional frameworks, where you build pages, React encourages you to break down your UI into small, reusable components. This modular approach brings several advantages to the table. 1. Reusability: Components are like building blocks that you can use and reuse across your application. Need a button? Create a button component. Want to display a user profile? Craft a profile component. This reusability not only saves time but also promotes a consistent and maintainable codebase. 2. Maintainability: Since each component is responsible for a specific part of the UI, making changes or fixing issues becomes a breeze. You don't have to scour through a massive codebase to find what you're looking for. Just locate the relevant component, make your adjustments, and you're done. 3. Scalability: As your application grows, the component-based architecture scales effortlessly. New features can be implemented by adding new components without disrupting existing functionality. It's like adding more LEGO pieces to your creation—your structure remains stable, and you can keep expanding. 4. Collaboration: Component-based development is a dream for collaborative projects. Different team members can work on different components simultaneously without stepping on each other's toes. This division of labor enhances productivity and fosters a smoother development process. 5. Testing and Debugging: With components, testing becomes more granular and focused. You can isolate and test each component independently, ensuring that it behaves as expected. If an issue arises, pinpointing the problem is more straightforward, making debugging less of a headache. Anatomy of a React Component Let's break down the basic structure of a React component: In this simple example, we have a functional component (MyComponent) and a class component (MyClassComponent). Both achieve the same result—a heading inside a div. The difference lies in their syntax and additional features offered by class components. Conclusion In a nutshell, React's component-based architecture is a game-changer in the world of web development. By breaking down your UI into modular, reusable components, you gain advantages in terms of reusability, maintainability, scalability, collaboration, and testing. Whether you're a beginner or a seasoned developer, understanding and embracing this approach can elevate your React game. So, the next time you're building a web application with React, think of it as assembling a digital LEGO masterpiece—one component at a time. Happy coding!

      12/01/2024

      1.55k

      Knowledge

      +4

      • Others
      • React
      • Software Development
      • Tech Stack

      Understanding React Components and Architecture in ReactJS Development Services

      12/01/2024

      1.55k

      Differences in UX demands of a desktop and mobile app for a SaaS product (1)

      Mobile

      Others

      Software Development

      +2

      • Tech Stack
      • Web

      Differences In UX Demands Of A Desktop And Mobile App For A SaaS Product

      While it was more common for individuals and institutions to buy software in the earlier days, the concept of software as a service isn’t that new either. And as smartphones get smarter and more accessible, many product companies are shifting their focus to this ballooning market to sustain and increase profit. But even though many have increased revenue by enhancing their mobile apps, some companies are excelling thanks to a good desktop app UX. Mobile apps often shine when it comes to daily life products for the individual end user while desktop apps encapsulate stunning collaboration and productivity solutions. A recent StatCounter study put desktop traffic at 56.51%, with mobile traffic at 50.48%. Many other reports show that there’s still a roughly 60-40 split in mobile and desktop traffic. Both market segments are here to stay, so let’s examine the differences between UX design for desktop and UX design for mobile: UI Details One of the significant differences is that desktop users are more comfortable having plenty of items fixed on a single UI screen/window. In contrast, mobile users have limited screen space and may use their thumbs more than any other finger, so you can hardly get away with a cluttered UI. Not only does it look overwhelming, but it also increases the chances of a user tapping the wrong button/option. Unfortunately, there are no straightforward solutions to this challenge. You're likely to tuck a feature/function two or more screens away, which users won't be so happy about. Luckily, some designs enable you to have retractable menus that slide into place and then slide away. You also have the option to create circular icon menus that appear when you hold down a button for a while. Ultimately, you should have a navigation option that makes it easy to go to the previous page or return to the general menu. Source: Freepik You’ll also need to include a button for the most important action a user can take at that stage in their journey. If it's the opening page, this could be a signup button; if it's a category page, it could be an "add to cart" button or a "buy" button if it's the checkout page. Whatever the CTA is, it should be visible. The user shouldn't have to first scroll down the page. It should also be within the thumb zone, so ensure it's wide enough. UX design for mobile should also consider the unique gestures like swiping, tilting and shaking that can make a mobile app more fun to use, not forgetting the use of haptic feedback to respond to a user’s command. >>> Explore more articles about UI and UX design: Top 10 Design Tools For UX And UI (2025 GUIDE)Top Emerging Trends In App UI Design (2025 OUTLOOK)Atomic Design In Software Development Performance Ideally, both desktop and mobile app versions should be as smooth and fast as possible. However, when you consider the context in which they operate and the behind-the-scenes work involved in making apps faster, you realize that you might need to put more emphasis on one of them. Mobile apps are more likely to be run on devices with limited RAM, storage space and processing power. Additionally, users are more likely to travel with mobile devices to remote areas where internet connectivity may be poorer. This is why it is essential to optimize mobile apps so they can still work fine when low on resources. From memory allocation to caching, reliance on CDNs and compression for lighter media file versions, offline modes, variable streaming bitrates and data template reuse, there are various techniques you can use to achieve higher mobile app performance. Additionally, don’t forget to test on as many devices and OS versions as possible. Personalization Many software users want to feel like the product was made just for them and it deeply understands them. In the past, personalization came in the form of changeable skins, fonts and colors. Later, it advanced to more important features like changing languages, currencies and measurement systems. However, personalization has to evolve even further. For instance, if the user has enabled your mobile app to access their location, can it suggest the perfect playlist when it detects that they are by the beach or at a riverside campsite or safari lodge. Can your shopping app switch to suggestions for sweaters and cold-weather clothes when the user is in a cold region? Will your food app point them to the places with the best hot beverages and confectioneries? Personalization covers several areas, including the way a person types and uses emojis, the order in which they browse pages, how they use search bars and more. Unlike desktop apps that run on devices like work computers that stay in the same place and are shared, or laptops that usually move between work and home, a mobile app often runs on a device that spends most of its time with one person, going everywhere. This is why making mobile app versions as adaptable to the user as possible is crucial. Security and Customer Support On the security front, mobility creates more headaches since it increases the chances of a user losing a device or connecting to an unsecured public network, among other scenarios. This means you should augment mobile apps with more security options, such as fingerprint locks, face ID and other approaches that a mobile device's native hardware can allow. On a deeper level, developers can look into code obfuscation, "root," and "jailbreak detection " to further protect against attack techniques that take advantage of the mobile app-specific architectural and operational characteristics. When it comes to customer support, mobile app UX designers can look into things like the ability to screenshot an error message page and quickly submit it via live chat or tap a call button to speak to an agent. Another vital customer support area is self-help. Remember, desktop app versions have the advantage since there's more space to display a help article column alongside the actual screen/dashboard where the user is working. They can also properly display video demos and offer an Info view where you see what a button or other element does by hovering the cursor over it. That said, mobile app UX designers need to find ways to condense knowledge bases and other self-help materials within the app to simplify the journey from learning to applying. They can also use GIFs to strike a middle-ground between heavy videos and static images when delivering demos. Wrapping Up Overall, it's prudent not to consider the desktop outdated. Instead, focus more on what it easily accommodates, then figure out how to emulate that on mobile devices. As always, it helps to work with a team of professionals conversant with the nuances of developing and delivering desktop and mobile SaaS apps. You can start this journey by contacting the SupremeTech team for a free consultation on how we bring software ideas to life for our clients.

      25/11/2022

      2.65k

      Mobile

      +4

      • Others
      • Software Development
      • Tech Stack
      • Web

      Differences In UX Demands Of A Desktop And Mobile App For A SaaS Product

      25/11/2022

      2.65k

      Customize software background

      Want to customize a software for your business?

      Meet with us! Schedule a meeting with us!