Author: webmaster

  • On-Device AI: Building Smarter, Faster, And Private Applications

    It’s not too far-fetched to say AI is a pretty handy tool that we all rely on for everyday tasks. It handles tasks like recognizing faces, understanding or cloning speech, analyzing large data, and creating personalized app experiences, such as music playlists based on your listening habits or workout plans matched to your progress.

    But here’s the catch:

    Where AI tool actually lives and does its work matters a lot.

    Take self-driving cars, for example. These types of cars need AI to process data from cameras, sensors, and other inputs to make split-second decisions, such as detecting obstacles or adjusting speed for sharp turns. Now, if all that processing depends on the cloud, network latency connection issues could lead to delayed responses or system failures. That’s why the AI should operate directly within the car. This ensures the car responds instantly without needing direct access to the internet.

    This is what we call On-Device AI (ODAI). Simply put, ODAI means AI does its job right where you are — on your phone, your car, or your wearable device, and so on — without a real need to connect to the cloud or internet in some cases. More precisely, this kind of setup is categorized as Embedded AI (EMAI), where the intelligence is embedded into the device itself.

    Okay, I mentioned ODAI and then EMAI as a subset that falls under the umbrella of ODAI. However, EMAI is slightly different from other terms you might come across, such as Edge AI, Web AI, and Cloud AI. So, what’s the difference? Here’s a quick breakdown:

    • Edge AI
      It refers to running AI models directly on devices instead of relying on remote servers or the cloud. A simple example of this is a security camera that can analyze footage right where it is. It processes everything locally and is close to where the data is collected.
    • Embedded AI
      In this case, AI algorithms are built inside the device or hardware itself, so it functions as if the device has its own mini AI brain. I mentioned self-driving cars earlier — another example is AI-powered drones, which can monitor areas or map terrains. One of the main differences between the two is that EMAI uses dedicated chips integrated with AI models and algorithms to perform intelligent tasks locally.
    • Cloud AI
      This is when the AI lives and relies on the cloud or remote servers. When you use a language translation app, the app sends the text you want to be translated to a cloud-based server, where the AI processes it and the translation back. The entire operation happens in the cloud, so it requires an internet connection to work.
    • Web AI
      These are tools or apps that run in your browser or are part of websites or online platforms. You might see product suggestions that match your preferences based on what you’ve looked at or purchased before. However, these tools often rely on AI models hosted in the cloud to analyze data and generate recommendations.

    The main difference? It’s about where the AI does the work: on your device, nearby, or somewhere far off in the cloud or web.

    What Makes On-Device AI Useful

    On-device AI is, first and foremost, about privacy — keeping your data secure and under your control. It processes everything directly on your device, avoiding the need to send personal data to external servers (cloud). So, what exactly makes this technology worth using?

    Real-Time Processing

    On-device AI processes data instantly because it doesn’t need to send anything to the cloud. For example, think of a smart doorbell — it recognizes a visitor’s face right away and notifies you. If it had to wait for cloud servers to analyze the image, there’d be a delay, which wouldn’t be practical for quick notifications.

    Enhanced Privacy and Security

    Picture this: You are opening an app using voice commands or calling a friend and receiving a summary of the conversation afterward. Your phone processes the audio data locally, and the AI system handles everything directly on your device without the help of external servers. This way, your data stays private, secure, and under your control.

    Offline Functionality

    A big win of ODAI is that it doesn’t need the internet to work, which means it can function even in areas with poor or no connectivity. You can take modern GPS navigation systems in a car as an example; they give you turn-by-turn directions with no signal, making sure you still get where you need to go.

    Reduced Latency

    ODAI AI skips out the round trip of sending data to the cloud and waiting for a response. This means that when you make a change, like adjusting a setting, the device processes the input immediately, making your experience smoother and more responsive.

    The Technical Pieces Of The On-Device AI Puzzle

    At its core, ODAI uses special hardware and efficient model designs to carry out tasks directly on devices like smartphones, smartwatches, and Internet of Things (IoT) gadgets. Thanks to the advances in hardware technology, AI can now work locally, especially for tasks requiring AI-specific computer processing, such as the following:

    • Neural Processing Units (NPUs)
      These chips are specifically designed for AI and optimized for neural nets, deep learning, and machine learning applications. They can handle large-scale AI training efficiently while consuming minimal power.
    • Graphics Processing Units (GPUs)
      Known for processing multiple tasks simultaneously, GPUs excel in speeding up AI operations, particularly with massive datasets.

    Here’s a look at some innovative AI chips in the industry:

    Product Organization Key Features
    Spiking Neural Network Chip Indian Institute of Technology Ultra-low power consumption
    Hierarchical Learning Processor Ceromorphic Alternative transistor structure
    Intelligent Processing Units (IPUs) Graphcore Multiple products targeting end devices and cloud
    Katana Edge AI Synaptics Combines vision, motion, and sound detection
    ET-SoC-1 Chip Esperanto Technology Built on RISC-V for AI and non-AI workloads
    NeuRRAM CEA–Leti Biologically inspired neuromorphic processor based on resistive RAM (RRAM)

    These chips or AI accelerators show different ways to make devices more efficient, use less power, and run advanced AI tasks.

    Techniques For Optimizing AI Models

    Creating AI models that fit resource-constrained devices often requires combining clever hardware utilization with techniques to make models smaller and more efficient. I’d like to cover a few choice examples of how teams are optimizing AI for increased performance using less energy.

    Meta’s MobileLLM

    Meta’s approach to ODAI introduced a model built specifically for smartphones. Instead of scaling traditional models, they designed MobileLLM from scratch to balance efficiency and performance. One key innovation was increasing the number of smaller layers rather than having fewer large ones. This design choice improved the model’s accuracy and speed while keeping it lightweight. You can try out the model either on Hugging Face or using vLLM, a library for LLM inference and serving.

    Quantization

    This simplifies a model’s internal calculations by using lower-precision numbers, such as 8-bit integers, instead of 32-bit floating-point numbers. Quantization significantly reduces memory requirements and computation costs, often with minimal impact on model accuracy.

    Pruning

    Neural networks contain many weights (connections between neurons), but not all are crucial. Pruning identifies and removes less important weights, resulting in a smaller, faster model without significant accuracy loss.

    Matrix Decomposition

    Large matrices are a core component of AI models. Matrix decomposition splits these into smaller matrices, reducing computational complexity while approximating the original model’s behavior.

    Knowledge Distillation

    This technique involves training a smaller model (the “student”) to mimic the outputs of a larger, pre-trained model (the “teacher”). The smaller model learns to replicate the teacher’s behavior, achieving similar accuracy while being more efficient. For instance, DistilBERT successfully reduced BERT’s size by 40% while retaining 97% of its performance.

    Technologies Used For On-Device AI

    Well, all the model compression techniques and specialized chips are cool because they’re what make ODAI possible. But what’s even more interesting for us as developers is actually putting these tools to work. This section covers some of the key technologies and frameworks that make ODAI accessible.

    MediaPipe Solutions

    MediaPipe Solutions is a developer toolkit for adding AI-powered features to apps and devices. It offers cross-platform, customizable tools that are optimized for running AI locally, from real-time video analysis to natural language processing.

    At the heart of MediaPipe Solutions is MediaPipe Tasks, a core library that lets developers deploy ML solutions with minimal code. It’s designed for platforms like Android, Python, and Web/JavaScript, so you can easily integrate AI into a wide range of applications.

    MediaPipe also provides various specialized tasks for different AI needs:

    • LLM Inference API
      This API runs lightweight large language models (LLMs) entirely on-device for tasks like text generation and summarization. It supports several open models like Gemma and external options like Phi-2.
    • Object Detection
      The tool helps you Identify and locate objects in images or videos, which is ideal for real-time applications like detecting animals, people, or objects right on the device.
    • Image Segmentation
      MediaPipe can also segment images, such as isolating a person from the background in a video feed, allowing it to separate objects in both single images (like photos) and continuous video streams (like live video or recorded footage).

    LiteRT

    LiteRT or Lite Runtime (previously called TensorFlow Lite) is a lightweight and high-performance runtime designed for ODAI. It supports running pre-trained models or converting TensorFlow, PyTorch, and JAX models to a LiteRT-compatible format using AI Edge tools.

    Model Explorer

    Model Explorer is a visualization tool that helps you analyze machine learning models and graphs. It simplifies the process of preparing these models for on-device AI deployment, letting you understand the structure of your models and fine-tune them for better performance.

    You can use Model Explorer locally or in Colab for testing and experimenting.

    ExecuTorch

    If you’re familiar with PyTorch, ExecuTorch makes it easy to deploy models to mobile, wearables, and edge devices. It’s part of the PyTorch Edge ecosystem, which supports building AI experiences for edge devices like embedded systems and microcontrollers.

    Large Language Models For On-Device AI

    Gemini is a powerful AI model that doesn’t just excel in processing text or images. It can also handle multiple types of data seamlessly. The best part? It’s designed to work right on your devices.

    For on-device use, there’s Gemini Nano, a lightweight version of the model. It’s built to perform efficiently while keeping everything private.

    What can Gemini Nano do?

    • Call Notes on Pixel devices
      This feature creates private summaries and transcripts of conversations. It works entirely on-device, ensuring privacy for everyone involved.
    • Pixel Recorder app
      With the help of Gemini Nano and AICore, the app provides an on-device summarization feature, making it easy to extract key points from recordings.
    • TalkBack
      Enhances the accessibility feature on Android phones by providing clear descriptions of images, thanks to Nano’s multimodal capabilities.

    Note: It’s similar to an application we built using LLaVA in a previous article.

    Gemini Nano is far from the only language model designed specifically for ODAI. I’ve collected a few others that are worth mentioning:

    Model Developer Research Paper
    Octopus v2 NexaAI On-device language model for super agent
    OpenELM Apple ML Research A significant large language model integrated within iOS to enhance application functionalities
    Ferret-v2 Apple Ferret-v2 significantly improves upon its predecessor, introducing enhanced visual processing capabilities and an advanced training regimen
    MiniCPM Tsinghua University A GPT-4V Level Multimodal LLM on Your Phone
    Phi-3 Microsoft Phi-3 Technical Report: A Highly Capable Language Model Locally on Your Phone

    The Trade-Offs of Using On-Device AI

    Building AI into devices can be exciting and practical, but it’s not without its challenges. While you may get a lightweight, private solution for your app, there are a few compromises along the way. Here’s a look at some of them:

    Limited Resources

    Phones, wearables, and similar devices don’t have the same computing power as larger machines. This means AI models must fit within limited storage and memory while running efficiently. Additionally, running AI can drain the battery, so the models need to be optimized to balance power usage and performance.

    Data and Updates

    AI in devices like drones, self-driving cars, and other similar devices process data quickly, using sensors or lidar to make decisions. However, these models or the system itself don’t usually get real-time updates or additional training unless they are connected to the cloud. Without these updates and regular model training, the system may struggle with new situations.

    Biases

    Biases in training data are a common challenge in AI, and ODAI models are no exception. These biases can lead to unfair decisions or errors, like misidentifying people. For ODAI, keeping these models fair and reliable means not only addressing these biases during training but also ensuring the solutions work efficiently within the device’s constraints.

    These aren’t the only challenges of on-device AI. It’s still a new and growing technology, and the small number of professionals in the field makes it harder to implement.

    Conclusion

    Choosing between on-device and cloud-based AI comes down to what your application needs most. Here’s a quick comparison to make things clear:

    Aspect On-Device AI Cloud-Based AI
    Privacy Data stays on the device, ensuring privacy. Data is sent to the cloud, raising potential privacy concerns.
    Latency Processes instantly with no delay. Relies on internet speed, which can introduce delays.
    Connectivity Works offline, making it reliable in any setting. Requires a stable internet connection.
    Processing Power Limited by device hardware. Leverages the power of cloud servers for complex tasks.
    Cost No ongoing server expenses. Can incur continuous cloud infrastructure costs.

    For apps that need fast processing and strong privacy, ODAI is the way to go. On the other hand, cloud-based AI is better when you need more computing power and frequent updates. The choice depends on your project’s needs and what matters most to you.

  • The Role Of Illustration Style In Visual Storytelling

    Illustration has been used for 10,000 years. One of the first ever recorded drawings was of a hand silhouette found in Spain, that is more than 66,000 years old. Fast forward to the introduction of the internet, around 1997, illustration has gradually increased in use. Popular examples of this are Google’s daily doodles and the Red Bull energy drink, both of which use funny cartoon illustrations and animations to great effect.

    Typically, illustration was done using pencils, chalk, pens, etchings, and paints. But now everything is possible — you can do both analog and digital or mixed media styles.

    As an example, although photography might be the most popular method to communicate visuals, it is not automatically the best default solution. Illustration offers a wider range of styles that help companies engage and communicate with their audience. Good illustrations create a mood and bring to life ideas and concepts from the text. To put it another way, visualisation.

    Good illustrations can also help give life to information in a better way than just using text, numbers, or tables.

    How do we determine what kind of illustration or style would be best? How should illustration complement or echo your corporate identity? What will your main audience prefer? What about the content, what would suit and highlight the content best, and how would it work for the age range it is primarily for?

    Before we dive into the examples, let’s discuss the qualities of good illustration and the importance of understanding your audience. The rubric below will help you make good choices for your audience’s benefit.

    What Makes A Good Illustration

    • Visualises something from the content (something that does not exist or has been described but not visualised).
    • Must be aesthetically pleasing, interesting, and stimulating to look at (needs to have qualities and harmonies between colour, elements, proportions, and subject matter).
    • Must have a feel, mood, dramatic edge, or attitude (needs to create a feeling and describe or bring to life an environment).
    • The illustration should enhance and bring to life what is described in text and word form.
    • Explains or unpacks what is written in any surrounding text and makes it come to life in an unusual and useful way (the illustration should complement and illuminate the content so readers better understand the content).

    Just look at what we are more often than not presented with.

    The importance of knowing about different audiences

    It is really important to know and consider different audiences. Not all of us are the same and have the same physical, cognitive, education, or resources. Our writing, designs, and illustrations need to take into account users’ make-up and capabilities.

    There are some common categories of audiences:

    • Child,
    • Teenager,
    • Middle-aged,
    • Ageing,
    • Prefer a certain style (goth, retro, modern, old fashioned, sporty, branded).

    Below are interesting examples of illustrations, in no particular order, that show how different styles communicate and echo different qualities and affect mood and tone.

    Watercolour

    Good for formal, classy, and sophisticated imagery that also lends itself to imaginative expression. It is a great example of texture and light that delivers a really humane and personal feel that you would not get automatically by using software.

    Strengths

    • Feeling, emotion, and sense of depth and texture.

    Drawing With Real-life objects

    A great option for highly abstract concepts and compositions with a funny, unusual, and unreal aspect. You can do some really striking and clever stuff with this style to engage readers in your content.

    Strengths

    • Conceptual play.

    Surreal Photomontage

    Perfect for abstract hybrid illustration and photo illustration with a surreal fantasy aspect. This is a great example of merging different imagery together to create a really dramatic, scary, and visually arresting new image that fits the musician’s work as well.

    Strengths

    • Conceptual mixing and merging, leading to new unseen imagery.

    Cartoon

    Well-suited for showing fun or humorous aspects, creating concepts with loads of wit and cleverness. New messages and forms of communication can be created with this style.

    Strengths

    • Conceptual.

    Cartoon With Block Colour

    Works well for showing fun, quirky, or humorous aspects and concepts, often with loads of wit and cleverness. The simplicity of style can be quite good for people who struggle with more advanced imagery concepts, making it quite accessible.

    Strengths

    • Simplicity and unclutteredness.

    Clean Vector

    Designed for clean and clear illustrations that are all-encompassing and durable. Due to the nature of this illustration style, it works quite well for a wide range of people as it is not overly stylistic in one direction or another.

    Strengths

    • Realism, conceptual, and widely pleasing.

    Textured Vintage Clean Vector

    Best suited for imagining rustic imagery, echoing a vintage feel. This a great example of how texture and non-cleanliness can create and enhance the feeling of the imagery; it is very Western and old-fashioned, perfect for the core meaning of the illustration.

    Strengths

    • Aged feeling and rough impression.

    Pictogram

    Highly effective for clean, legible, quickly recognizable imagery and concepts, especially at small sizes as well. It is no surprise that many pictograms are to be seen in quick viewing environments such as airports and show imagery that has to work for a wide range of people.

    Strengths

    • Legibility, speed of comprehension (accessibility).

    Abstract Geometric

    A great option for visually attractive and abstract imagery and concepts. This style lends itself to much customising and experimentation from the illustrator, giving some really cool and visually striking results.

    Strengths

    • Visual stimulation and curiosity.

    Lithography Etching

    Ideal for imagery that has an old, historic, and traditional feel. Has a great feel achieved through sketchy markings, etchings, and a greyscale colour palette. You would not automatically get this from software, but given the right context or maybe an unusual juxtaposed context (like the clash against a modern, clean, fashionable corporate identity), it could work really well.

    Strengths

    • Realism and old tradition.

    3D gradient

    It serves as a great choice for highly realistic illustration with a friendly, widely accessible character element. This style is not overly stylistic and lends itself to being accepted by a wider range of people.

    Strengths

    • Widely acceptable and appropriate.

    Sci-fi Comic Book And Pop Art

    It’s especially useful for high-impact, bright, animated, and colourful concepts. Some really cool, almost animated graphic communication can be created with this style, which can also be put to much humorous use. The boldness and in-your-face style promote visual engagement.

    Strengths

    • Animation.

    Tatoo

    Well-suited for bold block-coloured silhouettes and imagery. It is so bold and impactful, and there is still loads of detail there, creating a really cool and sharp illustration. The illustration works well in black and white and would be further enhanced with colour.

    Strengths

    • Directness and clarity.

    Pencil

    Perfect for humane, detailed imagery with plenty of feeling and character. The sketchy style highlights unusual details and lends itself to an imaginative feeling and imagery.

    Strengths

    • Humane and detailed imaginative feeling.

    Gradient

    Especially useful for highly imaginative and fantasy imagery. By using gradients and a light-to-dark color palette, the imagery really has depth and says, ‘Take me away on a journey.’

    Strengths

    • Fantasy (through depth of colour) and clean feeling.

    Charcoal

    It makes an excellent option for giving illustration a humane and tangible feel, with echoes of old historical illustrations. The murky black-and-white illustration really has an atmosphere to it.

    Strengths

    • Humane and detailed feeling.

    Woodcut

    It offers great value for block silhouette imagery that has presence, sharpness, and impact. Is colour even needed? The black against the light background goes a long way to communicating the imagery.

    Strengths

    • Striking and clear.

    Fashion

    A great option for imagery that has motion and flare to it, with a slight feminine feel. No wonder this style of illustration is used for fashion illustrations, great for expressing lines and colours with motion, and has a real fashion runway flare.

    Strengths

    • Motion and expressive flare.

    Caricature

    Ideal for humorous imagery and illustration with a graphic edge and clarity. The layering of light and dark elements really creates an illustration with depth, perfect for playing with the detail of the character, not something you would automatically get from a clean vector illustration. It has received more thought and attention than clean vector illustration typically does.

    Strengths

    • Detail and humour.

    Paint

    It serves as a great choice for traditional romantic imagery that has loads of detail, texture, and depth of feeling. The rose flowers are a good example of this illustration style because they have so much detail and colour shades.

    Strengths

    • Tradition and emotions.

    Chalk

    Well-suited for highly sketchy imagery to make something an idea or working concept. The white lines against the black background have an almost animated effect and give the illustrations real movement and life. This style is a good example of using pure lines in illustration but to great effect.

    Strengths

    • Hand-realised and animation.

    Illustration Sample Card

    How To Start Doing Illustration

    There are plenty of options, such as using pencils, chalk, pens, etchings, and paints, then possibly scanning in. You can also use software like Illustrator, Photoshop, Procreate, Corel Painter, Sketch, Inkscape, or Figma. But no matter what tools you choose, there’s one essential ingredient you’ll always need, and that is a mind and vision for illustration.

    Recommended Resources

  • Solo Development: Learning To Let Go Of Perfection

    As expected from anyone who has ever tried building anything solo, my goal was not to build an app but the app — the one app that’s so good you wonder how you ever survived without it. I had everything in place: wireframes, a to-do list, project structure — you name it. Then I started building. Just not the product. I started with the landing page for it, which took me four days, and I hadn’t even touched the app’s core features yet. The idea itself was so good I had to start marketing it right away!

    I found myself making every detail perfect: every color, shadow, gradient, font size, margin, and padding had to be spot on. I don’t even want to say how long the logo took.

    Spoiler:
    No one cares about your logo.

    Why did I get so stuck on something that was never even part of the core app I wanted so badly to build? Why wasn’t I nagging myself to move on when I clearly needed to?

    The reality of solo development is that there is no one to tell you when to stop or simply say, “Yo, this is good enough! Move on.“ Most users don’t care whether a login button is yellow or green. What they want (and need) is a button that works and solves their problem when clicking it.

    Test Early And Often

    Unnecessary tweaks, indecisive UI decisions, and perfectionism are the core reasons I spend more time on things than necessary.

    Like most solo developers, I also started with the hope of pushing out builds with the efficiency of a large-scale team. But it is easier said than done.

    When building solo, you start coding, then you maybe notice a design flaw, and you switch to fixing it, then a bug appears, and you try fixing that, and voilà — the day is gone. There comes a time when it hits you that, “You know what? It’s time to build messy.” That’s when good intentions of project and product management go out the window, and that’s when I find myself working by the seat of my pants rather than plowing forward with defined goals and actionable tasks that are based on good UI/UX principles, like storyboards, user personas, and basic prioritization.

    This realization is something you have to experience to grasp fully. The trick I’ve learned is to focus on getting something out there for people to see and then work on actual feedback. In other words,

    It’s more important to get the idea out there and iterate on it than reaching for perfection right out of the gate.

    Because guess what? Even if you have the greatest app idea in the world, you’re never going to make it perfect until you start receiving feedback on it. You’re no mind reader — as much as we all want to be one — and some insights (often the most relevant) can only be received through real user feedback and analytics. Sure, your early assumptions may be correct, but how do you know until you ship them and start evaluating them?

    Nowadays, I like to tell others (and myself) to work from hypotheses instead of absolutes. Make an assertion, describe how you intend to test it, and then ship it. With that, you can gather relevant insights that you can use to get closer to perfection — whatever that is.

    Strength In Recognizing Weakness

    Let’s be real: Building a full application on your own is not an easy feat. I’d say it’s like trying to build a house by yourself; it seems doable, but the reality is that it takes a lot more hands than the ones you have to make it happen. And not only to make it happen but to make it happen well.

    There’s only so much one person can do, and admitting your strengths and weaknesses up-front will serve you well by avoiding the trap that you can do it all alone.

    I once attempted to build a project management app alone. I knew it might be difficult, but I was confident. Within a few days, this “simple” project grew legs and expanded with new features like team collaboration, analytics, time tracking, and custom reports being added, many of which I was super excited to make.

    Building a full app takes a lot of time. Think about it; you’re doing the work of a team all alone without any help. There’s no one to provide you with design assets, content, or back-end development. No stakeholder to “swoop and poop” on your ideas (which might be a good thing). Every decision, every line of code, and every design element is 100% on you alone.

    It is technically possible to build a full-featured app solo, but when you think about it, there’s a reason why the concept of MVP exists. Take Instagram, for example; it wasn’t launched with reels, stories, creator’s insights, and so on. It started with one simple thing: photo sharing.

    All I’m trying to say is start small, launch, and let users guide the evolution of the product. And if you can recruit more hands to help, that would be even better. Just remember to leverage your strengths and reinforce your weaknesses by leaning on other people’s strengths.

    Yes, Think Like an MVP

    The concept of a minimum viable product (MVP) has always been fascinating to me. In its simplest form, it means building the basic version of your idea that technically works and getting it in front of users. Yes, this is such a straightforward and widely distributed tip, but it’s still one of the hardest principles for solo developers to follow, particularly for me.

    I mentioned earlier that my “genius” app idea grew legs. And lots of them. I had more ideas than I knew what to do with, and I hadn’t even written a reasonable amount of code! Sure, this app could be enhanced to support face ID, dark mode, advanced security, real-time results, and a bunch of other features. But all these could take months of development for an app that you’re not even certain users want.

    I’ve learned to ask myself: “What would this project look like if it was easy to build?”. It’s so surreal how the answer almost always aligns with what users want. If you can distill your grand idea into a single indispensable idea that does one or two things extremely well, I think you’ll find — as I have — that the final result is laser-focused on solving real user problems.

    Ship the simplest version first. Dark mode can wait. All you need is a well-defined idea, a hypothesis to test, and a functional prototype to validate that hypothesis; anything else is probably noise.

    Handle Imperfection Gracefully

    You may have heard about the “Ship it Fast” approach to development and instantly recognize the parallels between it and what I’ve discussed so far. In a sense, “Ship it Fast” is ultimately another way of describing an MVP: get the idea out fast and iterate on it just as quickly.

    Some might disagree with the ship-fast approach and consider it reckless and unprofessional, which is understandable because, as developers, we care deeply about the quality of our work. However,

    The ship-fast mentality is not to ignore quality but to push something out ASAP and learn from real user experiences. Ship it now — perfect it later.

    That’s why I like to tell other developers that shipping an MVP is the safest, most professional way to approach development. It forces you to stay in scope and on task without succumbing to your whimsies. I even go so far as to make myself swear an “Oath of Focus” at the start of every project.

    I, Vayo, hereby solemnly swear (with one hand on this design blueprint) to make no changes, no additions, and no extra features until this app is fully built in all its MVP glory. I pledge to avoid the temptations of endless tweaking and the thoughts of “just one more feature.”

    Only when a completed prototype is achieved will I consider any new features, enhancements, or tweaks.

    Signed,
    Vayo, Keeper of the MVP

    Remember, there’s no one there to hold you accountable when you develop on your own. Taking a brief moment to pause and accepting that my first version won’t be flawless helps put me in the right headspace early in the project.

    Prioritize What Matters

    I have noticed that no matter what I build, there’s always going to be bugs. Always. If Google still has bugs in the Google Notes app, trust me, then it’s fine for a solo developer to accept that bugs will always be a part of any project.

    Look at flaky tests. For instance, you could run a test over 1,000 times and get all greens, and then the next day, you run the same test, an error shows. It’s just the nature of software development. And for the case of endlessly adding features, it never ends either. There’s always going to be a new feature that you’re excited about. The challenge is to curb some of that enthusiasm and shelve it responsibly for a later time when it makes sense to work on it.

    I’ve learned to categorize bugs and features into two types: intrusive and non-intrusive. Intrusive are those things that prevent projects from functioning properly until fixed, like crashes and serious errors. The non-intrusive items are silent ones. Sure, they should be fixed, but the product will work just fine and won’t prevent users from getting value if they aren’t addressed right away.

    You may want to categorize your bugs and features in other ways, and I’ve seen plenty of other examples, including:

    • High value, low value;
    • High effort, low effort;
    • High-cost, low-cost;
    • Need to have, nice to have.

    I’ve even seen developers and teams use these categorizations to create some fancy priority “score” that considers each category. Whatever it is that helps you stay focused and on-task is going to be the right approach for you more than what specific category you use.

    Live With Your Stack

    Here’s a classic conundrum in development circles:

    Should I use React? Or NextJS? Or wait, how about Vue? I heard it’s more optimized. But hold on, I read that React Redux is dead and that Zustand is the new hot tool.

    And just like that, you’ve spent an entire day thinking about nothing but the tech stack you’re using to build the darn thing.

    We all know that an average user could care less about the tech stack under the hood. Go ahead and ask your mom what tech stack WhatsApp is built on, and let me know what she says. Most times, it’s just us who obsesses about tech stacks, and that usually only happens when we’re asked to check under the hood.

    I have come to accept that there will always be new tech stacks released every single day with the promise of 50% performance and 10% less code. That new tool might scale better, but do I actually have a scaling problem with my current number of zero users? Probably not.

    My advice:

    Pick the tools you work with best and stick to those tools until they start working against you.

    There’s no use fighting something early if something you already know and use gets the job done. Basically, don’t prematurely optimize or constantly chase the latest shiny object.

    Do Design Before The First Line of Code

    I know lots of solo developers out there suck at design, and I’m probably among the top 50. My design process has traditionally been to open VS Code, create a new project, and start building the idea in whatever way comes to mind. No design assets, comps, or wireframes to work with — just pure, unstructured improvisation. That’s not a good idea, and it’s a habit I’m actively trying to break.

    These days, I make sure to have a blueprint of what I’m building before I start writing code. Once I have that, I make sure to follow through and not change anything to respect my “Oath of Focus.”

    I like how many teams call comps and wireframes “project artifacts.” They are pieces of evidence that provide a source of truth for how something looks and works. You might be the sort of person who works better with sets of requirements, and that’s totally fine. But having some sort of documentation that you can point back to in your work is like having a turn-by-turn navigation on a long road trip — it’s indispensable for getting where you need to go.

    And what if you’re like me and don’t pride yourself on being the best designer? That’s another opportunity to admit your weaknesses up-front and recruit help from someone with those strengths. That way, you can articulate the goal and focus on what you’re good at.

    Give Yourself Timelines

    Personally, without deadlines, I’m almost unstoppable at procrastinating. I’ve started setting time limits when building any project, as it helps with procrastination and makes sure something is pushed out at a specified time. Although this won’t work without accountability, I feel the two work hand in hand.

    I set a 2–3 week deadline to build a project. And no matter what, as soon as that time is up, I must post or share the work in its current state on my socials. Because of this, I’m not in my comfort zone anymore because I won’t want to share a half-baked project with the public; I’m conditioned to work faster and get it all done. It’s interesting to see the length of time you can go if you can trick your brain.

    I realize that this is an extreme constraint, and it may not work for you. I’m just the kind of person who needs to know what my boundaries are. Setting deadlines and respecting them makes me a more disciplined developer. More than that, it makes me work efficiently because I stop overthinking things when I know I have a fixed amount of time, and that leads to faster builds.

    Conclusion

    The best and worst thing about solo development is the “solo” part. There’s a lot of freedom in working alone, and that freedom can be inspiring. However, all that freedom can be intoxicating, and if left unchecked, it becomes a debilitating hindrance to productivity and progress. That’s a good reason why solo development isn’t for everyone. Some folks will respond a lot better to a team environment.

    But if you are a solo developer, then I hope my personal experiences are helpful to you. I’ve had to look hard at myself in the mirror many days to come to realize that I am not a perfect developer who can build the “perfect” app alone. It takes planning, discipline, and humility to make anything, especially the right app that does exactly the right thing.

    Ideas are cheap and easy, but stepping out of our freedom and adding our own constraints based on progress over perfection is the secret sauce that keeps us moving and spending our time on those essential things.

    Further Reading On SmashingMag

  • Tight Mode: Why Browsers Produce Different Performance Results

    This article is a sponsored by DebugBear

    I was chatting with DebugBear’s Matt Zeunert and, in the process, he casually mentioned this thing called Tight Mode when describing how browsers fetch and prioritize resources. I wanted to nod along like I knew what he was talking about but ultimately had to ask: What the heck is “Tight” mode?

    What I got back were two artifacts, one of them being the following video of Akamai web performance expert Robin Marx speaking at We Love Speed in France a few weeks ago:

    Tight Mode discriminates resources, taking anything and everything marked as High and Medium priority. Everything else is constrained and left on the outside, looking in until the body is firmly attached to the document, signaling that blocking scripts have been executed. It’s at that point that resources marked with Low priority are allowed in the door during the second phase of loading.

    There’s a big caveat to that, but we’ll get there. The important thing to note is that…

    Chrome And Safari Enforce Tight Mode

    Yes, both Chrome and Safari have some working form of Tight Mode running in the background. That last image illustrates Chrome’s Tight Mode. Let’s look at Safari’s next and compare the two.

    Look at that! Safari discriminates High-priority resources in its initial fetch, just like Chrome, but we get wildly different loading behavior between the two browsers. Notice how Safari appears to exclude the first five PNG images marked with Medium priority where Chrome allows them. In other words, Safari makes all Medium- and Low-priority resources wait in line until all High-priority items are done loading, even though we’re working with the exact same HTML. You might say that Safari’s behavior makes the most sense, as you can see in that last image that Chrome seemingly excludes some High-priority resources out of Tight Mode. There’s clearly some tomfoolery happening there that we’ll get to.

    Where’s Firefox in all this? It doesn’t take any extra tightening measures when evaluating the priority of the resources on a page. We might consider this the “classic” waterfall approach to fetching and loading resources.

    Chrome And Safari Trigger Tight Mode Differently

    Robin makes this clear as day in his talk. Chrome and Safari are both Tight Mode proponents, yet trigger it under differing circumstances that we can outline like this:

    Chrome Safari
    Tight Mode triggered While blocking JS in the <head> is busy. While blocking JS or CSS anywhere is busy.

    Notice that Chrome only looks at the document <head> when prioritizing resources, and only when it involves JavaScript. Safari, meanwhile, also looks at JavaScript, but CSS as well, and anywhere those things might be located in the document — regardless of whether it’s in the <head> or <body>. That helps explain why Chrome excludes images marked as High priority in Figure 2 from its Tight Mode implementation — it only cares about JavaScript in this context.

    So, even if Chrome encounters a script file with fetchpriority="high" in the document body, the file is not considered a “High” priority and it will be loaded after the rest of the items. Safari, meanwhile, honors fetchpriority anywhere in the document. This helps explain why Chrome leaves two scripts on the table, so to speak, in Figure 2, while Safari appears to load them during Tight Mode.

    That’s not to say Safari isn’t doing anything weird in its process. Given the following markup:

    <head>
      <!-- two high-priority scripts -->
      <script src="script-1.js"></script>
      <script src="script-1.js"></script>
    
      <!-- two low-priority scripts -->
      <script src="script-3.js" defer></script>
      <script src="script-4.js" defer></script>
    </head>
    <body>
      <!-- five low-priority scripts -->
      <img src="image-1.jpg">
      <img src="image-2.jpg">
      <img src="image-3.jpg">
      <img src="image-4.jpg">
      <img src="image-5.jpg">
    </body>
    

    …you might expect that Safari would delay the two Low-priority scripts in the <head> until the five images in the <body> are downloaded. But that’s not the case. Instead, Safari loads those two scripts during its version of Tight Mode.

    Chrome And Safari Exceptions

    I mentioned earlier that Low-priority resources are loaded in during the second phase of loading after Tight Mode has been completed. But I also mentioned that there’s a big caveat to that behavior. Let’s touch on that now.

    According to Patrick’s article, we know that Tight Mode is “the initial phase and constraints loading lower-priority resources until the body is attached to the document (essentially, after all blocking scripts in the head have been executed).” But there’s a second part to that definition that I left out:

    “In tight mode, low-priority resources are only loaded if there are less than two in-flight requests at the time that they are discovered.”

    A-ha! So, there is a way for low-priority resources to load in Tight Mode. It’s when there are less than two “in-flight” requests happening when they’re detected.

    Wait, what does “in-flight” even mean?

    That’s what’s meant by less than two High- or Medium-priority items being requested. Robin demonstrates this by comparing Chrome to Safari under the same conditions, where there are only two High-priority scripts and ten regular images in the mix:

    <head>
      <!-- two high-priority scripts -->
      <script src="script-1.js"></script>
      <script src="script-1.js"></script>
    </head>
    <body>
      <!-- ten low-priority images -->
      <img src="image-1.jpg">
      <img src="image-2.jpg">
      <img src="image-3.jpg">
      <img src="image-4.jpg">
      <img src="image-5.jpg">
      <!-- rest of images -->
      <img src="image-10.jpg">
    </body>
    

    Let’s look at what Safari does first because it’s the most straightforward approach:

    Nothing tricky about that, right? The two High-priority scripts are downloaded first and the 10 images flow in right after. Now let’s look at Chrome:

    We have the two High-priority scripts loaded first, as expected. But then Chrome decides to let in the first five images with Medium priority, then excludes the last five images with Low priority. What. The. Heck.

    The reason is a noble one: Chrome wants to load the first five images because, presumably, the Largest Contentful Paint (LCP) is often going to be one of those images and Chrome is hedging bets that the web will be faster overall if it automatically handles some of that logic. Again, it’s a noble line of reasoning, even if it isn’t going to be 100% accurate. It does muddy the waters, though, and makes understanding Tight Mode a lot harder when we see Medium- and Low-priority items treated as High-priority citizens.

    Even muddier is that Chrome appears to only accept up to two Medium-priority resources in this discriminatory process. The rest are marked with Low priority.

    That’s what we mean by “less than two in-flight requests.” If Chrome sees that only one or two items are entering Tight Mode, then it automatically prioritizes up to the first five non-critical images as an LCP optimization effort.

    Truth be told, Safari does something similar, but in a different context. Instead of accepting Low-priority items when there are less than two in-flight requests, Safari accepts both Medium and Low priority in Tight Mode and from anywhere in the document regardless of whether they are located in the <head> or not. The exception is any asynchronous or deferred script because, as we saw earlier, those get loaded right away anyway.

    How To Manipulate Tight Mode

    This might make for a great follow-up article, but this is where I’ll refer you directly to Robin’s video because his first-person research is worth consuming directly. But here’s the gist:

    • We have these high-level features that can help influence priority, including resource hints (i.e., preload and preconnect), the Fetch Priority API, and lazy-loading techniques.
    • We can indicate fetchpriority=`highandfetchpriority=”low”` on items.
    <img src="lcp-image.jpg" fetchpriority="high">
    <link rel="preload" href="defer.js" as="script" fetchpriority="low"
    
    • Using fetchpriority="high" is one way we can get items lower in the source included in Tight Mode. Using fetchpriority="low is one way we can get items higher in the source excluded from Tight Mode.
    • For Chrome, this works on images, asynchronous/deferred scripts, and scripts located at the bottom of the <body>.
    • For Safari, this only works on images.

    Again, watch Robin’s talk for the full story starting around the 28:32 marker.

    That’s Tight… Mode

    It’s bonkers to me that there is so little information about Tight Mode floating around the web. I would expect something like this to be well-documented somewhere, certainly over at Chrome Developers or somewhere similar, but all we have is a lightweight Google Doc and a thorough presentation to paint a picture of how two of the three major browsers fetch and prioritize resources. Let me know if you have additional information that you’ve either published or found — I’d love to include them in the discussion.