<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[ScaleUp - Medium]]></title>
        <description><![CDATA[The Product Development company that turns your startup ideas into reality - Medium]]></description>
        <link>https://medium.com/scaleuptech?source=rss----d455d6fd6cec---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>ScaleUp - Medium</title>
            <link>https://medium.com/scaleuptech?source=rss----d455d6fd6cec---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 12 Nov 2026 19:49:58 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/scaleuptech" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[10 React Native Mistakes I Stopped Making After 5 Years]]></title>
            <link>https://medium.com/scaleuptech/10-react-native-mistakes-i-stopped-making-after-5-years-5a0929e8ab84?source=rss----d455d6fd6cec---4</link>
            <guid isPermaLink="false">https://medium.com/p/5a0929e8ab84</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[react-native]]></category>
            <dc:creator><![CDATA[Sanjin Sehic]]></dc:creator>
            <pubDate>Mon, 27 Jul 2026 13:56:06 GMT</pubDate>
            <atom:updated>2026-07-27T13:56:06.315Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eIGTATBI1wqLbG_gx-qi-A.png" /></figure><p>When I started working with React Native, I thought writing good code meant making it work.</p><p>And to be fair — that’s enough when you’re learning.</p><p>But after spending almost five years building production applications, maintaining large codebases, fixing performance issues, reviewing pull requests, and debugging bugs that only appeared in production, I realised many of my early habits were actually slowing me down.</p><p>Here are ten mistakes I used to make — and what I do instead today.</p><h3>1. Creating Components That Did Too Much</h3><p>One of my first habits was creating huge components.</p><p>A single screen would contain:</p><ul><li>API calls</li><li>State management</li><li>Business logic</li><li>UI</li><li>Navigation</li><li>Validation</li><li>Animations</li></ul><p>Everything lived in one file.</p><p>It worked… until it didn’t.</p><p>Large components quickly become difficult to understand, almost impossible to test, and painful to modify without accidentally breaking something.</p><h3>What I do now</h3><p>I try to give every component one responsibility.</p><p>Business logic moves into hooks.</p><p>Reusable UI becomes separate components.</p><p>Complex calculations become utility functions.</p><p>A screen should mostly describe <strong>what</strong> gets rendered — not <strong>how</strong> everything works behind the scenes.</p><h3>2. Overusing useEffect</h3><p>This is probably the biggest mistake I see — not only in my old code, but in many React applications today.</p><p>I used useEffect for everything.</p><p>Updating state.</p><p>Calculating values.</p><p>Synchronising data.</p><p>Reacting to other state changes.</p><p>Most of these effects weren’t actually side effects.</p><h3>What I do now</h3><p>Before writing a useEffect, I ask one question:</p><blockquote><em>Is this really a side effect?</em></blockquote><p>If something can be calculated during render, I calculate it.</p><p>If it belongs inside an event handler, I keep it there.</p><p>If it comes from props, I avoid duplicating it in state.</p><p>Fewer effects usually mean fewer bugs.</p><h3>3. Premature Optimisation</h3><p>At one point I wrapped almost every component with React.memo.</p><p>Everything. Buttons, Icons, Headers…</p><p>Even components that rendered once.</p><p>I thought more memoisation meant better performance.</p><p>It doesn’t.</p><p>Sometimes it actually makes performance worse.</p><h3>What I do now</h3><p>I profile first.</p><p>If I don’t know what is slow, I don’t optimise it.</p><p>Optimisation should solve an existing problem — not an imaginary one.</p><h3>4. Putting Everything Into Context</h3><p>Context is amazing.</p><p>Until it isn’t.</p><p>Early on I treated Context like a global store.</p><p>Authentication, Theme, Settings, Notifications… Everything.</p><p>Every update caused unrelated components to re-render.</p><h3>What I do now</h3><p>Context is for data that is truly global.</p><p>For everything else, local state is usually the better choice.</p><p>Sometimes the simplest solution is also the fastest one.</p><h3>5. Ignoring FlatList Performance</h3><p>I used to think FlatList handled everything automatically.</p><p>Then I worked on applications displaying hundreds or even thousands of items.</p><p>That’s when performance problems appeared.</p><h3>What I do now</h3><p>I pay attention to:</p><ul><li>stable keyExtractor</li><li>avoiding inline functions</li><li>getItemLayout when possible</li><li>memoised row components</li><li>proper windowSize</li><li>avoiding unnecessary re-renders</li></ul><p>Small improvements here can completely change how an application feels.</p><h3>6. Repeating API Logic Everywhere</h3><p>My early projects looked something like this:</p><pre>try {<br>  const response = await axios.get(...)<br>  ...<br>} catch (error) {<br>  ...<br>}</pre><p>Repeated dozens of times.</p><p>Loading states, Error handling, Authentication…</p><p>Every screen implemented them differently.</p><h3>What I do now</h3><p>API requests live behind reusable abstractions.</p><p>Every request follows the same pattern.</p><p>Authentication, retries, logging and error handling are centralised.</p><p>The screens become dramatically simpler.</p><h3>7. Fear of Native Code</h3><p>For years I avoided touching native Android code.</p><p>I thought:</p><blockquote><em>“I’m a JavaScript developer.”</em></blockquote><p>Eventually I had to build native modules.</p><p>Then another.</p><p>Then another.</p><p>It turned out native code wasn’t nearly as scary as I imagined.</p><h3>What I do now</h3><p>Whenever React Native cannot do something efficiently, I don’t fight the framework.</p><p>Sometimes fifty lines of Kotlin solve what hundreds of lines of JavaScript never could.</p><p>Learning just enough native development made me a much better React Native developer.</p><h3>8. Ignoring Error Reporting</h3><p>During development everything worked perfectly.</p><p>Production was a different story.</p><p>Users reported crashes.</p><p>Nobody knew why.</p><h3>What I do now</h3><p>Crash reporting is one of the first things I configure.</p><p>Knowing <strong>where</strong> an application crashed is infinitely better than guessing.</p><p>Good monitoring saves countless hours of debugging.</p><h3>9. Writing Code for Today Instead of Tomorrow</h3><p>Sometimes I wrote code that solved the current ticket as quickly as possible.</p><p>Then another feature arrived. Then another.</p><p>Soon every change became risky because everything depended on everything else.</p><h3>What I do now</h3><p>I don’t try to predict the future.</p><p>But I do leave the codebase in a slightly better state than I found it.</p><p>Future me is just another developer who deserves readable code.</p><h3>10. Thinking React Native Is “Just React”</h3><p>React Native uses React.</p><p>But mobile development introduces an entirely different set of challenges.</p><p>Memory, Offline behaviour, Permissions, Animations, App lifecycle, Background execution, Native limitations, Battery consumption, Platform differences…</p><p>Once I stopped treating mobile like a website, I started building much better applications.</p><h3>Final Thoughts</h3><p>Looking back, none of these mistakes were “bad.”</p><p>They were simply part of the learning process.</p><p>Every project taught me something new.</p><p>Every production bug made me rethink how I approached architecture.</p><p>And every difficult feature forced me to become a better engineer.</p><p>If you’re just starting with React Native, you’ll probably make some of these mistakes too.</p><p>That’s okay.</p><p>The important part isn’t avoiding every mistake — it’s recognising them early and continuously improving.</p><p>Five years from now, you’ll probably look back at the code you’re writing today and smile.</p><p>I know I do.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5a0929e8ab84" width="1" height="1" alt=""><hr><p><a href="https://medium.com/scaleuptech/10-react-native-mistakes-i-stopped-making-after-5-years-5a0929e8ab84">10 React Native Mistakes I Stopped Making After 5 Years</a> was originally published in <a href="https://medium.com/scaleuptech">ScaleUp</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React Native Optimization Playbook: What Every Developer Should Know]]></title>
            <link>https://medium.com/scaleuptech/react-native-optimization-playbook-what-every-developer-should-know-dec233702a4a?source=rss----d455d6fd6cec---4</link>
            <guid isPermaLink="false">https://medium.com/p/dec233702a4a</guid>
            <category><![CDATA[optimization]]></category>
            <category><![CDATA[react-native]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Sanjin Sehic]]></dc:creator>
            <pubDate>Tue, 18 Nov 2025 08:32:04 GMT</pubDate>
            <atom:updated>2025-11-18T08:32:03.089Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4gXZXfrHcPLJGVum1AWgCA.png" /></figure><p>If there’s one topic that every React Native developer struggles with at some point, it’s performance. The framework gives you a huge amount of flexibility — but also enough room to shoot yourself in the foot. Most performance issues aren’t caused by React Native itself, but by the way we structure components, handle state, load images, or manage the JavaScript thread.</p><p>The good news? Almost all performance bottlenecks have predictable causes and proven fixes. In this article, I’ll walk you through the techniques I’ve learned (and painfully discovered) over the years — practical tips that you can apply <strong>today</strong> to make your app smoother, faster, and more stable.</p><p>Let’s dive into the optimization playbook.</p><h3>Use Memoization the Right Way</h3><p>One of the biggest hidden performance killers is unnecessary re-renders. Even lightweight components can cause noticeable UI lag if they render hundreds of times due to parent updates.</p><p>Memoization helps — <strong>when used correctly</strong>.</p><h4>How to improve performance:</h4><ul><li><strong>React.memo</strong> prevents re-renders when props haven’t changed.</li><li><strong>useCallback</strong> ensures stable function references.</li><li><strong>useMemo</strong> caches expensive calculations.</li></ul><h4>Common mistake:</h4><p>Wrapping <em>everything</em> in memoization. This often increases complexity without real gains. Focus on:</p><ul><li>large components</li><li>heavy lists</li><li>components with expensive logic</li></ul><h3>Virtualize Long Lists (Stop Using ScrollView for 200+ Items)</h3><p>You’ll find this mistake everywhere: rendering large datasets inside ScrollView.<br> This forces React Native to mount every item at once—instant performance disaster.</p><h4>Use instead:</h4><ul><li>FlatList</li><li>SectionList</li><li>VirtualizedList</li></ul><p>These only render what’s visible on screen and recycle views as you scroll.</p><h4>Bonus optimizations:</h4><ul><li>set initialNumToRender thoughtfully</li><li>avoid inline functions/styles</li><li>use keyExtractor</li><li>enable getItemLayout when item height is fixed</li></ul><p>A well-optimized FlatList can turn a choppy list into a buttery smooth experience.</p><h3>Avoid Inline Functions and Objects in JSX</h3><p>Inline functions and object literals are created on <em>every</em> render, causing child components to rerender even when nothing changed.</p><h4>Bad example:</h4><pre>&lt;View style={{ padding: 10 }} onPress={() =&gt; handlePress(item)}&gt;</pre><h4>Good example:</h4><pre>const styles = { container: { padding: 10 } };<br>const onPress = useCallback(() =&gt; handlePress(item), [item]);</pre><p>This small change, applied consistently, can dramatically reduce unnecessary renders — especially in lists.</p><h3>Optimize Images (Caching, Resizing, Lazy Loading)</h3><p>Images are one of the biggest sources of performance issues in mobile apps.</p><h4>Key strategies:</h4><ul><li>Use react-native-fast-image for caching and smarter loading.</li><li>Compress images before bundling them.</li><li>Avoid using huge images where thumbnails would work.</li><li>Lazy-load off-screen images (especially in carousels and product lists).</li></ul><p>A single unoptimized image can slow down your app more than all JavaScript logic combined.</p><h3>Use Reanimated for Smooth Animations</h3><p>React Native’s built-in Animated library runs many calculations on the JS thread—fine for simple fades, but not enough for complex interactions.</p><p>react-native-reanimated moves animations to the UI thread. This results in:</p><ul><li>smoother gestures</li><li>consistent FPS</li><li>better interactions on low-end Android devices</li></ul><p>If you’re building anything with drag-and-drop, shared transitions, or gesture-heavy UI, Reanimated is a must.</p><h3>Optimize Navigation with the Right Navigator</h3><p>Navigation libraries can have different performance characteristics.</p><h4>Two tips:</h4><ul><li>Use <strong>createNativeStackNavigator</strong> (faster because it uses native views).</li><li>Use <strong>lazy</strong> or <strong>unmountOnBlur</strong> to avoid loading unnecessary screens.</li></ul><p>Each screen you leave mounted keeps its component tree alive. Sometimes that’s good — sometimes it’s not. Choose intentionally.</p><h3>Reduce Re-Renders With Better Component Architecture</h3><p>A giant component with 2,000 lines of code is not only hard to maintain — it’s a performance trap.</p><h4>Best practices:</h4><ul><li>Break screens into smaller components.</li><li>Each component manages its own state.</li><li>Keep prop chains shallow.</li></ul><p>This prevents a tiny change (e.g., toggling a boolean) from accidentally causing half the UI to rerender.</p><h3>Reduce Bridge Traffic (Minimize JS ⇄ Native Communication)</h3><p>One of the hidden performance bottlenecks in React Native is the <strong>bridge</strong> — the communication layer between JavaScript and native code. Every time your JS code sends data to native (or vice versa), it adds overhead. Individually these calls are tiny, but in large numbers they can visibly slow down animations, gesture handling, and lists.</p><h4>Common sources of excessive bridge usage:</h4><ul><li>Constantly sending repeated events (e.g., scroll events, sensor data).</li><li>Chatty native modules (e.g., every second sending updates).</li><li>Complex objects being serialized on each bridge call.</li><li>Rapid state updates that trigger multiple renders.</li></ul><h4>How to optimize bridge usage:</h4><ul><li>Batch data instead of sending many small messages.</li><li>Use JSI-based libraries (e.g., Reanimated, MMKV) to avoid the bridge entirely.</li><li>Reduce unnecessary event listeners (especially scroll and gesture listeners).</li></ul><p>By minimizing how often you cross the JS/native boundary, your app becomes smoother — especially on low-end Android devices, where the bridge overhead is more noticeable.</p><h3>Avoid Unnecessary API Calls &amp; Repeated Fetching</h3><h4>Repeated fetches mean:</h4><ul><li>extra re-renders</li><li>more work for JS thread</li><li>slower UI</li></ul><h4>Use caching strategies with:</h4><ul><li>React Query</li><li>SWR</li><li>custom caching hooks</li></ul><p>Smart caching often results in a visibly faster app without even touching component logic.</p><h3>Conclusion: Performance Is Not Magic — It’s Technique</h3><p>React Native is capable of excellent performance, but it rewards developers who understand how rendering works, how threads communicate, and how to structure apps responsibly.</p><p>You don’t need to rewrite everything in native code.<br> You just need the right optimization habits.</p><p>Use this playbook as a checklist, and over time, you’ll start recognizing performance pitfalls before they happen.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=dec233702a4a" width="1" height="1" alt=""><hr><p><a href="https://medium.com/scaleuptech/react-native-optimization-playbook-what-every-developer-should-know-dec233702a4a">React Native Optimization Playbook: What Every Developer Should Know</a> was originally published in <a href="https://medium.com/scaleuptech">ScaleUp</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Startup Series #3— I need to build it]]></title>
            <link>https://medium.com/scaleuptech/startup-series-3-i-need-to-build-it-477fabe7d240?source=rss----d455d6fd6cec---4</link>
            <guid isPermaLink="false">https://medium.com/p/477fabe7d240</guid>
            <category><![CDATA[lean-startup]]></category>
            <category><![CDATA[product-management]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[agile]]></category>
            <category><![CDATA[startup]]></category>
            <dc:creator><![CDATA[Adi Behlulovic]]></dc:creator>
            <pubDate>Fri, 31 Oct 2025 15:41:07 GMT</pubDate>
            <atom:updated>2025-10-31T15:41:03.339Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mtK5WjkWvRMMtVuv_2bq6g.jpeg" /></figure><p>You’ve done the hard part.<br>You validated your idea, confirmed that the problem exists, and proved that your solution can work.</p><p>Now comes the fun (and sometimes scary) part — turning your idea into a real product.</p><h3>Current state: where are you now</h3><p>At this stage, you’ve managed to:</p><ul><li>Validate the idea and the market.</li><li>Validate the problem you assumed existed with your target audience.</li><li>Validate the solution that solves that problem.</li></ul><p>All of this matters because it gives you confidence that you are onto something that can actually work.<br>You’re now sure that you need to build it.</p><p>Let’s go step by step.</p><h3>Defining what to build</h3><p>A lot of founders don’t spend enough time on this part — defining <em>what</em> to build.</p><p>The truth is, not every idea needs a full-scale product right away.<br>Some products can go live half-baked, gather feedback, and grow as you go. Others must be baked to perfection before showing them to users.</p><p>How do you know which path is yours?<br>It mostly depends on <strong>how innovative your idea is</strong>.</p><p>If your product is something new — opening a new market or changing user behavior — it’s usually better to build together with users.<br>Define your core differentiator, build the smallest version that demonstrates it, and collect feedback early.</p><p>On the other hand, if you’re building a product for an existing, saturated market, you might be better off launching only when your core value proposition is fully realized.</p><p>Because in a crowded market, a weak early version can hurt your chances. People already have habits and expectations. To win, you must stand out.</p><p>Examples make this clear:</p><ul><li><strong>Facebook</strong> started with a small group of university users and built its way up into a completely new market.</li><li><strong>Gmail</strong>, however, entered a crowded market but stood out with a sleek interface, large storage, and advanced search.</li></ul><p>Both strategies worked, because they matched the product type.</p><p>Regardless of your case, always keep two evolving lists:<br><strong>Core features</strong> (MVP) and <strong>Future features</strong> (R2, R3…).</p><p>Keep it simple: everything not needed for your first release goes into the second list.<br>Your priorities will evolve as you learn more, but two things will always drive decisions — <strong>time</strong> and <strong>budget</strong>.</p><p>Let’s say you’re building Uber. Your initial feature list might look like this:</p><pre>Feature  | Time | Cost<br>Authentication &amp; Login | 1 week | €2,000<br>Upload Photo | 1 day | €1,000<br>Payment | 2 weeks | €8,000<br>Real-Time Map Updates | 4 weeks | €16,000<br>Messaging | 2 weeks | €10,000</pre><p>At first, all seem essential.</p><p>But once you add time and cost, it’s clear that you might skip real-time map updates and messaging for version one, replacing them with simple notifications like <em>“Your ride is near.”</em></p><p>You get to launch faster, cheaper, and still deliver the core experience.</p><p>Today, AI tools can make this process even faster.<br>From generating wireframes and prototypes to creating user flow simulations or early feedback models, AI helps you define and visualize your MVP before spending a single euro on development.</p><p>👉 <strong>Check out our </strong><a href="https://tools.scaleup.ba/home"><strong>AI Toolkit for Founders</strong></a></p><h3>Choosing the right development approach</h3><p>Once you know what to build, the next big decision is <strong>how</strong> to build it.</p><p>The most common approaches are:</p><ol><li>Hiring an in-house dev team</li><li>Outsourcing development</li><li>A hybrid model</li></ol><p>From our experience at ScaleUp, the <strong>hybrid approach</strong> works best for early-stage founders.</p><p>Here’s why:</p><ul><li>We usually build the first version of the product (the MVP) end-to-end, so founders can move fast and validate early.</li><li>Once the product gains traction or funding is secured, we help the founder bring in a CTO or technical co-founder if needed.</li><li>When that happens, we don’t step away — we reorganize together, keeping our ScaleUp team as an embedded development partner under the founder’s or CTO’s leadership.</li></ul><p>This setup gives founders both speed and continuity: a full team from day one, and long-term technical stability as the product grows.</p><p>👉 <strong>See how we build MVPs</strong> (<a href="https://www.scaleup.ba/build">https://www.scaleup.ba/build</a>)</p><p>Other options that can work depending on context:</p><ul><li>Continue with an interim CTO from the development company.</li><li>Gradually replace the outsourced team with in-house hires.</li><li>Mix in-house and external devs.</li><li>Offer equity-based partnerships where the dev company acts as a technical co-founder.</li></ul><p>Whatever the setup, the key is fit.<br>Startups need small, agile, and flexible teams that can pivot quickly, not enterprise-sized vendors. Look for a team that is comfortable working with startups, can adjust pricing models, and has full-stack capability (design, development, QA, DevOps).</p><p>Avoid managing multiple agencies — it adds unnecessary overhead early on.</p><p>And increasingly, consider <strong>AI-augmented development workflows</strong>.<br>AI copilots can generate boilerplate code, assist with QA, automate documentation, or even help with refactoring. But they don’t replace human alignment. Someone still needs to own the <em>why</em> behind every feature.</p><h3>Building the right team</h3><p>Every successful product starts with the right team setup.</p><p>For early stages, this is the usual minimum:</p><ul><li><strong>Frontend or Full-stack Engineer</strong> — full-time</li><li><strong>Backend or Full-stack Engineer</strong> — full-time</li><li><strong>UI/UX Designer</strong> — part-time or full-time</li></ul><p>Alongside them, you’ll often need:</p><ul><li><strong>Tech Lead</strong> — to guide technical decisions</li><li><strong>Product/Project Manager</strong> — to define features, scope, and timelines</li><li><strong>QA Engineer</strong> — to ensure quality before launch</li></ul><p>As traction grows or funding comes in, you can start thinking about full-time additions. Each startup’s path is unique, so adapt as you go.</p><h3>Development timeline and roadmap</h3><p>Once you have your team and plan, it’s time to set your <strong>timeline and roadmap</strong>.</p><p>This step affects everything else — marketing, sales, investor communication, even your fundraising narrative.</p><p>A common trap here is the <em>never-ending MVP</em>.<br>Founders keep tweaking colors, layouts, or animations instead of shipping.<br>Small details matter, but not more than user feedback.</p><p>Launch. Learn. Iterate.</p><p>It helps to understand the key development phases:</p><ul><li><strong>Wireframe</strong> — low-fidelity blueprint for structure and flows</li><li><strong>Prototype</strong> — interactive mockup showing key interactions</li><li><strong>POC (Proof of Concept)</strong> — small-scale technical validation</li><li><strong>MVP (Minimum Viable Product)</strong> — functional version with core differentiator</li><li><strong>Future Releases (R2, R3)</strong> — subsequent iterations after MVP</li><li><strong>Alpha/Beta</strong> — early testing phases before public launch</li><li><strong>PMF (Product-Market Fit)</strong> — when the product sustains itself financially</li></ul><p>Forget buzzwords like “Minimum Loveable Product” — focus on delivering real value, not new acronyms.</p><h3>Agile development and rapid iteration</h3><p>Building doesn’t stop when you launch.<br>Each milestone is the start of another, usually more important, journey.</p><p>Once your MVP is live, your job is to test, learn, and improve fast.</p><p>There are dozens of frameworks out there — Waterfall, Agile, Scrum, Kanban, Lean Startup.<br>But the truth is, your process should serve your goal, not the other way around.</p><p>Most startups benefit from <strong>fast feedback cycles</strong> — a mix of Agile and Lean Startup principles.</p><p>At ScaleUp, we work in two-week iterations, constantly testing ideas in production with real users. Each sprint includes a feedback loop where we assess what worked, what didn’t, and what to improve next.</p><p>👉 <strong>See our process here</strong> (<a href="https://www.scaleup.ba/scale">https://www.scaleup.ba/grow</a>)</p><p>AI plays a growing role here, too. Automated test bots, performance monitoring, and AI-driven analytics can spot bottlenecks long before humans do, allowing you to move faster with confidence.</p><h3>Testing and QA: Don’t ship garbage</h3><p>Testing starts early.<br>As soon as you have something functional, you test it.</p><p>The first round should catch critical bugs before Alpha users ever touch it.<br>Your goal: let testers focus on usability, not broken features.</p><p>Parallel testing should cover:</p><ul><li>Functionality</li><li>UX and UI</li><li>Security</li><li>Performance</li><li>Compatibility</li><li>Compliance (if relevant)</li></ul><p>AI-driven testing tools now make this much easier.<br>They can automatically detect UI issues, missing states, or inconsistent flows before launch — saving you weeks of manual QA.</p><p>Once your Alpha and Beta versions are stable, you’re ready to launch.</p><h3>Prepare for launch</h3><p>Before you hit “Publish”, make sure your analytics are in place.<br>What gets measured gets improved.</p><p>Don’t drown in vanity metrics.<br>Focus on what truly matters for your product’s stage.</p><p>The simplest model to follow is <strong>AARRR (Pirate Metrics):</strong></p><ul><li><strong>Acquisition</strong> — how you attract users</li><li><strong>Activation</strong> — how you onboard them</li><li><strong>Retention</strong> — how you keep them</li><li><strong>Revenue</strong> — how you monetize</li><li><strong>Referral</strong> — how users promote you</li></ul><p>Start from the top and improve each step iteratively.<br>And use AI analytics tools when possible — they can surface insights you’d otherwise miss, from predicting churn to recommending feature priorities.</p><p>These metrics will guide your next steps, help you prioritize new features, and inform your scaling strategy.</p><h3>Wrapping up</h3><p>You’ve built it.<br>You’ve tested it.<br>You’ve launched it.</p><p>Now the real game begins — scaling.</p><p>In the next part of the Startup Series, we’ll talk about what comes next:<br>How to scale your product, grow your user base, and build a company around your idea without losing focus or momentum.</p><h3>About ScaleUp</h3><p>At ScaleUp, we help founders build and scale digital products faster, smarter, and with total ownership. We’ve built over 50 products used by millions of users worldwide. Whether you’re validating your idea or scaling your platform, our embedded teams act as your unfair product advantage.</p><p>👉 <strong>Let’s build together — </strong><a href="https://calendly.com/scaleup-adi/adi-meeting"><strong>Contact Us</strong></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=477fabe7d240" width="1" height="1" alt=""><hr><p><a href="https://medium.com/scaleuptech/startup-series-3-i-need-to-build-it-477fabe7d240">Startup Series #3— I need to build it</a> was originally published in <a href="https://medium.com/scaleuptech">ScaleUp</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Startup Series #2 — I have an idea]]></title>
            <link>https://medium.com/scaleuptech/startup-series-2-i-have-an-idea-f9fbbb588b54?source=rss----d455d6fd6cec---4</link>
            <guid isPermaLink="false">https://medium.com/p/f9fbbb588b54</guid>
            <category><![CDATA[startup]]></category>
            <category><![CDATA[product-development]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[ideas]]></category>
            <category><![CDATA[tech]]></category>
            <dc:creator><![CDATA[Adi Behlulovic]]></dc:creator>
            <pubDate>Fri, 24 Oct 2025 19:23:52 GMT</pubDate>
            <atom:updated>2025-10-24T19:23:27.836Z</atom:updated>
            <content:encoded><![CDATA[<h3>Startup Series #2 — I have an idea</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WjESF46F0GAnDr_Zgc-6Eg.png" /></figure><p>Everything starts with an idea. But always remember this:</p><blockquote>There is nothing so useless as doing efficiently something that should not have been done at all. —<strong> Peter Drucker</strong></blockquote><p>The thing is, it’s not just about the actual idea, but whether we are ready to act on it. That is essentially what entrepreneurship is all about. I bet that every one of us, at one point in our lives, has thought to ourselves — “Damn, this would be an awesome idea,” but only a few of us would actually try to turn the idea into reality.</p><p>What is even more depressing is that only a few of those who actually try will end up creating a successful product (success being a highly relative term). The weird thing is, it’s not merely a question of perseverance (in most cases, at least), but rather a question of knowing when to stop or pivot. That is the hard truth — even if you believe your idea is something the world truly needs, your potential customers may not agree.</p><p>So, the initial question you need to ask yourself is — is the world ready for this product? Are your customers ready for it?</p><p>I intentionally say ‘ready’ because it often happens that the product is indeed needed, but simply it is yet too early for it. In any case, the sooner you get the answer to this question, the better.</p><p>What is meant by ‘sooner the better’ is not solely about timing, as someone may take your idea before you do. It’s more about being fundamentally practical and spending the least amount of money in the shortest possible time frame to prove that your idea will work. How can you achieve this?</p><p>Unfortunately, this is not something that can be templated. The cold truth is, you need to be creative and define your customer segment. Test both the problem and value hypotheses.</p><h3><strong>Define customer segment</strong></h3><p>While this might seem obvious, take a moment to consider: who is your customer segment? For whom are you building your product? It’s okay to be broad and not too specific at this stage, but we should have some understanding so we can decide for whom we are going to build the product.</p><p>Helpful questions:</p><ol><li>Are you going to aim for the B2B or B2C segment?</li><li>In the case of B2C, which age group is likely to use your product the most?</li><li>For B2C, is there any common/shared interest among potential customers of your product?</li><li>For B2C, are you aiming for a specific region/country or worldwide?</li><li>In the case of B2B, are you aiming for startup or enterprise businesses?</li><li>For B2B, are you targeting any particular industry?</li><li>For B2B, are there any particular shared financial aspects these companies are required to have? (e.g., 1mm+ ARR)</li><li>For B2B, are you aiming for a specific region/country or worldwide?</li></ol><p>Now, store that somewhere. It’s likely to change as you grow, but it’s always good to know what you defined when you started.</p><p>Use all of those answers to the questions to consider if there is someone in your network who fits the parameters. If yes, save their contact info; ideally, they will be part of your focus group. If possible, these contacts should not be your close friends or family, as we want unbiased feedback. However, if that is your only option, talk with them as if it is not your idea. “Mom’s Test” has awesome tips that essentially help you get honest feedback, even from your mom (although you will always be the smartest and the prettiest one!).</p><p>Ideally, you will have around 10 contacts in your focus group, but try to add more. Some might not be willing to take part in validating the hypothesis.</p><p>Great! At this point, you should already have a list of potential customers for your future product!</p><h3><strong>Problem hypothesis</strong></h3><p>So, now let’s get a bit more practical. I need you to ask yourself: What kind of problems are you going to solve with your product? List down all the problems that you want to address.</p><p>Be as creative as possible and think deeply about the problem you want to solve. If you come up with multiple problems, try to prioritize them so that you have a leading problem you want to address. To assist in prioritizing, you can use different techniques. For example, you can use a 100-point prioritization method where you split 100 points across all the problems, and the problem with the highest number of points becomes the top priority (you can apply the same technique with the focus group, giving them 100 points to allocate across multiple problems to prioritize them).</p><p>Now, you need to decide how to approach testing the problem hypothesis. In general, there are two main approaches: quantitative and qualitative.</p><h4><strong>Quantitative approach</strong></h4><p>This essentially means that you need them to think about the problem and assign a numerical value to it. For example:</p><p><em>How frustrating is it for you to xyz?</em> (Then you provide a Likert scale from 1 to 7, where they choose the level of their frustration).</p><p>It is important to identify what would be satisfactory for you to validate the problem hypothesis. For example, you might decide that anything above 5 on a scale of 1 to 7 means that the problem hypothesis is validated. Alternatively, you could create your own scale, where scores of 1 to 3 indicate that the problem is not worth resolving, scores of 4 to 5 suggest it might be worth exploring further, and scores of 6 to 7 indicate that you might be on a promising path.</p><h4><strong>Qualitative approach</strong></h4><p>Instead of assigning a specific number to a problem with the qualitative approach, you are leaning toward having a discussion with your potential customers and attempting to elicit insightful answers from them.</p><p>The most used method here is conducting 1:1 interviews. You should prepare a list of questions to guide the interview, but don’t be too strict in following the script. Keep the questions as broad as possible, as you might uncover additional problems during the conversation.</p><p>In general, always try to prompt discussions about previous experiences. Remember, the goal here is to gather unbiased feedback. For instance, if you’re building an art trading mobile app, asking them how they usually buy or sell verified art will provide more insight than asking if they dislike encountering fake art on eBay. These discussions about previous experiences offer valuable insights and often lead to the discovery of additional topics. While it’s important to gain a broad understanding, try to keep the discussion focused on topics relevant to the narrative of your product.</p><p>While everyone would like confirmation that they are solving a real problem, it’s crucial to maintain objectivity. The way you ask your questions is extremely important.</p><h3><strong>Solution hypothesis</strong></h3><p>At this point, you have your ideal customer segment, your focus group, and furthermore, you have validated the problem! Believe me, you are already ahead of many startups out there. You wouldn’t believe how many startups are building their products now without knowing if what they are building is worth building at all.</p><p>Now, let’s test your solution.</p><p>This is where things get a bit more complicated, as you might actually need to invest some funds to complete this step.</p><p>You can try to explain the solution that you want to build, and for some products, that will be a solid option. Then, you can distribute surveys to gather quantitative data, and voila!</p><p>However, for many startups, that approach will not be viable because it is challenging to explain the product without visually showing it. Fortunately, there are multiple options to overcome this obstacle. For example, for many web or mobile apps, you can create a clickable design prototype. This prototype mimics the main functionality of the product and is at least 10 times cheaper than building the actual product.</p><p>Even if you proceed with a textual explanation of the solution, I would advise building your clickable prototype afterward. You will benefit greatly from it, as I will explain later.</p><p>For now, let’s review the two approaches you used for problem hypothesis validation.</p><h4>Quantitative approach</h4><p>If you are all about the data, then the quantitative approach is your best option. One of the safest methods is to create a questionnaire with a mix of questions. Ensure that there is a combination of scaled questions, such as ‘<em>How important do you find XYZ functionality?</em>’ (rated on a scale of 1–7), and open-ended questions, such as ‘<em>While using the prototype, did you find any cool functionality missing that would make your life easier?</em>’</p><p>The quantitative approach, like the one above, really assists you in rating the solutions that you offer. However, don’t expect to uncover many cool ideas; people are usually not so fond of thinking outside the box when presented with predefined options.</p><p>One important note is not to overdo it with the number of questions, for the same reason as why you shouldn’t expect many cool textual answers on surveys. People are busy and don’t have much time these days, so their motivation to focus and respond truthfully to your questions drops dramatically when they see a survey with a lot of questions. Keep it straight to the point, clear, and concise.</p><h4>Qualitative approach</h4><p>The qualitative approach, such as conducting 1:1 interviews, is perfect if you want to uncover hidden thoughts about your product from testers.</p><p>I always suggest going with this approach for idea validation, as it can reveal emotions that are simply impossible to detect through survey answers.</p><p>Interviews can be conducted online or in-person. Either way, the goal is to capture their emotions and gestures while they click through the prototype. Ask them to perform specific actions and observe if they struggle with them. Pay attention to whether they ask a lot of questions or seem confused. Additionally, inquire about their thoughts on the product and whether they would like to see any changes. Finally, ask if they would use this product that your friend wants to create.</p><p>Remember that your goal here is to determine whether it is worth investing your time and resources in building this product.</p><h3>Conclusion</h3><p>Remember to document all the insights you gather from these activities. Once you’re ready, review each insight individually and then decide if it’s worth pursuing your idea further.</p><p>Understand that from now onwards, you are not only investing your time, but also your money. Every subsequent phase in your journey becomes proportionally more expensive.</p><p>Now, if you have made an unbiased decision to continue, it is time to <strong>build</strong>.</p><p><em>But, who am I? To decide if you want to read more about startups from my point of view, here is a short bio.</em></p><p><em>I am an entrepreneur by nature who has been involved in building startup products for the last 10 years, taking on different roles such as software developer, business analyst, project manager, product manager, and founder. I have experienced being part of the team from various perspectives, and each viewpoint has been an essential piece in helping me understand the entire cycle and how everything is interconnected. When you’re in the trenches, the bigger picture isn’t always clear, but having been involved in all these teams, I have gained a better understanding of how everything functions because a startup is truly like a living organism. Today, I am the founder and CEO of ScaleUp, where our focus is on building digital startup products with founders and companies from all around the world.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f9fbbb588b54" width="1" height="1" alt=""><hr><p><a href="https://medium.com/scaleuptech/startup-series-2-i-have-an-idea-f9fbbb588b54">Startup Series #2 — I have an idea</a> was originally published in <a href="https://medium.com/scaleuptech">ScaleUp</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Cross-Domain Communication in React using postMessage]]></title>
            <link>https://medium.com/scaleuptech/cross-domain-communication-in-react-using-postmessage-de90d3ded583?source=rss----d455d6fd6cec---4</link>
            <guid isPermaLink="false">https://medium.com/p/de90d3ded583</guid>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[postmessage]]></category>
            <category><![CDATA[cross-domain]]></category>
            <dc:creator><![CDATA[Neira Durmic]]></dc:creator>
            <pubDate>Tue, 26 Aug 2025 10:03:05 GMT</pubDate>
            <atom:updated>2025-08-26T10:03:05.125Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/683/1*RuBwj6uyaxg7QZQXiMTjWg.jpeg" /></figure><p>Recently, I had to make two separate React apps exchange data — despite being hosted on different domains. I needed something simple and secure. One of the simplest ways I found to solve this was by using window.postMessage.</p><h3>The Problem</h3><ul><li><strong>App A</strong> → running on <a href="https://dashboard.example.com/">https://app.example.com</a></li><li><strong>App B</strong> → running on <a href="https://widgets.partner.com/">https://widget.example.com</a></li></ul><p><strong>The goal:</strong> when a user is about to access App B, App A should check if the user is logged in and then send a short-lived code securely to App B. App B can then verify this code with the backend. Since these apps are on different domains, they can’t directly share storage or state.</p><h3>Why postMessage?</h3><p>With postMessage, a page can talk to an iframe or a popup it created. It’s the safe, built-in way the browser lets different origins send messages to each other.</p><h3>The Setup</h3><h3>1. Sending a Message</h3><p>From <strong>App A</strong>, I open App B in a popup and send a short-lived code, which App B can send to the backend to validate the user’s session:</p><pre>// AppA.tsx<br>const openWidget = () =&gt; {<br>  // Open App B in a popup<br>  const widgetWindow = window.open(<br>    &#39;https://widget.example.com&#39;, <br>    &#39;widget&#39;, <br>    &#39;width=800,height=600&#39;<br>  );<br>   <br>  if (widgetWindow) {<br>    // Generate or get a short-lived code from your backend<br>    const shortLivedCode = &#39;...&#39;; // Generate this on your backend<br><br>    // Send the code securely<br>    widgetWindow.postMessage(<br>      { type: &#39;LOGIN_CODE&#39;, code: shortLivedCode },<br>      &#39;https://widget.example.com&#39;<br>    );<br>  }<br>};<br><br>// Example button<br>&lt;button onClick={openWidget}&gt;Proceed To Widget&lt;/button&gt;</pre><p>It’s important to explicitly specify the target origin (https://widget.example.com) to keep it secure.</p><h3>2. Receiving a Message</h3><p>Over in <strong>App B</strong>, I set up a listener inside a React component:</p><pre>// AppB.tsx<br>import { useEffect } from &quot;react&quot;;<br><br>export default function AppB() {<br>  useEffect(() =&gt; {<br>    const handleMessage = async (event: MessageEvent) =&gt; {<br>      // Only accept messages from App A<br>      if (event.origin !== &quot;https://app.example.com&quot;) return;<br><br>      const { type, code } = event.data;<br>      if (type === &#39;LOGIN_CODE&#39;) {<br>        // Verify the code with your backend<br>        const isValid = await verifyCode(code); <br><br>        if (isValid) {<br>          console.log(&#39;User is authenticated, proceeding...&#39;);<br>        } else {<br>          console.log(&#39;Invalid or expired code, redirecting to login.&#39;);<br>          window.location.href = &#39;/login&#39;;<br>        }<br>      }<br>    };<br><br>    window.addEventListener(&quot;message&quot;, handleMessage);<br>    return () =&gt; window.removeEventListener(&quot;message&quot;, handleMessage);<br>  }, []);<br><br>  return &lt;div&gt;Waiting for login verification...&lt;/div&gt;;<br>}</pre><p><strong>App B</strong> <strong>receives the data from App A </strong>and exchanges the code with the backend to validate the user session and decide whether to proceed or redirect the user.</p><h3>Bonus: Sending Back a Response</h3><p>Sometimes App B might need to respond to App A (for example, to confirm the redirect was handled):</p><pre>event.source?.postMessage(<br>  { type: &quot;LOGIN_PROCESSED&quot;, result: &quot;success&quot; },<br>  event.origin<br>);</pre><h3>Common Pitfalls</h3><ul><li><strong>Forgetting to check </strong><strong>event.origin</strong> → Critical for security. Don’t process messages from unknown domains.</li><li><strong>Using </strong><strong>* as the target origin</strong> → Okay for testing, but never in production. Always whitelist the exact domain.</li><li><strong>Message shape mismatch</strong> → Both apps should agree on the format (e.g., { type, payload }).</li></ul><h3>Additional Security Measures</h3><ol><li><strong>Make sure to validate the </strong><strong>code before sending or using, on both sides, </strong>to ensure it matches the expected type or pattern.</li></ol><p>2. <strong>Set a Timeout for Window Reference</strong></p><p>If the popup fails or is closed immediately — alert the user to prevent confusion and improve UX and security.</p><pre>setTimeout(() =&gt; {<br>  if (!widgetWindow || widgetWindow.closed) {<br>    alert(&quot;Failed to open login widget. Please try again.&quot;);<br>  }<br>}, 3000);</pre><p>3. <strong>Make sure your backend:</strong></p><ul><li>Issues codes that expire in minutes.</li><li>Accepts codes only once.</li><li>Logs or blocks suspicious reuse attempts.</li></ul><h3>Final Thoughts</h3><p>Using postMessage is simple, reliable, and works across domains without violating security rules.</p><p>If you’re ever in a situation where two React apps (or even one React app and a vanilla JS widget) need to communicate across domains, don’t overcomplicate it. Start with postMessage.</p><p>It’s a valuable approach that every frontend developer should be familiar with.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=de90d3ded583" width="1" height="1" alt=""><hr><p><a href="https://medium.com/scaleuptech/cross-domain-communication-in-react-using-postmessage-de90d3ded583">Cross-Domain Communication in React using postMessage</a> was originally published in <a href="https://medium.com/scaleuptech">ScaleUp</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Adding Light and Dark Mode Favicons in React]]></title>
            <link>https://medium.com/scaleuptech/adding-light-and-dark-mode-favicons-in-react-4ca1a36d6ad0?source=rss----d455d6fd6cec---4</link>
            <guid isPermaLink="false">https://medium.com/p/4ca1a36d6ad0</guid>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[favicon]]></category>
            <category><![CDATA[dark-and-light-mode]]></category>
            <category><![CDATA[react]]></category>
            <dc:creator><![CDATA[Sanjin Sehic]]></dc:creator>
            <pubDate>Thu, 14 Aug 2025 16:11:04 GMT</pubDate>
            <atom:updated>2025-08-14T15:27:10.886Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1022/1*FfWb6hWoWS_BXrQExfZiUg.png" /></figure><h3>Introduction</h3><p>Favicons are small but important — they appear in browser tabs, bookmarks, and mobile home screens. With dark mode becoming more common, it’s a good idea to provide separate icons for light and dark themes. This ensures your site always looks polished, no matter the user’s settings.</p><h3>Choosing Your Icons</h3><p>Keep your icons simple and recognizable at small sizes. For best results, start with <strong>16x16 PNG files with transparent backgrounds</strong>, then convert them to .ico format. Create two versions: one for light backgrounds (favicon-light.ico) and one for dark backgrounds (favicon-dark.ico). Place them in your React app’s public folder so they can be referenced directly in index.html.</p><h3>Implementation in React</h3><p>In your public/index.html, you can use the media attribute to automatically switch icons based on the user’s theme:</p><pre>&lt;link rel=&quot;icon&quot; href=&quot;/favicon-dark.ico&quot; media=&quot;(prefers-color-scheme: dark)&quot; /&gt;<br>&lt;link rel=&quot;icon&quot; href=&quot;/favicon-light.ico&quot; media=&quot;(prefers-color-scheme: light)&quot; /&gt;</pre><p>This method works without extra JavaScript and ensures the correct favicon appears as soon as the page loads. Modern browsers will detect the user’s preferred color scheme and display the appropriate icon.</p><h3>Pro Tip: Testing and Caching</h3><p>Browsers often cache favicons aggressively, so changes might not appear immediately. To test your light and dark mode favicons, try opening your site in an incognito window or do a hard refresh (Ctrl+Shift+R / Cmd+Shift+R). You can also toggle your system’s light/dark mode to make sure the correct favicon appears. This ensures your implementation works reliably across different browsers and devices.</p><h3>Conclusion</h3><p>Adding light and dark mode favicons is a small but meaningful improvement to user experience. By using simple PNGs, the right sizes, and the media attribute, you can make your React app look polished across all themes with minimal effort.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4ca1a36d6ad0" width="1" height="1" alt=""><hr><p><a href="https://medium.com/scaleuptech/adding-light-and-dark-mode-favicons-in-react-4ca1a36d6ad0">Adding Light and Dark Mode Favicons in React</a> was originally published in <a href="https://medium.com/scaleuptech">ScaleUp</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to Write a Native Android Module in React Native]]></title>
            <link>https://medium.com/scaleuptech/how-to-write-a-native-android-module-in-react-native-78c4c855a374?source=rss----d455d6fd6cec---4</link>
            <guid isPermaLink="false">https://medium.com/p/78c4c855a374</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[react-native]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Sanjin Sehic]]></dc:creator>
            <pubDate>Tue, 22 Jul 2025 06:52:43 GMT</pubDate>
            <atom:updated>2025-08-04T12:34:30.772Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*YO4bB6abaStcMd1D_U6rcw.jpeg" /></figure><h3>Why I Had to Go Native</h3><p>As a React Native developer, I rarely find myself stepping into the native world. React Native abstracts most platform-specific things so well that I almost forgot there’s Java and Kotlin running underneath.</p><p>But recently, I had a specific use case: I needed to reboot the Android device directly from my React Native app.</p><p>And here’s the catch — this functionality doesn’t exist in the React Native ecosystem. So I had no choice but to go native and write a custom Android module myself.</p><h3>What React Native Developers Should Know About Native Modules</h3><p>React Native provides a bridge that allows communication between JavaScript and the native layers (Java for Android and Objective-C/Swift for iOS).</p><p>By writing a native module, you can expose native functionality that isn’t available in the default RN APIs. Once registered, these native methods can be called directly from JavaScript using NativeModules.</p><p>Use cases include:</p><ul><li>Accessing native Android/iOS APIs</li><li>Performing privileged operations (like device reboot)</li><li>Handling complex performance-critical logic</li><li>Integrating with third-party native SDKs</li></ul><p>It’s surprisingly straightforward once you get past the initial setup.</p><h3>Full Process Overview</h3><p>Here’s the full step-by-step guide to creating and using a native Android module in React Native (I am using a reboot module as an example here):</p><p><strong>1. Navigate to your native module folder</strong><br> Go to:<br> android/app/src/main/java/com/app<br> (Replace com/app with your actual package name.)</p><p><strong>2. Create two files</strong></p><ul><li>RebootModule.java – This contains your native logic.</li><li>RebootPackage.java – This exposes the module to React Native.</li></ul><p><strong>3. Register the package</strong><br> Open your MainApplication.java (or MainApplication.kt if you&#39;re using Kotlin) and add your custom package in the getPackages() method.</p><p><strong>4. Call the native method from JavaScript</strong><br> Use NativeModules.RebootModule.rebootDevice() inside your React Native code.</p><h3>Writing Module in Java</h3><p>Here’s the native Java code I wrote to reboot the Android device from React Native. <strong>In this example, the reboot functionality requires root access</strong> — the reboot command won&#39;t work on regular (non-rooted) Android devices.<br><strong>Note:</strong> Most native modules you write do not require root access. This requirement is specific to the reboot command or any command that requires admin (su) access.</p><pre>package com.app;<br><br>import android.util.Log;<br>import androidx.annotation.NonNull;<br>import com.facebook.react.bridge.ReactApplicationContext;<br>import com.facebook.react.bridge.ReactContextBaseJavaModule;<br>import com.facebook.react.bridge.ReactMethod;<br>import com.facebook.react.bridge.Promise;<br><br>import java.io.DataOutputStream;<br>import java.io.IOException;<br><br>public class RebootModule extends ReactContextBaseJavaModule {<br>    private static final String TAG = &quot;RebootModule&quot;;<br><br>    public RebootModule(ReactApplicationContext reactContext) {<br>        super(reactContext);<br>    }<br><br>    @NonNull<br>    @Override<br>    public String getName() {<br>        return &quot;RebootModule&quot;;<br>    }<br><br>    @ReactMethod<br>    public void rebootDevice(Promise promise) {<br>        try {<br>            Process process = Runtime.getRuntime().exec(&quot;su&quot;);<br>            DataOutputStream os = new DataOutputStream(process.getOutputStream());<br>            os.writeBytes(&quot;reboot\n&quot;);<br>            os.flush();<br>            os.writeBytes(&quot;exit\n&quot;);<br>            os.flush();<br>            os.close();<br>            <br>            int exitCode = process.waitFor();<br>            <br>            if (exitCode == 0) {<br>                promise.resolve(&quot;Reboot initiated&quot;);<br>            } else {<br>                promise.reject(&quot;REBOOT_ERROR&quot;, &quot;Reboot command failed with exit code: &quot; + exitCode);<br>            }<br>        } catch (IOException | InterruptedException e) {<br>            promise.reject(&quot;REBOOT_ERROR&quot;, &quot;Reboot failed: &quot; + e.getMessage());<br>        }<br>    }<br>}</pre><p>This class extends ReactContextBaseJavaModule and defines a method rebootDevice() that uses root privileges (su) to execute a reboot command.</p><h3>Exposing Native Functionality to React Native</h3><p>To make this native module available in JavaScript, you need to create a ReactPackage and register it.</p><pre>package com.app;<br><br>import com.facebook.react.ReactPackage;<br>import com.facebook.react.bridge.NativeModule;<br>import com.facebook.react.uimanager.ViewManager;<br>import com.facebook.react.bridge.ReactApplicationContext;<br><br>import java.util.ArrayList;<br>import java.util.Collections;<br>import java.util.List;<br><br>public class RebootPackage implements ReactPackage {<br>    @Override<br>    public List&lt;NativeModule&gt; createNativeModules(ReactApplicationContext reactContext) {<br>        List&lt;NativeModule&gt; modules = new ArrayList&lt;&gt;();<br>        modules.add(new RebootModule(reactContext));<br>        return modules;<br>    }<br><br>    @Override<br>    public List&lt;ViewManager&gt; createViewManagers(ReactApplicationContext reactContext) {<br>        return Collections.emptyList();<br>    }<br>}</pre><p>Now, register this package in your MainApplication.java (or MainApplication.kt if using Kotlin).</p><pre>import com.app.RebootPackage<br><br>override fun getPackages(): List&lt;ReactPackage&gt; =<br>  PackageList(this).packages.apply {<br>    add(RebootPackage()) // &lt;-- add this line<br>}</pre><p>With that, your native module is ready to use.</p><h3>Calling the Native Method from JavaScript</h3><p>Once everything is wired up, using the native method in JS is simple:</p><pre>import { NativeModules } from &#39;react-native&#39;;<br><br>NativeModules.RebootModule.rebootDevice()<br>  .then(response =&gt; {<br>    console.log(response); // Reboot initiated<br>  })<br>  .catch(error =&gt; {<br>    console.error(&#39;Reboot failed:&#39;, error);<br>  });</pre><p>⚠️ <strong>Reminder:</strong> The <strong>reboot command</strong> used in this example works only on rooted Android devices. If the device is not rooted, this specific command will silently fail or return a permission error. <em>(Other native modules you create may not have this requirement.)</em>.</p><h3>Final Thoughts</h3><p>Writing a native module might seem intimidating if you’ve only worked in JavaScript — but it’s not rocket science.</p><p>For me, this was a necessary step to bridge a gap in functionality React Native couldn’t fill. I was surprised at how well the integration worked once the setup was complete.</p><p>If you’re a React Native dev who’s never went into native land, I encourage you to try writing one small module. Even a simple one like this reboot function can teach you a lot about how the native and JS worlds interact.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=78c4c855a374" width="1" height="1" alt=""><hr><p><a href="https://medium.com/scaleuptech/how-to-write-a-native-android-module-in-react-native-78c4c855a374">How to Write a Native Android Module in React Native</a> was originally published in <a href="https://medium.com/scaleuptech">ScaleUp</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React Native vs Native Development: Choosing the Right Approach for Your App]]></title>
            <link>https://medium.com/scaleuptech/react-native-vs-native-development-choosing-the-right-approach-for-your-app-053c5adc07c9?source=rss----d455d6fd6cec---4</link>
            <guid isPermaLink="false">https://medium.com/p/053c5adc07c9</guid>
            <category><![CDATA[react-native]]></category>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[startup]]></category>
            <dc:creator><![CDATA[Sanjin Sehic]]></dc:creator>
            <pubDate>Mon, 26 May 2025 14:09:06 GMT</pubDate>
            <atom:updated>2025-05-26T14:08:28.790Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/360/1*dFFMLH5BNkXjWKfsxaLSEQ.png" /></figure><h3>Introduction</h3><p>The debate between <strong>React Native vs. Native app development</strong> is one that many developers and businesses face when they’re ready to build an app.</p><p>On one hand, <strong>React Native</strong> offers cross-platform capabilities and faster development time. On the other, <strong>native app development</strong> promises optimal performance and full access to device features.</p><h3>Development Time</h3><p>A key factor when comparing React Native and Native app development is the <strong>development time</strong>.</p><p>With native development, separate codebases are written for Android and iOS platforms due to their technical differences. This means you’ll need two dedicated teams — one for Android and one for iOS — to ensure your app is available on both platforms. Plus, any code changes require rebuilding and rerunning the entire project, which adds extra time and effort.</p><p>React Native simplifies this by using a <strong>single codebase</strong> for both platforms, enabling developers to build apps for Android and iOS simultaneously. The <strong>hot reloading</strong> feature further accelerates deployment, as changes can be applied instantly without a full rebuild.</p><p>So, if you’re aiming for a faster and more affordable entry into the mobile market across both platforms, <strong>React Native</strong> is an excellent choice.</p><h3>Cost</h3><p>React Native significantly reduces development costs since you’re maintaining a single codebase instead of two. If <strong>cost is a key consideration</strong>, React Native is the clear winner.</p><h3>UI/UX Experience</h3><p>While React Native allows developers to reuse core functionality and write platform-specific code where needed, creating complex user interfaces — such as custom views, intricate navigation patterns, seamless transitions, and animations — can be challenging.</p><p>Matching the UI/UX standards of both platforms can also be tricky with React Native. In contrast, <strong>native development</strong> allows every screen to be designed individually for each platform, delivering a superior <strong>mobile app UI/UX experience</strong>.</p><p>In terms of delivering an <strong>exceptional mobile experience</strong>, <strong>native development</strong> is the better choice.</p><h3>Performance</h3><p>For most standard use cases, React Native provides commendable performance that’s often comparable to native apps. However, for scenarios involving <strong>complex animations or high-performance operations</strong>, the JavaScript bridge used by React Native can introduce slight delays, impacting performance.</p><h3>Scalability</h3><p>When it comes to <strong>scalability</strong>, React Native offers developers more flexibility to handle higher workloads and release <strong>feature-rich updates</strong>. React Native has the edge here.</p><h3>App Maintenance</h3><p>Maintaining a <strong>native app</strong> is more time-consuming because bugs must be addressed separately for each platform.</p><p>With <strong>React Native</strong>, you only need to fix bugs once, and the updates apply across both platforms, making maintenance simpler and more efficient.</p><h3>When to Choose Native App Development</h3><p>Go with <strong>native app development</strong> if:</p><ul><li>You’re building a <strong>complex application</strong>.</li><li>You want to ensure a <strong>superior native user experience</strong>.</li><li>Your app relies heavily on <strong>device-specific features</strong> (e.g., a Brightness Controller app or a video-playing app in the background).</li><li>You’re targeting a <strong>single platform</strong>.</li></ul><h3>When to Choose React Native</h3><p>Choose <strong>React Native</strong> if:</p><ul><li>You’re building a <strong>simple and uniform app</strong>.</li><li>You need to <strong>launch on both platforms simultaneously</strong>.</li><li>You want to <strong>enter the market quickly</strong>.</li><li>You’re working with a <strong>limited budget</strong>.</li></ul><h3>Conclusion</h3><p><strong>React Native</strong> offers advantages like <strong>cost-effectiveness, cross-platform compatibility, and faster development time</strong>. However, it can face performance and complexity challenges for demanding applications.</p><p><strong>Native development</strong> excels at delivering <strong>high-performance apps</strong> that fully leverage device capabilities, though it requires more resources due to separate codebases for Android and iOS.</p><ul><li><strong>Startup Advantage</strong>: React Native is great for startups seeking a cost-efficient and quick market entry.</li><li><strong>Enterprise Advantage</strong>: Native development is better for businesses prioritizing performance, user experience, and leveraging platform-specific features.</li></ul><p>The right choice depends on your <strong>business goals, available resources, and emphasis on cost, performance, and user experience</strong>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=053c5adc07c9" width="1" height="1" alt=""><hr><p><a href="https://medium.com/scaleuptech/react-native-vs-native-development-choosing-the-right-approach-for-your-app-053c5adc07c9">React Native vs Native Development: Choosing the Right Approach for Your App</a> was originally published in <a href="https://medium.com/scaleuptech">ScaleUp</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[User Interviews: The One Thing That Will Save You from Designing Garbage]]></title>
            <link>https://medium.com/scaleuptech/user-interviews-the-one-thing-that-will-save-you-from-designing-garbage-1c9b4e91a015?source=rss----d455d6fd6cec---4</link>
            <guid isPermaLink="false">https://medium.com/p/1c9b4e91a015</guid>
            <category><![CDATA[user-interface]]></category>
            <category><![CDATA[design]]></category>
            <category><![CDATA[user-experience]]></category>
            <category><![CDATA[user-research]]></category>
            <category><![CDATA[user-interviews]]></category>
            <dc:creator><![CDATA[Amina Mehic Bektas]]></dc:creator>
            <pubDate>Fri, 14 Mar 2025 07:52:13 GMT</pubDate>
            <atom:updated>2025-03-14T08:35:32.456Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oP6soumhvuIr_EehD7WhCQ.png" /><figcaption>When your UI looks good but makes no sense.</figcaption></figure><p>If you’re a product designer and you’re not talking to users, let me tell you something straight: you’re guessing. And guessing in product design is the fastest way to waste time, build the wrong thing, and frustrate everyone — your team, your users, and yourself.</p><p>A lot of designers avoid user interviews because:</p><ul><li>They think they already know what users want. (<em>They don’t.</em>)</li><li>It feels like extra work. (<em>It’s not — it’s work that prevents rework.</em>)</li><li>They don’t know how to do it properly. (<em>That’s what this article is for.</em>)</li></ul><p>If you’re a beginner, or just someone who’s been avoiding user interviews like a dentist appointment, this guide will take you from “What do I even ask?” to “Oh wow, this just made my product actually usable.”</p><h3>Why Even Do User Interviews?</h3><p>Because real users don’t care about your beautiful UI. They care about getting something done. And if your product makes their life harder instead of easier, they’ll leave. Fast.</p><p>Let me give you a real-world example:</p><p>I worked on <strong>SHARPENN</strong>, a platform connecting consumers with beauty professionals. At one point, our onboarding process was long and complicated. We assumed people would take the time to set everything up properly. (<em>They didn’t.</em>)</p><p>So, I ran user interviews — real calls with real people who had never seen the app before. I gave them tasks, watched them struggle, and listened to their thoughts as they tried to sign up. Guess what? Most of them either quit halfway or got frustrated.</p><p>Based on those interviews, I <strong>cut the onboarding flow significantly</strong>, and the result? A huge jump in user retention. No A/B test, no analytics, no guessing — just actual conversations with actual users telling me exactly what was broken.</p><p>If I had relied on my assumptions, I would’ve wasted months designing something nobody wanted to use.</p><h3>How to Run a User Interview (Like a Smart Person, Not a Robot)</h3><p>Let’s get into the <strong>how</strong>. Here’s a simple framework to follow:</p><h3>1. Find the Right Users</h3><p>Not your coworkers. Not your mom. Not other designers. Find <strong>actual target users</strong> — people who would realistically use the product.</p><p>Where?</p><ul><li>If you have an existing user base, <strong>recruit them through email or in-app pop-ups</strong>.</li><li>If you don’t, <strong>go where they hang out</strong> — Facebook groups, Reddit, LinkedIn, Discord, niche communities.</li></ul><h3>2. Don’t Ask What They Think, Ask What They Do</h3><p>New designers make the mistake of asking:</p><ul><li><em>“Would you use this feature?”</em> (They’ll say yes just to be nice.)</li><li><em>“Do you like this design?”</em> (Meaningless. They’re not UI critics.)</li></ul><p>Instead, ask:</p><ul><li><em>“Can you show me how you currently do [task]?”</em> (Now you see their real process.)</li><li><em>“What was the last time you struggled with [problem]?”</em> (Now you know if they even have the problem you’re solving.)</li></ul><h3>3. Give Them a Task, Then Shut Up</h3><p>This is where you learn the most. Instead of talking about the product, <strong>let them use it</strong>.</p><p>Example: On SHARPENN, I needed to see if non-tech users could navigate the app. So, on a Google Meet call, I gave them tasks like:</p><ul><li><em>“Find a hairstylist job and apply for the position.”</em></li><li><em>“Try to message a professional you like.”</em></li></ul><p>Then I <strong>watched</strong>.</p><ul><li>Where did they hesitate?</li><li>What confused them?</li><li>Where did they rage-click?</li></ul><p>And I didn’t explain anything. If I had to explain it, that meant the UI was unclear.</p><h3>What to Do With the Insights?</h3><p>Once you have data from multiple users, look for patterns. If <strong>one person</strong> gets stuck, maybe they’re just bad at technology. If <strong>five out of six</strong> get stuck, you’ve got a design problem.</p><p>Examples of changes I made based on user interviews:<br> ✅ <strong>Cutting onboarding time</strong> → More users completed signup.<br> ✅ <strong>Reworking navigation</strong> → Users found what they needed faster.<br> ✅ <strong>Simplifying the main screen</strong> → Less confusion, more engagement.</p><p>These weren’t “creative” design choices. They were <strong>direct responses</strong> to real user struggles.</p><h3>Final Thought: Get Over Yourself &amp; Start Talking to Users</h3><p>Some designers act like user interviews aren’t necessary because <em>“I understand good UX”</em>. No, you don’t — not until you watch someone completely fail to use your design.</p><p>User interviews aren’t extra work. They’re <strong>insurance</strong> against making dumb design decisions. If you take one thing from this article, let it be this:</p><p><strong>Designing without talking to users is like cooking blindfolded — you’re just hoping it turns out fine. Don’t do that.</strong></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1c9b4e91a015" width="1" height="1" alt=""><hr><p><a href="https://medium.com/scaleuptech/user-interviews-the-one-thing-that-will-save-you-from-designing-garbage-1c9b4e91a015">User Interviews: The One Thing That Will Save You from Designing Garbage</a> was originally published in <a href="https://medium.com/scaleuptech">ScaleUp</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why You Should Write on Medium: Share, Learn, and Grow]]></title>
            <link>https://medium.com/scaleuptech/why-you-should-write-on-medium-share-learn-and-grow-fe73021fe729?source=rss----d455d6fd6cec---4</link>
            <guid isPermaLink="false">https://medium.com/p/fe73021fe729</guid>
            <category><![CDATA[writing]]></category>
            <category><![CDATA[medium]]></category>
            <category><![CDATA[learning]]></category>
            <dc:creator><![CDATA[Sanjin Sehic]]></dc:creator>
            <pubDate>Tue, 25 Feb 2025 21:24:36 GMT</pubDate>
            <atom:updated>2025-02-25T21:23:51.176Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/626/1*Ns5xO3qC76NvstUcG11OOg.png" /></figure><h3>A Platform Built for Writers</h3><p>Medium is designed for writers of all levels, whether you’re a beginner sharing your first thoughts or an expert with years of experience. Unlike setting up a personal blog, which requires managing hosting, design, and SEO, Medium handles everything for you. You can focus entirely on writing and sharing your ideas.</p><p>With its clean interface and built-in audience, Medium makes publishing effortless. You don’t need to worry about technical details — just write, hit publish, and your work is out there for readers to discover.</p><h3>Writing Makes You a Better Thinker</h3><p>Writing isn’t just about putting words on a page — it’s a process of organizing thoughts, clarifying ideas, and questioning your own understanding. When you write on Medium, you’re not just sharing what you know, you’re also strengthening and improving your own knowledge.</p><p>To explain something clearly, you need to be sure about it yourself. This pushes you to research, double-check facts, and think critically. Over time, this habit improves your ability to communicate, analyze, and learn better. Writing regularly on Medium isn’t just about helping others — it’s one of the best ways to grow yourself.</p><h3>Helping the Community</h3><p>Sharing knowledge is one of the best ways to give back to the community. When you write on Medium, you’re contributing to a space where people come to learn, find solutions, and gain new perspectives. <br>What might seem simple or obvious to you could be exactly what someone else needs to read.</p><h3>We All Learn from Each Other</h3><p>No one knows everything, but together, we can learn so much. Medium is a place where people from different backgrounds and experiences share their insights, mistakes, and lessons learned. By reading others’ perspectives, you expand your own understanding.</p><p>When you write, you contribute to this collective knowledge. Your experiences, no matter how big or small, can inspire or help someone else. And in return, the feedback, comments, and discussions around your writing can teach you new things too.</p><h3>Your Voice Matters — Start Writing Today!</h3><p>Everyone has something valuable to share. Whether it’s a lesson you’ve learned, an idea that excites you, or a challenge you’ve overcome, your experiences can inspire and help others. You don’t need to be an expert — just start writing.</p><p>Many people hold back because they think their ideas aren’t important enough or that they’re not “good” writers. But the truth is, writing is a skill that improves with practice, and every perspective matters. The more you write, the more confident you become.</p><p>I know this because I was once in the same place. I hesitated, wondering if my ideas were good enough or if my writing was strong enough. I was scared to put my thoughts out there. But I took the leap, and now I’m glad I did. Writing has helped me grow, connect with others, and made me realize that every voice, including mine, has value.</p><p>So don’t wait for the perfect moment — start today. Share your thoughts, learn from the process, and be part of a community that grows together.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fe73021fe729" width="1" height="1" alt=""><hr><p><a href="https://medium.com/scaleuptech/why-you-should-write-on-medium-share-learn-and-grow-fe73021fe729">Why You Should Write on Medium: Share, Learn, and Grow</a> was originally published in <a href="https://medium.com/scaleuptech">ScaleUp</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>