{
    "componentChunkName": "component---src-pages-blog-index-js",
    "path": "/blog/",
    "result": {"data":{"allMarkdownRemark":{"edges":[{"node":{"frontmatter":{"title":"When Agentic Coding Meets Startup Reality","description":"A founder story that showed me what AI can accelerate and what it cannot replace","slug":"/blog/agentic-coding-meets-startup-reality","date":"2026-07-01T00:00:00.000Z","tags":["AI","Startup","Culture","Engineering"],"draft":false},"html":"<p>I recently interviewed with a founder who had a big business idea and a very small budget.</p>\n<p>At first, it sounded like most of the work was already done.\nHe told me the product was basically built, and he just needed a technical partner to help with the backend.</p>\n<p>He shared an AI-generated document with me.\nIt had a lot of technical concepts in it.\nTo be honest, even for me as a software architect, it was not easy to understand right away.</p>\n<p>My first reaction was something like:</p>\n<p>Wow.\nThis guy may have built a whole system without a technical background.\nAgentic coding is really changing the game.\nMaybe Claude is coming for my job soon.</p>\n<p>That was honestly my feeling in the moment.\nI was kind of impressed, kind of confused, and kind of thinking, \"okay, what is really going on here?\"\nHonestly, I had that tiny little fear in my chest like, \"great, maybe I really am about to be replaced by a guy with a laptop and Claude.\"</p>\n<p>But then I took a deeper look.</p>\n<hr>\n<h3>The deeper look</h3>\n<p>Once I started digging in, the picture changed very quickly.</p>\n<p>What looked like a finished system was really more like a rough setup made to look finished:</p>\n<ul>\n<li>one HTML file being used like a multi-page product</li>\n<li>mock data presented like a backend</li>\n<li>AI-written documentation that sounded technical but was still fuzzy in practice</li>\n<li>no clear CI/CD setup</li>\n<li>no real separation between development, sandbox, and production</li>\n</ul>\n<p>It was not a disaster.\nBut it was also not a finished product.</p>\n<p>And that is the part I think a lot of people miss right now.</p>\n<p>AI can make something look much more complete than it really is.\nIt can generate the shape of a product before the product is actually ready.</p>\n<p>That can be useful.\nIt can also be very misleading.\nIt can even make a messy idea feel like a polished startup if you do not look too closely.</p>\n<hr>\n<h3>What the founder really needed</h3>\n<p>At first, he said he needed a technical partner who could help with some tech.</p>\n<p>But after we talked more, it became clear that what he really needed was not just technical execution.\nHe needed reality, gently but clearly.</p>\n<p>He needed:</p>\n<ul>\n<li>a clearer understanding of what was actually built</li>\n<li>a realistic view of what still needed to be built</li>\n<li>help separating product idea from technical illusion</li>\n<li>someone who could translate startup ambition into a real engineering plan</li>\n</ul>\n<p>That is where I had to slow things down.</p>\n<p>I had to explain some basic technical concepts.\nI had to point out blockers.\nI had to show him why the current setup would not scale the way he thought it would.</p>\n<p>Honestly, it was not easy.\nIt took patience.\nIt took honesty.\nAnd it took a lot of back-and-forth.\nThere were moments where I wanted to say, \"bro, this is not a backend, this is a dressed-up demo.\"\nBut I also knew that would not help.</p>\n<p>But I think that conversation mattered.\nSometimes the most helpful thing is not saying yes.\nIt is helping someone see the whole picture.\nEven if the picture is a little ugly at first.</p>\n<hr>\n<h3>Why this experience stayed with me</h3>\n<p>What stayed with me was not the AI-generated document.\nIt was the gap between appearance and reality.</p>\n<p>Agentic coding is awesome.\nIt really is.\nIt lets non-technical founders move faster, prototype earlier, and think more concretely.</p>\n<p>That is a huge win.\nI am not even being sarcastic here.\nThat part is genuinely exciting.</p>\n<p>But there is a difference between:</p>\n<ul>\n<li>generating a convincing prototype</li>\n<li>and building a reliable product</li>\n</ul>\n<p>That difference shows up in production.\nIt shows up in deployment.\nIt shows up in how systems behave when real users hit them.\nIt shows up in the boring details:</p>\n<ul>\n<li>environment configuration</li>\n<li>test coverage</li>\n<li>backend contracts</li>\n<li>error handling</li>\n<li>observability</li>\n<li>release process</li>\n</ul>\n<p>That is where the real work lives.\nThat is also the part nobody can fake for very long.\nThe internet is full of people faking it for a while.\nProduction has a funny way of exposing everybody.</p>\n<hr>\n<h3>The honest conversation</h3>\n<p>Eventually, I gave him a more transparent view of the project and the idea.</p>\n<p>That conversation changed things.</p>\n<p>The good news is that he did not abandon the idea.\nHe did not throw everything away and start another fuzzy concept built on another one-page HTML repo.\nWhich, honestly, would have been the most startup thing ever.</p>\n<p>Instead, he started to understand the difference between:</p>\n<ul>\n<li>a fast AI-generated demo</li>\n<li>and a real startup foundation</li>\n</ul>\n<p>That is a healthy shift.</p>\n<p>Because once a founder sees the gap clearly, they can make better decisions.</p>\n<p>They can ask better questions.\nThey can build with more intention.\nThey can stop confusing momentum with product maturity.</p>\n<hr>\n<h3>What I learned from this</h3>\n<p>This experience reminded me of a few things.</p>\n<p>First, agentic coding is not fake.\nIt is very real, and it is already changing how people build.\nAnd yes, it is a little scary sometimes.</p>\n<p>Second, technical clarity still matters a lot.\nEven if an idea is born in AI, the system still has to survive real users, real deadlines, and real infrastructure.</p>\n<p>Third, founders do not always need someone to say yes.\nSometimes they need someone who can make the truth easier to understand.</p>\n<p>That is a big part of being a good technical partner.</p>\n<p>You are not just building software.\nYou are helping someone understand what software can and cannot do.</p>\n<hr>\n<h3>My takeaway</h3>\n<p>I was actually happy to help.\nNot because I enjoy cleaning up chaos.\nWell, maybe a little.</p>\n<p>Not because the project was perfect.\nNot because everything was clean.\nBut because it gave me a chance to stand close to a founder who was trying to build something real, even if the starting point was messy.\nThat part felt meaningful.\nI like helping people get from \"vibes\" to something real.\nEspecially when they are trying hard and honestly do not fully know what they are doing yet.</p>\n<p>That is part of startup life too.</p>\n<p>The best ideas often begin with confusion.\nThe job is to turn that confusion into structure.</p>\n<p>And if agentic coding helps more people start the journey, that is a good thing.</p>\n<p>But it still takes humans to turn the first draft into a real business.</p>"}},{"node":{"frontmatter":{"title":"TDD In The Age Of AI Agents","description":"Why tests matter even more when code is generated faster than ever","slug":"/blog/tdd-in-the-age-of-ai-agents","date":"2026-06-29T00:00:00.000Z","tags":["AI","Engineering","Culture","Product"],"draft":false},"html":"<p>I have been thinking a lot about how software development is changing.</p>\n<p>Not because writing code is going away.\nBut because the way we get to working code is changing very fast.</p>\n<p>AI agents can now draft features, refactor files, create tests, and even fix bugs in a way that would have felt impossible a few years ago.\nThat is exciting.\nIt is also dangerous if we stop paying attention to discipline.</p>\n<p>For me, that is where TDD becomes more important, not less.</p>\n<hr>\n<h3>The new reality</h3>\n<p>Agentic development changes the shape of the work.</p>\n<p>Instead of spending all your energy on typing every line yourself, you spend more time:</p>\n<ul>\n<li>defining what the system should do</li>\n<li>checking whether the output matches the intent</li>\n<li>keeping complexity under control</li>\n<li>deciding when to trust the agent and when to stop it</li>\n</ul>\n<p>That is a different job.\nAnd it requires a different kind of focus.</p>\n<p>The biggest shift is not technical.\nIt is psychological.</p>\n<p>When code comes back quickly, it becomes very easy to mistake speed for correctness.\nThat is exactly where TDD helps.</p>\n<hr>\n<h3>Why TDD still matters</h3>\n<p>TDD gives you a small but powerful loop:</p>\n<ul>\n<li>write down the behavior first</li>\n<li>make the failure visible</li>\n<li>produce the minimum code to pass</li>\n<li>refactor with confidence</li>\n</ul>\n<p>That loop is valuable in normal development.\nIt becomes even more valuable when an agent is involved.</p>\n<p>Why?</p>\n<p>Because tests are a form of truth.\nThey help you separate:</p>\n<ul>\n<li>what you want</li>\n<li>what the code currently does</li>\n<li>what the agent thinks you asked for</li>\n</ul>\n<p>That separation matters.\nAgents are good at producing options.\nThey are not always good at understanding the shape of the problem the way a human does.</p>\n<p>If the test is weak, the agent can still look productive while drifting away from the real goal.\nIf the test is strong, the agent has a better boundary to work inside.</p>\n<hr>\n<h3>What agents change</h3>\n<p>Kent Beck’s broader point, as I read it, is not that agents make engineering obsolete.\nIt is that they push the important skills upward.</p>\n<p>That matches what I am seeing too.</p>\n<p>The valuable part is becoming:</p>\n<ul>\n<li>setting a clear vision</li>\n<li>breaking work into meaningful milestones</li>\n<li>controlling complexity as the system grows</li>\n<li>knowing what \"done\" actually means</li>\n</ul>\n<p>Those are not glamorous tasks, but they are the ones that keep projects from turning into chaos.</p>\n<p>The old habit was to focus on syntax, implementation details, and manual repetition.\nThe new habit is to focus on direction, quality, and verification.</p>\n<p>That is why I do not see AI agents as a replacement for engineering discipline.\nI see them as a stress test for it.</p>\n<hr>\n<h3>The failure modes are real</h3>\n<p>AI agents can be incredibly useful.\nThey can also surprise you in very annoying ways.</p>\n<p>Sometimes they:</p>\n<ul>\n<li>over-optimize for the prompt instead of the product</li>\n<li>remove useful tests because they look unnecessary</li>\n<li>produce code that compiles but does not really solve the problem</li>\n<li>create a false sense of progress because something changed fast</li>\n</ul>\n<p>That is why I do not trust speed on its own.</p>\n<p>Speed without validation is just a faster way to make mistakes.</p>\n<p>And when you are working in a product environment, mistakes are not abstract.\nThey affect users, teams, timelines, and trust.</p>\n<hr>\n<h3>The workflow I like</h3>\n<p>If I were building with agents today, I would keep the process simple.</p>\n<ol>\n<li>\n<p>Start with behavior.\nDefine what the feature should do in plain language.</p>\n</li>\n<li>\n<p>Write the test or acceptance check first.\nMake the expectation visible before the implementation exists.</p>\n</li>\n<li>\n<p>Let the agent draft the code.\nUse it as leverage, not as authority.</p>\n</li>\n<li>\n<p>Verify the result against the test and the design intent.\nAsk whether the solution is correct, not just whether it is complete.</p>\n</li>\n<li>\n<p>Refactor with human judgment.\nClean up the shape of the code so the next change is easier.</p>\n</li>\n</ol>\n<p>That flow keeps the human in charge of meaning while letting the agent handle more of the repetitive work.</p>\n<p>That feels like the right balance to me.</p>\n<hr>\n<h3>Why this matters for teams</h3>\n<p>This is not only a developer workflow issue.\nIt affects how teams operate.</p>\n<p>When agents become part of the development process, teams need stronger habits around:</p>\n<ul>\n<li>code review</li>\n<li>test quality</li>\n<li>architecture decisions</li>\n<li>shared understanding of product goals</li>\n</ul>\n<p>The best teams will not be the ones who use the most AI.\nThey will be the ones who use it with the clearest standards.</p>\n<p>That is especially important for startups.\nStartups move fast already.\nIf you add AI into the mix without strong feedback loops, you can scale confusion just as easily as you scale output.</p>\n<p>So the goal is not to chase more code.\nThe goal is to build better systems with less waste.</p>\n<hr>\n<h3>My takeaway</h3>\n<p>I do not think TDD is becoming outdated.\nI think it is becoming more useful in an environment where generation is cheap and correctness is still expensive.</p>\n<p>Agentic development gives us leverage.\nTDD gives us confidence.</p>\n<p>Together, they create a workflow where we can move quickly without losing our sense of direction.</p>\n<p>And that feels like the real opportunity.</p>\n<p>Not to write more code for the sake of it.\nBut to build software with more clarity, more control, and more intention.</p>"}},{"node":{"frontmatter":{"title":"SaaS Is Not Dead. But the Easy Version Might Be.","description":"AI is changing software, but it is not killing production-grade SaaS","slug":"/blog/saas-is-not-dead","date":"2026-06-11T00:00:00.000Z","tags":["AI","SaaS","Product","Startup"],"draft":false},"html":"<p>Everyone keeps saying SaaS is dead.</p>\n<p>The argument goes like this:</p>\n<p>AI can build software now.\r\nSo why pay for Salesforce when you can ask Claude to build a CRM?\r\nWhy keep subscribing when a prompt can generate the thing?</p>\n<p>It sounds dramatic.</p>\n<p>It also misses the point.</p>\n<p>AI is changing software, but it is not deleting the need for real products.</p>\n<p>Vibe coding works really well for tools used by a small number of people.\r\nIt works for internal tools.\r\nIt works for prototypes.\r\nIt works for narrow workflows where the stakes are low and the users know exactly what they want.</p>\n<p>It does <strong>not</strong> replace the software that entire companies rely on every day.</p>\n<p>Workday, Salesforce, Gmail, and the rest of the enterprise stack are not just apps.</p>\n<p>They are years of edge cases.\r\nYears of permissions.\r\nYears of integrations.\r\nYears of compliance, uptime, support, reporting, security, and boring reliability.</p>\n<p>You do not reproduce that in a weekend with Claude Code.</p>\n<p>That is the part the \"SaaS is dead\" crowd keeps skipping.</p>\n<p>Production software is not just code.</p>\n<p>It is maintenance.\r\nIt is trust.\r\nIt is uptime.\r\nIt is knowing what happens when something breaks at 2 a.m.\r\nIt is handling the weird customer who uses the product in a way nobody predicted.\r\nIt is surviving the thousand tiny failures that never show up in a demo.</p>\n<p>Most companies would rather pay for that than own it themselves.</p>\n<hr>\n<h3>But the doomsday version is not totally wrong</h3>\n<p>Some SaaS will die.</p>\n<p>Not because software becomes useless.\r\nNot because every company will suddenly become a software company.\r\nBut because the business model changes underneath it.</p>\n<p>AI lowers the cost of building.\r\nThat means more products can be made faster, by fewer people, with less capital.</p>\n<p>It also means customers will have higher expectations.\r\nMore alternatives.\r\nLess patience for bloated tools that solve a problem only slightly better than a script, a prompt, or a lightweight workflow.</p>\n<p>The old SaaS playbook was simple:</p>\n<ul>\n<li>build a product</li>\n<li>sell seats</li>\n<li>add features</li>\n<li>raise prices</li>\n<li>expand into adjacent workflows</li>\n</ul>\n<p>That playbook still works for some products.</p>\n<p>But it gets weaker when the software is generic, replaceable, or only marginally better than what a smart team can assemble themselves.</p>\n<hr>\n<h3>We have seen this movie before</h3>\n<p>A good analogy is television.</p>\n<p>Cinema did not die when TV arrived.\r\nBut it changed.</p>\n<p>People no longer needed to leave the house to watch moving pictures.\r\nThat shifted the whole category.</p>\n<p>Theaters had to adapt.\r\nSome formats faded.\r\nSome became more premium.\r\nSome became cultural events.\r\nMovies survived, but they reshaped around a world where entertainment could happen at home.</p>\n<p>AI may do the same thing to SaaS.</p>\n<p>Not all software disappears.</p>\n<p>But the center of gravity moves.</p>\n<p>Some products will get commoditized.\r\nSome will become more niche.\r\nSome will need to become deeply embedded in a workflow to survive.\r\nSome will need to become meaningfully better, not just a little better.</p>\n<p>The companies that adapt will thrive.</p>\n<p>The ones that assume customers will keep paying just because they always have will be in trouble.</p>\n<hr>\n<h3>I have seen enough to take this seriously</h3>\n<p>My last company, Crossfill, shut down.</p>\n<p>That makes this whole conversation feel less abstract.</p>\n<p>It is easy to talk about market shifts like they are strategy deck slides.\r\nIt is different when you have lived through a product, a team, and a business reaching the point where they no longer work.</p>\n<p>Shutdowns have a way of clarifying things.</p>\n<p>They show you what actually mattered.\r\nThey show you what was fragile.\r\nThey show you how fast a market can move on from a product that once felt necessary.</p>\n<p>That experience makes me skeptical of any argument that says a category is permanently safe.</p>\n<p>It also makes me skeptical of the opposite extreme.</p>\n<p>Nothing is guaranteed.\r\nNot even the tools everyone assumes are untouchable.</p>\n<hr>\n<h3>So what survives?</h3>\n<p>I think the winners will be the software that becomes harder to replace, not easier.</p>\n<p>The products that survive will be the ones that are:</p>\n<ul>\n<li>deeply embedded in real workflows</li>\n<li>reliable under pressure</li>\n<li>trusted by teams, not just admired in demos</li>\n<li>expensive to rebuild correctly</li>\n<li>better than a prompt plus a weekend</li>\n</ul>\n<p>The future is not <strong>no SaaS</strong>.</p>\n<p>The future is probably <strong>less generic SaaS</strong> and <strong>more software that earns its place</strong>.</p>\n<p>That means fewer companies winning by being the default.\r\nMore companies winning by being indispensable.</p>\n<p>It also means some products will need to stop thinking like software vendors and start thinking like workflow owners.</p>\n<p>Not just \"how do we add AI?\"\r\nBut \"what are we actually irreplaceable for?\"</p>\n<p>That is a much harder question.\r\nBut it is the right one.</p>\n<hr>\n<h3>AI is not an asteroid</h3>\n<p>That is the biggest mistake people make.</p>\n<p>AI is not an asteroid that wipes out software.</p>\n<p>It is a force multiplier.</p>\n<p>It lowers the cost of creation.\r\nIt increases the speed of iteration.\r\nIt makes it easier to build alternatives.\r\nIt raises the bar for what customers expect.</p>\n<p>That is not the end of SaaS.</p>\n<p>It is a pressure test.</p>\n<p>Some companies will thrive.\r\nSome will get squeezed.\r\nSome really are dinosaurs.</p>\n<p>The ones that survive will not be the ones with the loudest AI marketing.</p>\n<p>They will be the ones that are actually useful, deeply embedded, and hard to replace.</p>\n<p>SaaS is not dead.</p>\n<p>But the easy version of SaaS might be.</p>"}},{"node":{"frontmatter":{"title":"WATERFALL -> AGILE -> AGENTIC","description":"What I learned running multi-agent coding workflows at Crossfill","slug":"/blog/waterfall-agile-agentic","date":"2026-04-28T00:00:00.000Z","tags":["AI","Engineering","Product","Culture"],"draft":false},"html":"<p>At Crossfill, I started running multiple AI coding agents at the same time.</p>\n<p>Not one chat.\r\nNot one tool.\r\nA real multi-agent workflow.</p>\n<p>I used multiple Codex, Claude, and Gemini accounts in parallel,\r\ngiving each agent a clear responsibility based on the task at hand.</p>\n<p>Then I mentored the team to work the same way.\r\nDesigners, PMs, engineers.\r\nDifferent backgrounds, same goal:\r\nShip faster without losing product thinking.</p>\n<p>That experience changed how I see software development.</p>\n<hr>\n<p>I believe we are moving through a clear evolution:</p>\n<p>WATERFALL -> AGILE -> AGENTIC.</p>\n<ul>\n<li>Waterfall optimized for being right upfront, because iteration was expensive.</li>\n<li>Agile optimized for human iteration speed, because iteration got cheaper.</li>\n<li>Agentic optimizes for something else entirely: when iteration is basically free.</li>\n</ul>\n<p>This is not just a tooling trend.\r\nIt is an operating model shift.</p>\n<hr>\n<p>A lot of people still treat agentic coding (or vibe coding) like a side quest.</p>\n<p>Non-technical people building random demos.\r\nFun, but not serious.</p>\n<p>That is part of the picture.\r\nBut it is not the full story.</p>\n<p>What we are seeing is a new software culture forming in real time.</p>\n<ul>\n<li>no PRDs, just paste a gist and start prototyping</li>\n<li>less manual code review, more automated review skills and eval loops</li>\n<li>less rollback thinking, more branch-and-explore thinking</li>\n<li>huge output, huge debt, huge surface area</li>\n<li>velocity goes up, entropy also goes up</li>\n<li>product quality depends more on curation and pruning</li>\n<li>non-coders can finally encode domain expertise into working software</li>\n<li>strong engineers can orchestrate agent swarms with custom harnesses</li>\n</ul>\n<p>It looks chaotic because it is chaotic.\r\nBut early paradigm shifts usually look like this.</p>\n<hr>\n<h3>The slop phase is real</h3>\n<p>Yes, there is code slop.\r\nApp slop.\r\nSlop slop slop.</p>\n<p>And honestly, this is expected.</p>\n<p>When creation gets much cheaper, output volume explodes first.\r\nSignal systems come later.</p>\n<p>The internet went through this.\r\nSoftware will too.</p>\n<ul>\n<li>more creation</li>\n<li>more noise</li>\n<li>better filtering needed</li>\n<li>better product-level garbage collection needed</li>\n</ul>\n<p>In this environment, maintenance becomes strategy.\r\nRefactoring becomes governance.\r\nPruning becomes product leadership.</p>\n<hr>\n<h3>Org design is next</h3>\n<p>This shift does not stop at developer workflow.\r\nIt reshapes teams.</p>\n<p>We will reorganize around:</p>\n<ul>\n<li>who can direct agents effectively</li>\n<li>who governs quality, security, and compliance</li>\n<li>who protects UX coherence</li>\n<li>who owns architecture over time</li>\n</ul>\n<p>The old boundaries between Engineering, Product, and Design will collide first.\r\nThen settle into a new model.</p>\n<hr>\n<h3>This is the same movie we saw with Agile</h3>\n<p>Agile had a similar arc:</p>\n<ul>\n<li>messy experimentation</li>\n<li>lightweight culture</li>\n<li>formalization (XP, Scrum, TDD)</li>\n<li>enterprise adoption and certification theater</li>\n<li>eventual normalization</li>\n</ul>\n<p>Agentic development will likely follow a similar path.\r\nRight now, we are still early.\r\nThat is why it feels unserious to some people.</p>\n<hr>\n<h3>The uncomfortable prediction</h3>\n<p>Just like people eventually talked trash about waterfall,\r\none day people may talk trash about agile too.</p>\n<p>Not because agile was useless.\r\nBecause agile was built for a different constraint:\r\nhuman-only iteration.</p>\n<p>Agentic changes that constraint.</p>\n<p>When iteration approaches zero cost,\r\neverything upstream and downstream has to be redesigned.</p>\n<p>Not just coding.\r\nProduct.\r\nTeams.\r\nCompanies.</p>\n<p>Maybe even what a company is.</p>"}},{"node":{"frontmatter":{"title":"How I Taught Vibe Coding To Non-Technical Designers","description":"What worked when I taught vibe coding at Crossfill","slug":"/blog/teaching-vibe-coding-to-designers","date":"2026-01-18T00:00:00.000Z","tags":["Culture","Product","AI"],"draft":false},"html":"<p>At Crossfill, I taught vibe coding to UI/UX designers who didn’t come from engineering backgrounds.</p>\n<p>At first, they were nervous.\r\nNot because they weren’t smart.\r\nBecause they assumed code was a locked door and they didn’t have the key.</p>\n<p>That was the first thing I tried to change.</p>\n<p>I told them:</p>\n<p><strong><em>You don’t need to become an engineer to use code as a design tool.</em></strong></p>\n<p>The goal was never “turn designers into developers.”\r\nThe goal was to help them prototype ideas faster, communicate better with engineers, and feel more ownership from idea to implementation.</p>\n<hr>\n<h3>What I mean by vibe coding</h3>\n<p>To me, vibe coding is:</p>\n<ul>\n<li>using AI and lightweight coding tools to quickly explore ideas</li>\n<li>focusing on product behavior and UX flow before polishing every detail</li>\n<li>iterating in short loops: prompt, test, refine, repeat</li>\n</ul>\n<p>It is not about writing “perfect architecture” on day one.\r\nIt is about creating momentum.</p>\n<hr>\n<h3>How I taught it</h3>\n<p>I kept the process simple and practical.</p>\n<h4>1. Start from behavior, not syntax</h4>\n<p>I asked designers to describe:</p>\n<ul>\n<li>what the user is trying to do</li>\n<li>what should happen after each interaction</li>\n<li>what edge cases should feel like</li>\n</ul>\n<p>Once that was clear, code became a translation layer, not a scary mystery.</p>\n<h4>2. Build tiny, visible wins</h4>\n<p>Instead of “build a whole app,” we did:</p>\n<ul>\n<li>one interactive card</li>\n<li>one state transition</li>\n<li>one filtered list</li>\n</ul>\n<p>Small wins built confidence quickly.</p>\n<h4>3. Use prompts like product specs</h4>\n<p>I encouraged prompts that included:</p>\n<ul>\n<li>target user</li>\n<li>intent</li>\n<li>constraints</li>\n<li>expected output</li>\n</ul>\n<p>Better prompt quality gave better outputs and better learning.</p>\n<h4>4. Review together like a product critique</h4>\n<p>We didn’t review only visuals.\r\nWe reviewed:</p>\n<ul>\n<li>UX flow</li>\n<li>readability</li>\n<li>fallback states</li>\n<li>performance assumptions</li>\n</ul>\n<p>That made the collaboration with engineering much smoother later.</p>\n<hr>\n<h3>What changed</h3>\n<p>After a few weeks, the difference was obvious.</p>\n<ul>\n<li>Designers moved faster from concept to testable prototype.</li>\n<li>Hand-off quality improved because behavior was clearer.</li>\n<li>Conversations between design and engineering got more specific and less abstract.</li>\n<li>Designers became more confident in technical discussions.</li>\n</ul>\n<p>The biggest shift was not technical.\r\nIt was psychological.</p>\n<p>They stopped saying:\r\n“I can’t do this because I’m not technical.”</p>\n<p>And started saying:\r\n“Let me prototype this first, then we can refine it together.”</p>\n<hr>\n<h3>Lessons for teams</h3>\n<p>If you want non-technical teammates to learn vibe coding:</p>\n<ul>\n<li>teach workflow, not jargon</li>\n<li>reward practical output, not perfect code</li>\n<li>make collaboration the goal, not role replacement</li>\n<li>keep the loop short and visible</li>\n</ul>\n<p>Most people can learn way more than they think when the environment feels safe.</p>\n<p>And that was the real win at Crossfill.</p>\n<p>It wasn’t just about shipping faster.\r\nIt was about building a team where more people felt empowered to create.</p>"}},{"node":{"frontmatter":{"title":"My First Hiring Experience - Learning That Hiring Is Human","description":"I got asked to do something I had never done","slug":"/blog/hiring-is-human","date":"2025-04-30T00:00:00.000Z","tags":["HR","Culture"],"draft":false},"html":"<p>At my recent company, I got asked to do something I had never done before:\r\nHire a UX designer.</p>\n<p>It might sound simple for someone else, but for me, it felt huge.\r\nI wasn’t some polished recruiter in a fancy suit.\r\nI was a senior engineer with a thick Asian accent, no HR experience, and definitely not a model-looking face to <em>“represent the company.”</em></p>\n<p>Honestly, when the task landed on me, I didn’t know whether to laugh, cry, or just hide under my desk.\r\nMe, being the face of the company during an interview?\r\nI half-joked to myself that this company might go bankrupt if the candidate judged us based on my interview skills.</p>\n<p>Even though I was the one hiring, I prepared for about a full day😅.\r\nI reviewed UX designer resume, thought about possible questions, tried to predict what the candidate might ask about the company, the product, the team — everything.\r\nIt almost felt like <em>I</em> was the one being interviewed.</p>\n<p>The day of the interview, my stomach was twisting a little.\r\nI thought it would be a short, robotic checklist:</p>\n<p><strong><em>\"Hello, can you use Figma? Great. Welcome aboard.\"</em></strong></p>\n<p>But that’s not what happened.</p>\n<p>The conversation flowed.\r\n<em><strong>One hour</strong></em> went by — without me even noticing.\r\nWe didn’t just talk about technical skills; we talked about ideas.\r\nHow they see UX, how we think about product.\r\nWe talked about culture, work philosophy, and the kinds of values we wanted to protect as the team grew.\r\nWe even laughed about random startup chaos stories (because who hasn’t experienced that?).</p>\n<p>By the end of it, I realized something important:</p>\n<ul>\n<li><em>Hiring isn’t about judgment.</em></li>\n<li><em>It’s about connection.</em></li>\n<li><em>It’s about building a bridge between people and business — not just measuring skills on a spreadsheet.</em></li>\n</ul>\n<p>I’m not even sure if the candidate ended up getting the offer.\r\nBut for me, the experience itself was already a win.\r\nI had stepped way outside my comfort zone.\r\nI had grown.\r\nAnd I had learned that even if you feel nervous, imperfect, or unqualified,\r\nyou can still create a real, human connection — and that’s what matters most.</p>\n<p>This experience taught me:</p>\n<ul>\n<li>At the end of the day, hiring is human.</li>\n<li>It’s about empathy.</li>\n<li>It’s about seeing possibility in someone, and offering them a glimpse of the story you’re trying to write together.</li>\n</ul>\n<p>And for a guy who never thought he’d survive an English interview as <em><strong>“the face of the company,”</strong></em>\r\nThat felt like a pretty good first step.</p>"}},{"node":{"frontmatter":{"title":"What \"Customer-Facing\" Really Means To Me","description":"A lot of people think \"custoner-facing\" just","slug":"/blog/into-their-world","date":"2025-03-17T00:00:00.000Z","tags":["Culture","Startup","Customer"],"draft":false},"html":"<p>A lot of people think <strong>\"customer-facing\"</strong> just means respond quickly, stay polite, get the job done.</p>\n<p>But in my mind, that's missing the whole point.</p>\n<p>Being customer-facing means diving headfirst into the customer's world.\r\nIt is about seeing through their eyes, thinking their thoughts, feeling their frustrations and dreams.\r\nYou have to live in their world first - <strong><em>really live there</em></strong> - before you can ever expect them to step into yours.</p>\n<p>It's not just about solving problems.\r\nIt's about <em>showing up</em> with genuine interest, sharing their excitement, building trust, makeing them feel seen.\r\nIf you do it right, you don't just earn a customer - you make a real connection.\r\nThey love working with you, because they feel like you're on their team.</p>\n<p>And from there?</p>\n<ul>\n<li>You can lead them somewhere even better.</li>\n<li>You can open doors they didn't know existed.</li>\n<li>You can create wins together that neither side could've pulled off alone.</li>\n</ul>\n<p>At the end of the day, real business isn't cold - it's emotional.\r\nIf you can make people feel energized, hopeful, proud to work with you...\r\nYou're not just closing deals.\r\nYou're building something that <em>lasts</em>.</p>\n<p>That's the kind of customer-facing mindset I bring.\r\nThat's how I want to build, every day.</p>"}},{"node":{"frontmatter":{"title":"Thomas And The Startup Culture","description":"I worked for 3 startups, as a full-time employee","slug":"/blog/thomas-and-startup-culture","date":"2022-11-30T00:00:00.000Z","tags":["Culture","Startup"],"draft":false},"html":"<p>I worked for 5 startups, as a full-time employee for 2 of them, and a contractor for the other.</p>\n<p>During the process, I taught myself to be creative, innovative and entrepreneurial while delivering what is expected from me - the high-quality software.</p>\n<p>Some of my significant contributions are:</p>\n<ul>\n<li>helping a gaming startup increase the <code class=\"language-text\">annual revenue by 8.9%</code></li>\n<li>helping an AI startup land <code class=\"language-text\">2 rounds of venture funding</code></li>\n<li>helping a drone-tech startup <code class=\"language-text\">sell their business</code></li>\n</ul>\n<p>I engage in my daily endeavors with passion and share the ambition of the team making an impact on people’s lives. This makes me a self-initiator.</p>\n<p><strong>_ People who are passionate can be trained in everything. But we don’t know how to train in attitude. _</strong></p>\n<p>I strongly believe in the above quote, and I personally experienced it while working at startups.\r\nI work hard, be part of the team, and am willing to take challenges as the founders do.</p>\n<p>Fully understanding the startup life, I am ready to jump in and make things right, and very accustomed to wearing many hats whenever needed.</p>\n<p>Things that I take seriously while working at startups are:</p>\n<p>sticking to and living by the company value\r\ngetting to know the team culture and being a happy part of it\r\nopen communication and welcoming constructive criticism\r\nThe strongest personal trait of mine is self-discipline. It breeds many of my positive work ethics.\r\nEveryday is my struggle to build world-class self-discipline. You can try <a href=\"https://30daysofdiscipline.com/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">30 days of discipline</a> too.</p>\n<p>I want to see myself join you in your startup journey and make difference.\r\nUntil then, take care.</p>\n<p>Email me at <a href=\"mailto:tms.doan@gmail.com\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">tms.doan@gmail.com</a>.</p>"}},{"node":{"frontmatter":{"title":"A Journey into Mental Healthcare Innovation","description":"In August 2022, I embarked on a new adventure","slug":"/blog/thomas-and-therify","date":"2022-03-11T00:00:00.000Z","tags":["Culture","Startup","Healthcare"],"draft":false},"html":"<p>In August 2022, I embarked on a new adventure by joining <a href=\"https://therify.co\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Therify</a>, a mental healthcare startup with a powerful vision: to make culturally responsive mental health care accessible to individuals and organizations alike. As someone who thrives on building meaningful products and has a deep interest in startups, this opportunity felt like the perfect alignment of my skills, values, and passions.</p>\n<h1>Why Therify’s Mission Resonated with Me</h1>\n<p>Mental health is a topic close to my heart.\r\nWhen I learned about Therify’s mission—to connect people with therapists who understand their cultural, personal, and professional challenges—I knew this was more than just another tech project. It was a chance to make a real impact.</p>\n<p>As a <strong>product-minded</strong> engineer, I’m not just about writing code.\r\nI’m about solving problems, creating intuitive user experiences, and contributing to business goals.\r\nTherify’s business idea—leveraging technology to empower diverse communities through personalized mental health support—immediately sparked my curiosity.\r\nIt wasn’t just a service; it was a movement to address a critical gap in healthcare.</p>\n<h1>Building with Purpose</h1>\n<p>From the moment I joined, I dove into projects that pushed me to think beyond the technical.\r\nWorking on features like AI-powered therapist matching, secure teletherapy, and analytics for employer insights, I found myself at the intersection of tech innovation and human connection.</p>\n<p>I approached each task with a product-first mindset, always asking:</p>\n<ul>\n<li><em>How does this feature improve the user’s experience?</em></li>\n<li><em>How does it support Therify’s broader mission and business growth?</em></li>\n<li><em>What’s the long-term value we’re creating for individuals and organizations?</em></li>\n</ul>\n<p>Joining a startup like Therify meant stepping into a dynamic, fast-paced environment.\r\nEvery decision felt pivotal, every line of code impactful.\r\nI loved collaborating with a passionate team who shared a common goal: to redefine how mental health care is delivered.</p>\n<p>For me, startups are all about building from the ground up, taking calculated risks, and driving innovation.\r\nTherify was no exception.\r\nIt offered me the chance to combine my technical expertise with my passion for solving meaningful problems, all while contributing to a business idea that truly mattered.</p>\n<h1>Looking Ahead</h1>\n<p>My journey with Therify has reaffirmed my belief in the power of technology to create positive change.\r\nIt’s a reminder that the work we do as engineers isn’t just about software; it’s about people—their needs, their struggles, and their growth.</p>\n<p>Looking back, I’m grateful for the opportunity to join a company that values both innovation and impact.\r\nAnd as we continue to build and grow, I’m excited to see how we can further push the boundaries of what mental health care can achieve.</p>"}},{"node":{"frontmatter":{"title":"Dark Mode Toggle","description":"Dark mode without the flash of default theme","slug":"/blog/dark-mode-toggle","date":"2021-04-21T00:00:00.000Z","tags":["Theming","Dark Mode"],"draft":false},"html":"<p>Dark mode toggle without the flash of default theme. Important bits:</p>\n<ul>\n<li>CSS variables for color theming</li>\n<li>Put <code class=\"language-text\">data-theme</code> attribute on <code class=\"language-text\">&lt;html></code>, not <code class=\"language-text\">&lt;body></code>, so we can run the JS before the DOM finishes rendering</li>\n<li>Run local storage check in the <code class=\"language-text\">&lt;head></code></li>\n<li>JS for toggle button click handler can come after render</li>\n</ul>\n<h2>HTML</h2>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre class=\"language-html\"><code class=\"language-html\"><span class=\"token doctype\"><span class=\"token punctuation\">&lt;!</span><span class=\"token doctype-tag\">DOCTYPE</span> <span class=\"token name\">html</span><span class=\"token punctuation\">></span></span>\r\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>html</span> <span class=\"token attr-name\">lang</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>en<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">data-theme</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>light<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\r\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>head</span><span class=\"token punctuation\">></span></span>\r\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>meta</span> <span class=\"token attr-name\">charset</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>utf-8<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\r\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>meta</span> <span class=\"token attr-name\">name</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>viewport<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">content</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>width=device-width, initial-scale=1.0<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\r\n    ...\r\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>script</span><span class=\"token punctuation\">></span></span><span class=\"token script\"><span class=\"token language-javascript\">\r\n      <span class=\"token comment\">// If there's a theme stored in localStorage, use it on the &lt;html></span>\r\n      <span class=\"token keyword\">const</span> localStorageTheme <span class=\"token operator\">=</span> localStorage<span class=\"token punctuation\">.</span><span class=\"token function\">getItem</span><span class=\"token punctuation\">(</span><span class=\"token string\">'theme'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n      <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>localStorageTheme<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\r\n        document<span class=\"token punctuation\">.</span>documentElement<span class=\"token punctuation\">.</span><span class=\"token function\">setAttribute</span><span class=\"token punctuation\">(</span><span class=\"token string\">'data-theme'</span><span class=\"token punctuation\">,</span> localStorageTheme<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n      <span class=\"token punctuation\">}</span>\r\n    </span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>script</span><span class=\"token punctuation\">></span></span>\r\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>head</span><span class=\"token punctuation\">></span></span>\r\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>body</span><span class=\"token punctuation\">></span></span>\r\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>theme-toggle<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\r\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>button</span>\r\n        <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>theme-toggle-btn js-theme-toggle<span class=\"token punctuation\">\"</span></span>\r\n        <span class=\"token attr-name\">aria-label</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>Activate dark mode<span class=\"token punctuation\">\"</span></span>\r\n        <span class=\"token attr-name\">title</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>Activate dark mode<span class=\"token punctuation\">\"</span></span>\r\n      <span class=\"token punctuation\">></span></span>\r\n        <span class=\"token comment\">&lt;!--\r\n        &lt;svg class=\"light-mode\">\r\n          &lt;use xlink:href=\"#sun\">&lt;/use>\r\n        &lt;/svg>\r\n        &lt;svg class=\"dark-mode\">\r\n          &lt;use xlink:href=\"#moon\">&lt;/use>\r\n        &lt;/svg>\r\n        --></span>\r\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>button</span><span class=\"token punctuation\">></span></span>\r\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\r\n\r\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>script</span> <span class=\"token attr-name\">src</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>app.js<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token script\"></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>script</span><span class=\"token punctuation\">></span></span>\r\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>body</span><span class=\"token punctuation\">></span></span>\r\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>html</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<h2>CSS Variables</h2>\n<div class=\"gatsby-highlight\" data-language=\"css\"><pre class=\"language-css\"><code class=\"language-css\"><span class=\"token selector\">:root</span> <span class=\"token punctuation\">{</span>\r\n  <span class=\"token property\">--bg</span><span class=\"token punctuation\">:</span> #ffffff<span class=\"token punctuation\">;</span>\r\n  <span class=\"token property\">--text</span><span class=\"token punctuation\">:</span> #000000<span class=\"token punctuation\">;</span>\r\n<span class=\"token punctuation\">}</span>\r\n\r\n<span class=\"token selector\">[data-theme='dark']</span> <span class=\"token punctuation\">{</span>\r\n  <span class=\"token property\">--bg</span><span class=\"token punctuation\">:</span> #000000<span class=\"token punctuation\">;</span>\r\n  <span class=\"token property\">--text</span><span class=\"token punctuation\">:</span> #ffffff<span class=\"token punctuation\">;</span>\r\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h2>JavaScript</h2>\n<div class=\"gatsby-code-title\">app.js</div>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> themeToggleBtn <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span><span class=\"token function\">querySelector</span><span class=\"token punctuation\">(</span><span class=\"token string\">'.js-theme-toggle'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n\r\nthemeToggleBtn<span class=\"token punctuation\">.</span><span class=\"token function\">addEventListener</span><span class=\"token punctuation\">(</span><span class=\"token string\">'click'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">onToggleClick</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n\r\n<span class=\"token keyword\">const</span> <span class=\"token function-variable function\">onToggleClick</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\r\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> theme <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span>documentElement<span class=\"token punctuation\">.</span>dataset<span class=\"token punctuation\">;</span>\r\n  <span class=\"token keyword\">const</span> themeTo <span class=\"token operator\">=</span> theme <span class=\"token operator\">&amp;&amp;</span> theme <span class=\"token operator\">===</span> <span class=\"token string\">'light'</span> <span class=\"token operator\">?</span> <span class=\"token string\">'dark'</span> <span class=\"token operator\">:</span> <span class=\"token string\">'light'</span><span class=\"token punctuation\">;</span>\r\n  <span class=\"token keyword\">const</span> label <span class=\"token operator\">=</span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">Activate </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>theme<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\"> mode</span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">;</span>\r\n\r\n  document<span class=\"token punctuation\">.</span>documentElement<span class=\"token punctuation\">.</span><span class=\"token function\">setAttribute</span><span class=\"token punctuation\">(</span><span class=\"token string\">'data-theme'</span><span class=\"token punctuation\">,</span> themeTo<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  localStorage<span class=\"token punctuation\">.</span><span class=\"token function\">setItem</span><span class=\"token punctuation\">(</span><span class=\"token string\">'theme'</span><span class=\"token punctuation\">,</span> themeTo<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n\r\n  themeToggleBtn<span class=\"token punctuation\">.</span><span class=\"token function\">setAttribute</span><span class=\"token punctuation\">(</span><span class=\"token string\">'aria-label'</span><span class=\"token punctuation\">,</span> label<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n  themeToggleBtn<span class=\"token punctuation\">.</span><span class=\"token function\">setAttribute</span><span class=\"token punctuation\">(</span><span class=\"token string\">'title'</span><span class=\"token punctuation\">,</span> label<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<h2>Resources</h2>\n<ul>\n<li><a href=\"https://css-tricks.com/a-complete-guide-to-dark-mode-on-the-web/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://css-tricks.com/a-complete-guide-to-dark-mode-on-the-web/</a></li>\n<li><a href=\"https://css-tricks.com/flash-of-inaccurate-color-theme-fart/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://css-tricks.com/flash-of-inaccurate-color-theme-fart/</a></li>\n<li><a href=\"https://mxb.dev/blog/color-theme-switcher/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://mxb.dev/blog/color-theme-switcher/</a></li>\n<li><a href=\"https://www.joshwcomeau.com/react/dark-mode/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://www.joshwcomeau.com/react/dark-mode/</a></li>\n<li><a href=\"https://web.dev/prefers-color-scheme/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://web.dev/prefers-color-scheme/</a></li>\n</ul>"}},{"node":{"frontmatter":{"title":"Accessible Clickable Cards","description":"Clickable cards with multiple child links","slug":"/blog/clickable-cards","date":"2021-04-21T00:00:00.000Z","tags":["Accessibility","CSS"],"draft":false},"html":"<p><a href=\"https://codepen.io/code-n-cool/pen/xxRBvgd?editors=1100\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Codepen Demo</a></p>\n<p>Card layout where the card itself isn't an anchor link, but the whole card is clickable (with a <code class=\"language-text\">:before</code> pseudo element on the main <code class=\"language-text\">&lt;a></code>). Links inside of the card are still clickable.</p>\n<h2>CSS</h2>\n<div class=\"gatsby-highlight\" data-language=\"css\"><pre class=\"language-css\"><code class=\"language-css\"><span class=\"token selector\">.grid__item</span> <span class=\"token punctuation\">{</span>\r\n  <span class=\"token selector\">&amp;:hover,\r\n  &amp;:focus-within</span> <span class=\"token punctuation\">{</span>\r\n    <span class=\"token property\">background-color</span><span class=\"token punctuation\">:</span> #eee<span class=\"token punctuation\">;</span>\r\n  <span class=\"token punctuation\">}</span>\r\n\r\n  <span class=\"token selector\">a</span> <span class=\"token punctuation\">{</span>\r\n    <span class=\"token property\">position</span><span class=\"token punctuation\">:</span> relative<span class=\"token punctuation\">;</span>\r\n    <span class=\"token property\">z-index</span><span class=\"token punctuation\">:</span> 1<span class=\"token punctuation\">;</span>\r\n  <span class=\"token punctuation\">}</span>\r\n\r\n  <span class=\"token selector\">h2</span> <span class=\"token punctuation\">{</span>\r\n    <span class=\"token selector\">a</span> <span class=\"token punctuation\">{</span>\r\n      <span class=\"token property\">position</span><span class=\"token punctuation\">:</span> static<span class=\"token punctuation\">;</span>\r\n\r\n      <span class=\"token selector\">&amp;:hover,\r\n      &amp;:focus</span> <span class=\"token punctuation\">{</span>\r\n        <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> blue<span class=\"token punctuation\">;</span>\r\n      <span class=\"token punctuation\">}</span>\r\n\r\n      <span class=\"token selector\">&amp;:before</span> <span class=\"token punctuation\">{</span>\r\n        <span class=\"token property\">content</span><span class=\"token punctuation\">:</span> <span class=\"token string\">''</span><span class=\"token punctuation\">;</span>\r\n        <span class=\"token property\">display</span><span class=\"token punctuation\">:</span> block<span class=\"token punctuation\">;</span>\r\n        <span class=\"token property\">position</span><span class=\"token punctuation\">:</span> absolute<span class=\"token punctuation\">;</span>\r\n        <span class=\"token property\">z-index</span><span class=\"token punctuation\">:</span> 0<span class=\"token punctuation\">;</span>\r\n        <span class=\"token property\">width</span><span class=\"token punctuation\">:</span> 100%<span class=\"token punctuation\">;</span>\r\n        <span class=\"token property\">height</span><span class=\"token punctuation\">:</span> 100%<span class=\"token punctuation\">;</span>\r\n        <span class=\"token property\">top</span><span class=\"token punctuation\">:</span> 0<span class=\"token punctuation\">;</span>\r\n        <span class=\"token property\">left</span><span class=\"token punctuation\">:</span> 0<span class=\"token punctuation\">;</span>\r\n        <span class=\"token property\">transition</span><span class=\"token punctuation\">:</span> background-color 0.1s ease-out<span class=\"token punctuation\">;</span>\r\n        <span class=\"token property\">background-color</span><span class=\"token punctuation\">:</span> transparent<span class=\"token punctuation\">;</span>\r\n      <span class=\"token punctuation\">}</span>\r\n    <span class=\"token punctuation\">}</span>\r\n  <span class=\"token punctuation\">}</span>\r\n<span class=\"token punctuation\">}</span></code></pre></div>"}},{"node":{"frontmatter":{"title":"Writing Is Hard","description":"I have the hardest time with creative writing","slug":"/blog/writing-is-hard","date":"2021-04-21T00:00:00.000Z","tags":["Blogging","Culture"],"draft":false},"html":"<p>I have the hardest time with creative writing. Producing a continuous flow of words should be easier than this.</p>\n<p>Even now, I’m tempted to spin that previous sentence around in my head over and over, thinking about how I could word it better, or how I could make the point more creatively.</p>\n<p>But you know what? I won’t! Because it states exactly my point, and it’s fine the way it is.</p>\n<p>I feel like I have tons of ideas, bouncing from one thought to another, making intuitive leaps, and it is just a challenge to get it written down. By the time I’m half way through a sentence, I’ve already made several parallel branches in my head of new possibilities I want to go to.</p>\n<p>And by the time I finally get something together, I run it through the ol’ meat grinder over and over again, before scrapping it. What a chore!</p>\n<p>It almost feels like being lost in the woods, constantly backtracking, doubting where I am going.</p>\n<p><strong>There is nothing to writing. All you do is sit down at a typewriter and bleed.</strong> <em>* Ernest Hemmingway *</em></p>\n<p>Thinking, on the other hand, comes naturally. I can get lost in thought for great gulfs of time. But putting those thoughts into concise sentences in writing is always a challenge. For some reason, it’s much easier to do it in real time whilst babbling out words to a person directly with my mouth.</p>\n<p>The only writing I am used to is technical writing, where specificity and clarity is key. Creative writing is much more challenging. And to a logic-worshiping creature such as myself that always sees the world through a lens of rationality, it is fairly easy to visualize what I am trying to accomplish with technical writing. This is not so with creative writing.</p>\n<p>With technical writing, the outline, structure, and details sort of just materialize on their own. I guess this is because is all makes perfectly logic sense up front in the first place, and my job at that point is to communicate it clearly.</p>\n<p>This is very different than communicating creatively.</p>\n<p>With creative writing, I find myself endlessly polishing, rewording, and tweaking what I write, which turns writing into an ordeal for me. I end up with a jumbled mess of ideas scattered around, before thinking up more topics of blog posts I suddenly become passionate about and move onto.</p>\n<p>Seriously, I must have like a dozen unfinished posts now.</p>\n<p>So instead of applying my tried-and-true technical writing approach to creative writing, I’m trying something new. I’m writing in near stream-of-conscious. And I’m not going to go back and doubt every little word in every sentence.</p>\n<p>I’m currently reading the diary of Anne Frank. For a young teenager scribbling away in a diary that she probably thought nobody would ever read, she sure is an excellent writer. And a creative one at that.</p>\n<p>In fact, she writes better than most blog I’ve seen. I’m not sure if it’s because she wasn’t overthinking it, of if she just had a unique combination of maturity, individuality, and intelligence for her age, or if she was a natural-born writer who would’ve blossomed into a successful writing career had she survived into adulthood..</p>\n<p>[…]</p>\n<p>.. ok, back. From a sudden Anne Frank <a href=\"http://www.urbandictionary.com/define.php?term=wiki%20spiral\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Wikipedia spiral</a>. Anyways, I wish I could write as easily as Anne Frank.</p>\n<p>Moving along though, I have a great interest in writing. Not my writing, gods no. But in the writing of others. Introspective perception is what it’s all about for me.</p>\n<p>Reading is one of my favorite pastimes, and one thing I really appreciate is all the little nuances authors go through in their writing; the way they spin words and play with them, the sort of imagery they invoke, and the chain reaction of thought they’re able to trigger with the shortest of sentences.</p>\n<p>Underground and 90’s gangster rappers excel in this regard, exceptionally so.</p>\n<p>So let’s see here. I’ve managed to jump topics from writing perfectionism, to technical writing and thinking, to all my unfinished posts, to Anne Frank, to books, and then to rappers.</p>\n<p>And I’m ok with that. Perhaps it’s better this way.</p>\n<p>And hey, that was actually pretty fun that time.</p>"}},{"node":{"frontmatter":{"title":"SOLID Principles Checklist (in Python)","description":"With so many soliloquies of SOLID Principles online","slug":"/blog/solid-principles-checklist","date":"2020-09-20T00:00:00.000Z","tags":["Blogging","Tech"],"draft":false},"html":"<p>With so many soliloquies of SOLID Principles online, ripe with the same old definitions, theoretical verbosity, and yet, the most basic of examples, I’ve always found it difficult to digest and keep it all in mind while developing.</p>\n<p>So I wanted to create a condensed checklist that is wall hang-worthy.</p>\n<h2>SOLID Principles Checklist</h2>\n<ul>\n<li>SOLID is a means to an end, not an end in itself</li>\n<li>The end is maintainability.</li>\n<li>SOLID dogmatism should not dirty the code with Needless Complexity</li>\n</ul>\n<h2>Single Responsibility Principle</h2>\n<ul>\n<li>Each class does one thing and does one thing well</li>\n<li>Each method in a class does one thing and does one thing well</li>\n<li>If a classes’ behavior ever changed, it should impact most of its methods</li>\n<li>Aim for short enough methods that can fit on your screen</li>\n<li>Avoid numerous parameters in methods</li>\n</ul>\n<h2>Open Closed Principle</h2>\n<p>When adding a new functionality</p>\n<ul>\n<li>Base entities aren’t modified (closed for modification)</li>\n<li>Other entities extend the base entity (open for extension)</li>\n<li>Use interface, a module in Python, as the base entity</li>\n<li>Opt for composition over inheritance when an interface is not enough</li>\n</ul>\n<h2>Liskov Substitution Principle</h2>\n<p>In class inheritance</p>\n<ul>\n<li>Subclass add to the base class’s behavior</li>\n<li>Subclass doesn’t replace the base class’s behavior</li>\n<li>Parent instance is replaceable with any of child instances w/o side effects</li>\n</ul>\n<h2>Interface Segregation Principle</h2>\n<ul>\n<li>Base class shouldn’t be generalized</li>\n<li>A class shouldn’t have any methods it doesn’t use</li>\n<li>Multiple interfaces, modules in Python, are better than one</li>\n</ul>\n<h2>Dependency Inversion Principle</h2>\n<ul>\n<li>A class shouldn’t depend on a specific type of class</li>\n<li>Avoid changing the class implementation because of a dependency</li>\n<li>The dependency should be abstracted (generalized)</li>\n<li>Use Dependency Injection</li>\n<li>OCP + LSP = DIP!</li>\n</ul>\n<h3>Further Readings</h3>\n<p>Following is a famous visualisation of the SOLID principles by a Medium author.\r\n<a href=\"https://medium.com/backticks-tildes/the-s-o-l-i-d-principles-in-pictures-b34ce2f1e898\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">The S.O.L.I.D Principles in Pictures by Ugonna Thelma</a></p>\n<p>It is common that we go adrift in the profoundness of the principles and concepts, but they could be readily mastered through constant reminders and learning the perspectives of other great minds.</p>"}},{"node":{"frontmatter":{"title":"Documenting Database Design","description":"Documenting database design just seems to be one of","slug":"/blog/documentating-database-design","date":"2020-07-30T00:00:00.000Z","tags":["Culture","Tech"],"draft":false},"html":"<p>Documenting database design just seems to be one of those things that web developers tend to suck at.</p>\n<p>I have some theories as to why:</p>\n<ul>\n<li>draws on writing &#x26; design talents, rather than just technical talents</li>\n<li>is usually about the business domain, not the application itself</li>\n<li>can be boring and tedious</li>\n</ul>\n<p>If done before coding, it becomes quickly out of date. If done after coding, it probably never gets done at all.</p>\n<p>The odds are further stacked against web developers since conventions and techniques for documenting databases rarely gets brought up, ever.</p>\n<p>All the focus goes into the relationships, modeling, and queries.</p>\n<h3>Garbage In, Garbage Out</h3>\n<p>The first step to having good documentation is having good database design in the first place.</p>\n<p>If there is a convoluted design, expect convoluted documentation. In fact, expect convoluted data models and business logic in the application itself, too.</p>\n<p>Be ruthless about:</p>\n<ul>\n<li>modeling of business domain into tables in a non-technical manner\n<ul>\n<li>ie. so easy a caveman business person can (mostly) visualize it</li>\n</ul>\n</li>\n<li>well-defined tables with a clear, single purpose</li>\n<li>foreign key relationships enforced on every table</li>\n<li>consistent table/column naming</li>\n<li>normalization</li>\n</ul>\n<h3>Where the Pristine Runs Afoul</h3>\n<p>The design always seems to start off solid, but as development progresses, corners get cut, and before you know it, those pristine tables are full of little hacks that were thrown in last minute.</p>\n<p>Sometimes it’s the removal of no-longer-needed columns, rendering a once-useful table into something no longer needed itself.</p>\n<p>You then end up with this leftover.. thing, that keeps getting populated by the application. It gets even worse when its sole purpose in life becomes holding up foreign key constraints between other tables.</p>\n<p>Other times, ultra-specific, awkwardly-named columns get added to an existing table due to convenience, which often turns into an eyebrow raiser for the next developer that has to figure out what the column does, and why it’s in that table.</p>\n<p>In worst cases, flag or enum-type columns get added to allow rows to have their own state, effectively denormalizing the table.</p>\n<p>And somewhere in the spacetime continuum, or perhaps outside of it, the gods weep.</p>\n<p>It’s these sort of last minute, weird, stupid things that fouls up pristine database design, and makes documentation that more difficult and verbose. To this, I say: always refactor, no matter the risk.</p>\n<h3>What to Document</h3>\n<p>Moving along, I find those following the most important to document:</p>\n<ul>\n<li>High-level ER diagram showing relationships, primary &#x26; foreign keys</li>\n<li>Short descriptions for all tables at the conceptual/business domain level</li>\n<li>Explanations or notes for columns only if they are not self-evident</li>\n<li>Example Data For Each Column</li>\n</ul>\n<p>Sometimes you will be stuck with weird columns or tables that are not self-evident as to what they are for. This is what should be documented.</p>\n<p>Redundantly documenting anything that is already self-evident adds noise and buries the tasty morsels that readers should be drooling over.</p>\n<p>This applies to code, for that matter.</p>\n<h4>Table Descriptions</h4>\n<p>Expanding on the table descriptions part, provide a summary for each table:</p>\n<ul>\n<li>The kind of object the table represents</li>\n<li>The table’s purpose (in brief, conceptual language)</li>\n<li>Foreign key relationships it has with other tables\n<ul>\n<li>ie belongs-to and has-a relationships</li>\n<li>as in: “orders belongs to carts”, “orders has a items”</li>\n</ul>\n</li>\n<li>Description &#x26; gotchas for the columns that are not self-evident</li>\n<li>Example of the data expected in each column, for all columns\n<ul>\n<li>If acts as an enum (such as a list of possible status), then list all values</li>\n</ul>\n</li>\n</ul>\n<h3>Shut up About the Application</h3>\n<p>I don’t believe in going into detail about how the data may power things on the user interface, or what controllers use the data models, and so forth.</p>\n<p>The database design should stand on its own, regardless of what application, services, or views are using it.</p>\n<h3>Diagrams</h3>\n<p>ER diagrams really helps one to see how everything fits together at a glance.</p>\n<p>If there are a lot of tables, I find that it helps to break up the tables into clusters which share foreign key relationships, rather than provide a single overview that is not even readable.</p>\n<p>Always generate ER diagrams, don’t even consider making one by hand for a second. For MySQL, there is the free <a href=\"https://www.mysql.com/products/workbench/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">MySQL Workbench</a>.</p>"}},{"node":{"frontmatter":{"title":"BEM and SASS in ReactJS Applications","description":"Unless you are using Styled-components for","slug":"/blog/bem-sass-react","date":"2020-05-19T00:00:00.000Z","tags":["Blogging","Tech"],"draft":false},"html":"<p>Unless you are using Styled-components for styling ReactJS components, the choice of class naming convention directly affects the productivity and more.</p>\n<p>There’s no argue why we should be using some CSS preprocessors instead of plain CSS. Read through <a href=\"https://www.mugo.ca/blog/7-benefits-of-using-SASS-over-conventional-CSS\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">7 benefits of using SASS</a> over conventional CSS to remind yourself of why.\r\nSASS provides 2 different syntaxes - SASS and SCSS. I prefer SCSS as it is CSS-compatible, meaning that when you rename your CSS file from XYZ.css to XYZ.scss, it immediately becomes a valid SCSS file.</p>\n<p>Now, what is BEM?\r\nBEM, which stands for Block-Element-Modifier, is one of the most well-accepted CSS naming conventions.\r\nTo give you a quick &#x26; easy overview of what BEM looks like:</p>\n<h3>Block (B)</h3>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>book<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">...</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\r\n<span class=\"token punctuation\">.</span>book <span class=\"token punctuation\">{</span>\r\n  <span class=\"token literal-property property\">color</span><span class=\"token operator\">:</span> #<span class=\"token constant\">EFEFEF</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h3>Element (E)</h3>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>book<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\r\n  ...\r\n  </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>span</span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>book__author<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>span</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\r\n</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\r\n<span class=\"token punctuation\">.</span>book__author <span class=\"token punctuation\">{</span>\r\n  <span class=\"token literal-property property\">color</span><span class=\"token operator\">:</span> #<span class=\"token number\">004345</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h3>Modifier (M)</h3>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>book book--sold<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">...</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\r\n<span class=\"token punctuation\">.</span>book<span class=\"token operator\">--</span>sold <span class=\"token punctuation\">{</span>\r\n  text<span class=\"token operator\">-</span>decoration<span class=\"token operator\">:</span> stroke<span class=\"token punctuation\">;</span>\r\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>(reference: <a href=\"http://getbem.com/naming/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">BEM — Block Element Modifier</a>)</p>\n<p>Besides enabling a global naming rule for your project and the team, BEM provides several other advantages.</p>\n<ul>\n<li>Better HTML/CSS decoupling</li>\n<li>Better CSS performance</li>\n<li>No CSS conflicts</li>\n<li>Ease of code maintenance</li>\n</ul>\n<p>(reference: <a href=\"https://www.altitudesystems.co.uk/blog/2017/july/to-bem-or-not-to-bem-that-is-the-question\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">To BEM or not to BEM? That is the question.</a>)\r\nBEM couples well with SCSS syntax. Imagine you write CSS rules for a book element.</p>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre class=\"language-html\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>book<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\r\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>span</span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>book__author<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>Napoleon Hill<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>span</span><span class=\"token punctuation\">></span></span>\r\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>span</span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>book__title<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>Think and Grow Rich<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>span</span><span class=\"token punctuation\">></span></span>\r\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\r\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>book book--sold<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\r\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>span</span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>book__author<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>David Schwartz<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>span</span><span class=\"token punctuation\">></span></span>\r\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>span</span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>book__title<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>The Magic of Thinking Big<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>span</span><span class=\"token punctuation\">></span></span>\r\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"css\"><pre class=\"language-css\"><code class=\"language-css\"><span class=\"token selector\">.book</span> <span class=\"token punctuation\">{</span> <span class=\"token property\">background-color</span><span class=\"token punctuation\">:</span> black<span class=\"token punctuation\">;</span> <span class=\"token punctuation\">}</span>\r\n<span class=\"token selector\">.book__author</span> <span class=\"token punctuation\">{</span> <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> white<span class=\"token punctuation\">;</span> <span class=\"token punctuation\">}</span>\r\n<span class=\"token selector\">.book__title</span> <span class=\"token punctuation\">{</span> <span class=\"token property\">font-weight</span><span class=\"token punctuation\">:</span> bold<span class=\"token punctuation\">;</span> <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> white<span class=\"token punctuation\">;</span> <span class=\"token punctuation\">}</span>\r\n<span class=\"token selector\">.book--sold</span> <span class=\"token punctuation\">{</span> <span class=\"token property\">text-decoration</span><span class=\"token punctuation\">:</span> stroke<span class=\"token punctuation\">;</span> <span class=\"token punctuation\">}</span></code></pre></div>\n<p>Let’s rewrite this rule in SCSS.</p>\n<div class=\"gatsby-highlight\" data-language=\"css\"><pre class=\"language-css\"><code class=\"language-css\"><span class=\"token selector\">.book</span> <span class=\"token punctuation\">{</span>\r\n  <span class=\"token property\">background-color</span><span class=\"token punctuation\">:</span> black<span class=\"token punctuation\">;</span>\r\n  \r\n  <span class=\"token selector\">&amp;__author</span> <span class=\"token punctuation\">{</span>\r\n    <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> white<span class=\"token punctuation\">;</span>\r\n  <span class=\"token punctuation\">}</span>\r\n  <span class=\"token selector\">&amp;__title</span> <span class=\"token punctuation\">{</span>\r\n    <span class=\"token property\">font-weight</span><span class=\"token punctuation\">:</span> bold<span class=\"token punctuation\">;</span>\r\n    <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> white<span class=\"token punctuation\">;</span>\r\n  <span class=\"token punctuation\">}</span>\r\n  \r\n  <span class=\"token selector\">&amp;--sold</span> <span class=\"token punctuation\">{</span>\r\n    <span class=\"token property\">text-decoration</span><span class=\"token punctuation\">:</span> stroke<span class=\"token punctuation\">;</span>\r\n  <span class=\"token punctuation\">}</span>\r\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>The nested syntax of SCSS plays a major role in the beauty of BEM blended in SCSS.</p>\n<p>With the basic knowledge of SCSS and BEM so far, let’s explore my self-found best practice for writing component styles using them.\r\nLet us assume that we are working on a project structure like the following:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">project\r\n - src\r\n   - components\r\n     - Book.jsx\r\n     - Book.style.scss\r\n     - Article.jsx\r\n     - Article.style.scss\r\n     - <span class=\"token punctuation\">..</span>.\r\n   - containers\r\n     - Archive.container.jsx\r\n     - Archive.style.scss\r\n     - <span class=\"token punctuation\">..</span>.\r\n   - styles\r\n   - utils\r\n - node_modules\r\n - <span class=\"token punctuation\">..</span>.</code></pre></div>\n<p>One of the common misconceptions when writing a component style is ignoring the name conflicts.\r\nImagine we write styles for Book component and Article component separately.</p>\n<div class=\"gatsby-code-title\">highlight.js</div>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token operator\">...</span>\r\n<span class=\"token keyword\">import</span> <span class=\"token string\">'./Book.style.scss'</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token operator\">...</span>\r\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> author<span class=\"token punctuation\">,</span> title <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span>\r\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span> <span class=\"token attr-name\">className</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>book<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\r\n    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>span</span> <span class=\"token attr-name\">className</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>author<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>author<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>span</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\r\n    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>span</span> <span class=\"token attr-name\">className</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>title<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>title<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>span</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\r\n    ...\r\n  </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\r\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<div class=\"gatsby-code-title\">Book.style.scss</div>\n<div class=\"gatsby-highlight\" data-language=\"css\"><pre class=\"language-css\"><code class=\"language-css\"><span class=\"token selector\">.author</span> <span class=\"token punctuation\">{</span> <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> white<span class=\"token punctuation\">;</span> <span class=\"token punctuation\">}</span>\r\n<span class=\"token selector\">.title</span> <span class=\"token punctuation\">{</span> <span class=\"token property\">font-weight</span><span class=\"token punctuation\">:</span> bold<span class=\"token punctuation\">;</span> <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> white<span class=\"token punctuation\">;</span> <span class=\"token punctuation\">}</span></code></pre></div>\n<div class=\"gatsby-code-title\">Article.jsx</div>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token operator\">...</span>\r\n<span class=\"token keyword\">import</span> <span class=\"token string\">'./Article.style.scss'</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token operator\">...</span>\r\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> author<span class=\"token punctuation\">,</span> title <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span>\r\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span> <span class=\"token attr-name\">className</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>article<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\r\n    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>span</span> <span class=\"token attr-name\">className</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>author<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>author<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>span</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\r\n    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>span</span> <span class=\"token attr-name\">className</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>title<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>title<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>span</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\r\n    ...\r\n  </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\r\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<div class=\"gatsby-code-title\">Article.style.scss</div>\n<div class=\"gatsby-highlight\" data-language=\"scss\"><pre class=\"language-scss\"><code class=\"language-scss\"><span class=\"token selector\">.author </span><span class=\"token punctuation\">{</span> <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> blue<span class=\"token punctuation\">;</span> <span class=\"token punctuation\">}</span>\r\n<span class=\"token selector\">.title </span><span class=\"token punctuation\">{</span> <span class=\"token property\">text-decoration</span><span class=\"token punctuation\">:</span> underline<span class=\"token punctuation\">;</span> <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> blue<span class=\"token punctuation\">;</span> <span class=\"token punctuation\">}</span></code></pre></div>\n<p>One could falsely assume that these two styles are kept local to the respective components, but they are not. As and when these two components render on the same page, the unwanted conflicts of CSS rules occur.\r\nNote the resulting HTML page source:</p>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre class=\"language-html\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>body</span><span class=\"token punctuation\">></span></span>\r\n  ...\r\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>book<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\r\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>span</span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>author<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>Napoleon Hill<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>span</span><span class=\"token punctuation\">></span></span>\r\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>span</span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>title<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>Think and Grow Rich<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>span</span><span class=\"token punctuation\">></span></span>\r\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\r\n  ...\r\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>article<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\r\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>span</span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>author<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>danny liu<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>span</span><span class=\"token punctuation\">></span></span>\r\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>span</span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>title<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>BEM and SCSS in ReactJS applications<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>span</span><span class=\"token punctuation\">></span></span>\r\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\r\n  ...\r\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>body</span><span class=\"token punctuation\">></span></span>\r\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>style</span><span class=\"token punctuation\">></span></span><span class=\"token style\"><span class=\"token language-css\">\r\n  <span class=\"token selector\">...\r\n  .author</span> <span class=\"token punctuation\">{</span> <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> white<span class=\"token punctuation\">;</span> <span class=\"token punctuation\">}</span>\r\n  <span class=\"token selector\">.title</span> <span class=\"token punctuation\">{</span> <span class=\"token property\">font-weight</span><span class=\"token punctuation\">:</span> bold<span class=\"token punctuation\">;</span> <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> white<span class=\"token punctuation\">;</span> <span class=\"token punctuation\">}</span>\r\n  <span class=\"token selector\">...\r\n  .author</span> <span class=\"token punctuation\">{</span> <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> blue<span class=\"token punctuation\">;</span> <span class=\"token punctuation\">}</span>\r\n  <span class=\"token selector\">.title</span> <span class=\"token punctuation\">{</span> <span class=\"token property\">text-decoration</span><span class=\"token punctuation\">:</span> underline<span class=\"token punctuation\">;</span> <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> blue<span class=\"token punctuation\">;</span> <span class=\"token punctuation\">}</span>\r\n  ...\r\n</span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>style</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<p>The prettiest solution to the above issue is applying scopes, the unique namespaces, for each component style definitions.</p>\n<div class=\"gatsby-code-title\">Book.style.scss</div>\n<div class=\"gatsby-highlight\" data-language=\"css\"><pre class=\"language-css\"><code class=\"language-css\"><span class=\"token selector\">.book</span> <span class=\"token punctuation\">{</span>\r\n  <span class=\"token selector\">.author</span> <span class=\"token punctuation\">{</span>\r\n    <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> white<span class=\"token punctuation\">;</span>\r\n  <span class=\"token punctuation\">}</span>\r\n  <span class=\"token selector\">.title</span> <span class=\"token punctuation\">{</span>\r\n    <span class=\"token property\">font-weight</span><span class=\"token punctuation\">:</span> bold<span class=\"token punctuation\">;</span>\r\n    <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> white<span class=\"token punctuation\">;</span>\r\n  <span class=\"token punctuation\">}</span>\r\n<span class=\"token punctuation\">}</span></code></pre></div>\n<div class=\"gatsby-code-title\">Article.style.scss</div>\n<div class=\"gatsby-highlight\" data-language=\"scss\"><pre class=\"language-scss\"><code class=\"language-scss\"><span class=\"token selector\">.article </span><span class=\"token punctuation\">{</span>\r\n  <span class=\"token selector\">.author </span><span class=\"token punctuation\">{</span>\r\n    <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> blue<span class=\"token punctuation\">;</span>\r\n  <span class=\"token punctuation\">}</span>\r\n  <span class=\"token selector\">.title </span><span class=\"token punctuation\">{</span>\r\n    <span class=\"token property\">text-decoration</span><span class=\"token punctuation\">:</span> underline<span class=\"token punctuation\">;</span>\r\n    <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> blue<span class=\"token punctuation\">;</span>\r\n  <span class=\"token punctuation\">}</span>\r\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>If you chose to use BEM, the namespacing of component styles would come naturally, and you don’t need to stress about remembering it every time. Meanwhile, your application benefits from the aforementioned BEM advantages as well.</p>\n<div class=\"gatsby-code-title\">Book.style.scss</div>\n<div class=\"gatsby-highlight\" data-language=\"scss\"><pre class=\"language-scss\"><code class=\"language-scss\"><span class=\"token selector\">.book </span><span class=\"token punctuation\">{</span>\r\n  <span class=\"token selector\"><span class=\"token parent important\">&amp;</span>__author </span><span class=\"token punctuation\">{</span>\r\n    <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> white<span class=\"token punctuation\">;</span>\r\n  <span class=\"token punctuation\">}</span>\r\n  <span class=\"token selector\"><span class=\"token parent important\">&amp;</span>__title </span><span class=\"token punctuation\">{</span>\r\n    <span class=\"token property\">font-weight</span><span class=\"token punctuation\">:</span> bold<span class=\"token punctuation\">;</span>\r\n    <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> white<span class=\"token punctuation\">;</span>\r\n  <span class=\"token punctuation\">}</span>\r\n<span class=\"token punctuation\">}</span></code></pre></div>\n<div class=\"gatsby-code-title\">Article.style.scss</div>\n<div class=\"gatsby-highlight\" data-language=\"scss\"><pre class=\"language-scss\"><code class=\"language-scss\"><span class=\"token selector\">.article </span><span class=\"token punctuation\">{</span>\r\n  <span class=\"token selector\"><span class=\"token parent important\">&amp;</span>__author </span><span class=\"token punctuation\">{</span>\r\n    <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> blue<span class=\"token punctuation\">;</span>\r\n  <span class=\"token punctuation\">}</span>\r\n  <span class=\"token selector\"><span class=\"token parent important\">&amp;</span>__title </span><span class=\"token punctuation\">{</span>\r\n    <span class=\"token property\">text-decoration</span><span class=\"token punctuation\">:</span> underline<span class=\"token punctuation\">;</span>\r\n    <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> blue<span class=\"token punctuation\">;</span>\r\n  <span class=\"token punctuation\">}</span>\r\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p><strong>Caution</strong>: Stick to the habit of assigning UNIQUE class names to the root DOM elements of your components. Otherwise, the conflicts of CSS rules will happen.</p>"}},{"node":{"frontmatter":{"title":"Developer's Dilemma - Folder Structure and Component Naming","description":"I bet, for many developers or for me at least, there’s","slug":"/blog/folder-structure-n-component-naming","date":"2020-05-14T00:00:00.000Z","tags":["Blogging","Tech"],"draft":false},"html":"<p>I bet, for many developers or for me at least, there’s often a dilemma in the initial phase of a development project.\r\nThat is …</p>\n<p><strong>_ How to set up the folder structure and file naming conventions, a.k.a the project structure? _</strong></p>\n<p>Project structure plays a critical role in the long-term productivity, maintainability and architectural excellency of any development project.\r\nHaving laid it out myself as well as worked on someone else’s setup, I learned it the hard way.</p>\n<p>As ReactJS is my primary FE library of choice, this article will depict a sample ReactJS project and its structure.</p>\n<p><code class=\"language-text\">Precaution: Nothing here is written in rocks, the methodology I am describing here is just one of many approaches 😏</code></p>\n<h3>Folder Structure</h3>\n<p>One of the questions I often face is regarding to how structure files and folders. In this post, I am starting off with a minimum structure, the one created with create-react-app.\r\nThe <code class=\"language-text\">create-react-app</code> generates a basic project for us, containing in its root, the files: <code class=\"language-text\">.gitignore</code>, <code class=\"language-text\">package.json</code>, <code class=\"language-text\">README.md</code>, <code class=\"language-text\">yarn.lock</code></p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 320px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/118946372103c6d0c9ea7b0d4e13bcab/4e610/create-react-app-structure.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 119.42857142857142%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAYCAYAAAD6S912AAAACXBIWXMAAAsTAAALEwEAmpwYAAACeklEQVQ4y52V2ZKaQBSG5wGSqowLoKwKKioqmw3N6pbJVd7/YTL0mTrtEh1FLS9OQQt+/P9Zut9k1arsscuGoxlzZgGbTH3W6faY1DFqQ5T0uvh80/QRo8kaknQN5eoPZPkWZLkPbUEFQdRuhijpIHWM0/UYoqRXb4KoMU0fwmweMlRKkxXzA8ryYsd2H39ZUe5YFBV8necbRmnJFMVkgqRfqD0BcSErJgfO5iHMXQLLZQq2PQfdGPHAD+rG//iu7gqIi/HERWUQhCnk+QYGgyk0W8pTlq+AnW4P7PGCuV4MYZjyl369SzyP5zn6lq/bCg95gK7cZ72+DYPRDFwvgsnUw49cJb4Gfm0Zi4O5NK0pZNkGoiiHIExeB+JV1Sywhg7QZAXhAdZodm/afAqoqBZYA4f3IkJRoTML7sLuAtFyrz/mdhcuAc+LwXUjwKK9BOSWB1NIMIdxAWm2AdOaQKutvm7ZNCcQLlNud+r4D9U9tIxVjmkJlJbguoTDELqP2734EIhF8fwYSJRz0Hujy6t9jGZbuZiWmj7c5xCLgnZJlJ2szxeEr5ckBc+nvPKy0q9XeHjAc4jAothBlm8OwD0EN4wgoPw336eg1AERhAPf648Z2o3iEopiC4RkuGHAj5+tC7vcckuut3ycZVkxGW5VqIYm5X70goRbRuX4B8znw6Kcbw5GzwZCct6Dq/UHV7kkGQeKovZc25wDVW0IJC4gz7dQrn7Dfn9MUP3zk3LMoW6M2GDoMNeL2MKNWBQXzHGCi4Pp3gF1pRBtoWU8Bmx7wWcYx1C4Y/WGUt42n3iDIYha1WzJVautVI2mXLUFtZI6RnV8/kT8+wLyU5eXoyEJYgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"initial structure by create-react-app\"\n        title=\"initial structure by create-react-app\"\n        src=\"/static/118946372103c6d0c9ea7b0d4e13bcab/4e610/create-react-app-structure.png\"\n        srcset=\"/static/118946372103c6d0c9ea7b0d4e13bcab/1aaec/create-react-app-structure.png 175w,\n/static/118946372103c6d0c9ea7b0d4e13bcab/4e610/create-react-app-structure.png 320w\"\n        sizes=\"(max-width: 320px) 100vw, 320px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>It also generates the folders: <code class=\"language-text\">public</code> and <code class=\"language-text\">src</code>. The last one is where we keep our source code.</p>\n<h3>Containers and Components</h3>\n<p>I tried the separation between Containers and Presentation Components in the project’s root folder. I mean, inside src, I had a folder named <code class=\"language-text\">components</code> and another folder named <code class=\"language-text\">containers</code>:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 554px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/ce4b77fdb385d322337943cd72bb030c/5c9af/component-container-sep.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 17.71428571428571%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAS0lEQVQY06XMsREAIQhEUfqvjcDUCnBMlIBBSNYxuAaO4M2PdikikJl4PeeU0RgDIoI5J/beUNXf3p5aa2Bm9N6x1qofmhk+7l52AYToMz+XPSJhAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"following the conceptual separation in the project structure\"\n        title=\"following the conceptual separation in the project structure\"\n        src=\"/static/ce4b77fdb385d322337943cd72bb030c/5c9af/component-container-sep.png\"\n        srcset=\"/static/ce4b77fdb385d322337943cd72bb030c/1aaec/component-container-sep.png 175w,\n/static/ce4b77fdb385d322337943cd72bb030c/98287/component-container-sep.png 350w,\n/static/ce4b77fdb385d322337943cd72bb030c/5c9af/component-container-sep.png 554w\"\n        sizes=\"(max-width: 554px) 100vw, 554px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>However, this kind of approach introduced some issues like:</p>\n<ul>\n<li>Subjectives rules</li>\n</ul>\n<p>You don’t have clear rules about what is a Container and what is a Presentational Component. The difference between each other can be subjective and when you are in a team, it will be hard to have all the developers agreeing and judging equally this matter.\r\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 700px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/e3f435c8eb31db842147959728e1183c/554bf/subjective.jpg\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 74.28571428571428%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAMEBf/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHbQyaLwK//xAAZEAACAwEAAAAAAAAAAAAAAAABAgADESH/2gAIAQEAAQUCZgFS7ZscEwUtoHP/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAYEAADAQEAAAAAAAAAAAAAAAAAEEERIv/aAAgBAQAGPwLTpQi//8QAGhABAAIDAQAAAAAAAAAAAAAAAQARITFRwf/aAAgBAQABPyFhxE0B7KTFdYuAFNiUAW3s/9oADAMBAAIAAwAAABCDD//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABURAQEAAAAAAAAAAAAAAAAAAAEQ/9oACAECAQE/EFn/xAAaEAEBAQEBAQEAAAAAAAAAAAABESEAUTFB/9oACAEBAAE/EFbUeB+vnSINgl12iectOGtG5Pnzqs4sbHzs8o1Bvf/Z'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"lol...\"\n        title=\"lol...\"\n        src=\"/static/e3f435c8eb31db842147959728e1183c/03346/subjective.jpg\"\n        srcset=\"/static/e3f435c8eb31db842147959728e1183c/71299/subjective.jpg 175w,\n/static/e3f435c8eb31db842147959728e1183c/1e9fe/subjective.jpg 350w,\n/static/e3f435c8eb31db842147959728e1183c/03346/subjective.jpg 700w,\n/static/e3f435c8eb31db842147959728e1183c/554bf/subjective.jpg 720w\"\n        sizes=\"(max-width: 700px) 100vw, 700px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<ul>\n<li>Lost dynamism of the components</li>\n</ul>\n<p>Even when you decide a component fits in one of the specific types, it’s easy to get it changed along the project lifetime, and forcing you to move it from components to containers folder and vice-versa.</p>\n<ul>\n<li>Components with the same name</li>\n</ul>\n<p>Components should have declarative and unique names in the application, to avoid confusion about the responsibility of each one. However, the above approach opens a breach to having two components with the same name, one being a container and other being a presentational.</p>\n<ul>\n<li>Productivity loss</li>\n</ul>\n<p>You have to constantly navigate between containers and components folders, even when working in a single feature. Because it’s common that a single feature has components of the two types.</p>\n<p>For those reasons, I realized that when organizing folders and files, it’s irrelevant to split the components by the concept of presentational vs container.</p>\n<h3>Separating and grouping the code</h3>\n<p>Inside the <code class=\"language-text\">components</code> folder, I would group the files by module/feature.</p>\n<p>For example, for a CRUD of user, the structure would be as the following:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 545px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/e8b03b85d021216f7f756fdcc48b0815/084e3/components-user-scope.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 20%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAXElEQVQY052OuwpAIQxD+/9/5yYOgmCF4uCjOOdSweGOOpwk0yHUWoOx1sKcc6Oqz1CtFTFGhBCQc8YYY0utXyCzMjOcc/De732E5/ENZNF7h4ggpYRSyu/hrfADn94wV1szX/kAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"scoped for user module\"\n        title=\"scoped for user module\"\n        src=\"/static/e8b03b85d021216f7f756fdcc48b0815/084e3/components-user-scope.png\"\n        srcset=\"/static/e8b03b85d021216f7f756fdcc48b0815/1aaec/components-user-scope.png 175w,\n/static/e8b03b85d021216f7f756fdcc48b0815/98287/components-user-scope.png 350w,\n/static/e8b03b85d021216f7f756fdcc48b0815/084e3/components-user-scope.png 545w\"\n        sizes=\"(max-width: 545px) 100vw, 545px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>When a component is composed by more than one file, I’d put this component and its files in a folder with the same name. Eg: Let’s say you have a <code class=\"language-text\">Form.css</code> containing the <code class=\"language-text\">Form.jsx</code>’s styles. In this case, the structure would be like:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 544px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/38b696acef56a62db546bf7d49851c79/b0e00/components-user-scope-enhanced.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 24.571428571428573%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAbElEQVQY06XOOwrAIBAEUO9/NjtBG8FCBfH/OcAEFxJIGVPMLkzxdllKCaUUzDnRWsMY45XdfwmLMUJrDaUUnHMPcoIRuNYiSEoJ7z16779QtkcIAcYYcM4hhEDOGfvQMVhrJdRaS/v+7gS8AFKJe89SZ/qJAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"scoped for user module (enhanced)\"\n        title=\"scoped for user module (enhanced)\"\n        src=\"/static/38b696acef56a62db546bf7d49851c79/b0e00/components-user-scope-enhanced.png\"\n        srcset=\"/static/38b696acef56a62db546bf7d49851c79/1aaec/components-user-scope-enhanced.png 175w,\n/static/38b696acef56a62db546bf7d49851c79/98287/components-user-scope-enhanced.png 350w,\n/static/38b696acef56a62db546bf7d49851c79/b0e00/components-user-scope-enhanced.png 544w\"\n        sizes=\"(max-width: 544px) 100vw, 544px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>The test files stay with the file that is being tested. In the above case, the test for <code class=\"language-text\">Form.jsx</code> would stay in its same folder and would be named as <code class=\"language-text\">Form.spec.jsx</code></p>\n<h3>UI Components</h3>\n<p>Beyond separating the components by modules, I’d also include a <code class=\"language-text\">UI</code> folder inside <code class=\"language-text\">src/components</code>, to keep all the generic components in it.\r\nUI components are components generic enough not to belong to a module and likely to be reused. I could go with <code class=\"language-text\">Common</code> instead of <code class=\"language-text\">UI</code>, but the name <code class=\"language-text\">UI</code> represents the difference well with <code class=\"language-text\">logic</code>.\r\nExamples of these components are: Buttons, Inputs, Checkboxes, Selects, Modals, Data display elements, etc…</p>\n<h3>Naming components</h3>\n<p>The name we give to the components, should be clear and unique in the application, in order to make them easier to find and to avoid possible confusions.\r\nA component’s name is very handy when we need to debug using tools as <code class=\"language-text\">React Dev Tools</code>, and when run time errors happen in the application. The error always come with the component name where it happened.\r\nBasically, a component that is located at: <code class=\"language-text\">components/User/List.jsx</code> would be named as <code class=\"language-text\">UserList</code>.\r\nWhen the file is inside a folder with same name, we don’t need to repeat the name. That said, <code class=\"language-text\">components/User/Form/Form.jsx</code>, would be named as <code class=\"language-text\">UserForm</code> and not as <code class=\"language-text\">UserFormForm</code>.</p>\n<ul>\n<li>Search for the component definition</li>\n</ul>\n<p>I use <code class=\"language-text\">sublime</code> or <code class=\"language-text\">VSCode</code> as the IDE for the web development, and they support the <em>fuzzy search</em>.\r\nTherefore, file name not being identical to the component name doesn’t pose any difficulty in search.\r\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 700px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/4a3d8c230514d80a241781a61993aa4c/acc8b/fuzzy-search-sublime.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 28.57142857142857%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAyElEQVQY04XL246CMBCA4T6GiCjIQg8s7aCdWiiHoKxkN9H3fxzjaS/QxOTLZJKZn0hZQuEYwyj+9vz1zItmXnib7839eBEkQZAEK0oG89e1x8Z243gefk5QVJttXWwcFNUrBSXlmmcmyy3lSGz1W46j6491PTTtYMuucr1GJ5VWgBNSaco1E4YJZMIQiwez7dHsJeySNA/XIorFckXnfvzKX3w94ysCuYPMATS5cinTlOPd/wcThme7yfKIqcCUY8qQ8untY3wB2Z4/XaOoTsEAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"fuzzy search on sublime\"\n        title=\"fuzzy search on sublime\"\n        src=\"/static/4a3d8c230514d80a241781a61993aa4c/39600/fuzzy-search-sublime.png\"\n        srcset=\"/static/4a3d8c230514d80a241781a61993aa4c/1aaec/fuzzy-search-sublime.png 175w,\n/static/4a3d8c230514d80a241781a61993aa4c/98287/fuzzy-search-sublime.png 350w,\n/static/4a3d8c230514d80a241781a61993aa4c/39600/fuzzy-search-sublime.png 700w,\n/static/4a3d8c230514d80a241781a61993aa4c/57cd1/fuzzy-search-sublime.png 1050w,\n/static/4a3d8c230514d80a241781a61993aa4c/4af54/fuzzy-search-sublime.png 1400w,\n/static/4a3d8c230514d80a241781a61993aa4c/acc8b/fuzzy-search-sublime.png 1568w\"\n        sizes=\"(max-width: 700px) 100vw, 700px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<ul>\n<li>DRY on imports</li>\n</ul>\n<p>When I followed this naming convention, I could avoid some lengthy and repeated names in the import path.\r\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 544px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/0575b769393e900d8878f4861e9626e9/b0e00/shorter-import-path.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 25.142857142857146%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAsklEQVQY012Q2Q6FIAxE/f8PVGPcRdxXwNe5mSYQvQ8nLW2ZgUbTNKGqKjRNg6IoUNe1nEnbtlBKYRxHXNeF4zhwnqfk5L7vT04iCsZxjCzLJJI0TYUkSSTmeS5GZVmKcd/34L1/QcaIjuu6wlqL53ngnPvAOjHGBHj5nXsxeSHFtNZYlkVc53kOsMb+tm2hz+jhzL7v3xeyyF11XRf2xm/xi9zfMAyyQ99n5Iyfo8lb8AehoHU2hWhiggAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"shorter import path\"\n        title=\"shorter import path\"\n        src=\"/static/0575b769393e900d8878f4861e9626e9/b0e00/shorter-import-path.png\"\n        srcset=\"/static/0575b769393e900d8878f4861e9626e9/1aaec/shorter-import-path.png 175w,\n/static/0575b769393e900d8878f4861e9626e9/98287/shorter-import-path.png 350w,\n/static/0575b769393e900d8878f4861e9626e9/b0e00/shorter-import-path.png 544w\"\n        sizes=\"(max-width: 544px) 100vw, 544px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<h3>Screens</h3>\n<p>Screens, as the name already suggests, would be the screens that we have in the application.\r\nFor <code class=\"language-text\">users</code> scope, we would have a screen for the user list, a screen for creating a user and a screen for editing a user.\r\nA screen is where I use components to compose a page. Most of the time, the screen would’t contain any logic and would be a functional component.</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">import</span> React <span class=\"token keyword\">from</span> <span class=\"token string\">'react'</span><span class=\"token punctuation\">;</span>\r\n<span class=\"token keyword\">import</span> UserForm <span class=\"token keyword\">from</span> <span class=\"token string\">'../../components/User/Form/Form'</span><span class=\"token punctuation\">;</span>\r\n\r\n<span class=\"token keyword\">const</span> <span class=\"token function-variable function\">ScreensUserForm</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">match</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span> params <span class=\"token punctuation\">}</span> <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span>\r\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\r\n    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\r\n      </span><span class=\"token punctuation\">{</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token operator\">!</span>params<span class=\"token punctuation\">.</span>id <span class=\"token operator\">?</span> <span class=\"token string\">'Create'</span> <span class=\"token operator\">:</span> <span class=\"token string\">'Update'</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">}</span><span class=\"token plain-text\"> User\r\n    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\r\n    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">UserForm</span></span> <span class=\"token attr-name\">id</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>params<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\">\r\n  </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\r\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\r\n\r\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> ScreensUserForm<span class=\"token punctuation\">;</span></code></pre></div>\n<p>And the folder structure and component naming within the screens folder should follow the same convention as the <code class=\"language-text\">components</code> folder, except that we conveniently add a prefix to descriminate the screen components, i.e. <code class=\"language-text\">ScreensUserForm</code>\r\nThe final structure of this example project would look like:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 543px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/497801064f29c470a73bca89112ba28e/8586d/final-proj-structure.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 43.99999999999999%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAnElEQVQoz6WRzQqFIBCFe/9nayMJQghplkUUaro/lxko7jZdHHQ2H+enO44DIQTc940YI1JKLLqf94u6ZVmgtYZSCuu6NsEYeJ4npmmClBLOuddptUOKTM4I2vc9g733yDnXA8mZMQbzPDfHZiBp33eUUljNHY7jiGEYQP9n8f+1PwGv6+K41J0QgmOTy2qHtOi2bbDWcn8tCxPwB8TnqthuiQzKAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"the final project structure\"\n        title=\"the final project structure\"\n        src=\"/static/497801064f29c470a73bca89112ba28e/8586d/final-proj-structure.png\"\n        srcset=\"/static/497801064f29c470a73bca89112ba28e/1aaec/final-proj-structure.png 175w,\n/static/497801064f29c470a73bca89112ba28e/98287/final-proj-structure.png 350w,\n/static/497801064f29c470a73bca89112ba28e/8586d/final-proj-structure.png 543w\"\n        sizes=\"(max-width: 543px) 100vw, 543px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>Note that <code class=\"language-text\">Root.jsx</code> is the component where routing is defined</p>\n<h3>Additional thoughts</h3>\n<p>Personally, I would put some non-component files in the relevantly named folders directly under <code class=\"language-text\">src</code> folder.\r\nFor example, <code class=\"language-text\">utils</code> for the helper functions, <code class=\"language-text\">hooks</code> for custom hooks, and <code class=\"language-text\">services</code> for API handlers.</p>\n<h3>Conclusion</h3>\n<p>This approach is definitely a <strong>work in progress</strong> as I’d constantly seek for a better alternative, be it an enhanced version of this one or a completely different one.\r\nThe foremost question is if I really need <code class=\"language-text\">Screens</code> folder, but it seems convenient at the moment.</p>\n<p>To be continued …</p>"}},{"node":{"frontmatter":{"title":"React Native - Native or Hybrid?","description":"React Native is dominating the mobile app development","slug":"/blog/react-native-not-hybrid","date":"2020-04-12T00:00:00.000Z","tags":["Culture","Tech"],"draft":false},"html":"<p>React Native is dominating the mobile app development landscape.\r\nI tried to come up with a justification of why based on my experience.</p>\n<h3>What’s React Native?</h3>\n<ul>\n<li>Native Application, not Hybrid</li>\n<li>JSX and ES6+ JavaScript interface</li>\n<li>Logic - JavaScript thread</li>\n<li>UI - Main thread (and more for background computing)</li>\n</ul>\n<h3>Cross Platform</h3>\n<ul>\n<li>How does it work</li>\n<li>Writing code in JSX blocks</li>\n<li>Invoke platform API to display native elements e.g. becomes UIView for iOS and View for Android</li>\n<li>React Native works like a connector between platforms</li>\n<li>Business and View logic run by different threads</li>\n</ul>\n<h3>Lifecycle of new component</h3>\n<ul>\n<li>constructor() -> good place to add state unless you are using class properties</li>\n<li>componentWillMount() -> avoid using it at all, if anything needs to be done with component do that in DidMount</li>\n<li>render() -> React Element which will be rendered and made into native UI afterwards</li>\n<li>componentDidMount() -> perfect place to call all side effects</li>\n</ul>\n<h3>Lifecycle of updating component</h3>\n<ul>\n<li>componentWillReceiveProps(nextProps) -> try to limit yourself just to this.setState only here</li>\n<li>shouldComponentUpdate(nextProps, nextState) -> can be used for optimization</li>\n<li>componentWillUpdate(nextProps, nextState) -> component will get an update, you can do some calculations here depending on current and next props/states</li>\n<li>render() -> As in mounting component lifecycle</li>\n<li>componentDidUpdate(prevProps, prevState) -> component got updated you can call some refs here or similar after update</li>\n</ul>\n<h3>How it does compare with other solutions?</h3>\n<ul>\n<li>More performant than Cordova with Ionic as it is Native vs Hybrid</li>\n<li>Can reuse same code on all platforms (unlike Xamarin.iOS and Xamarin.Android, while Xamarin.Forms has same capability)</li>\n<li>Flutter is new and not stable yet enough but it is promising as well</li>\n<li>Most complete JavaScript solution as of now</li>\n</ul>\n<h3>The good parts (the final WHY)</h3>\n<ul>\n<li>Write once, use everywhere</li>\n<li>Straightforward and easy to start if had experience with React previously</li>\n<li>Can reuse same libraries as from Web for most of the things (redux, redux-saga etc.)</li>\n<li>Satisfying performance</li>\n<li>Community getting bigger on daily basis with plenty of packages that are getting available</li>\n<li>Plenty of platforms that are supported with some additional packages (Windows 10, Windows 10 Mobile, OSX, Web)</li>\n</ul>\n<h3>The bad parts</h3>\n<ul>\n<li>Problems with updating packages and RN itself</li>\n<li>No support for Android 64-bit (that’s need to be added as of 2019 it will be required)</li>\n<li>Layers are pretty fast, but bridges might be bottleneck so this need to be considered when writing a native module</li>\n<li>Rare cases where platforms JS interpreter are different (e.g. lack of Proxy within Android - requires polyfill)</li>\n</ul>\n<p>React Native provides an interface (bridge) between the Native language and Javascript code. There are heated debates on whether React Native is a native or a hybrid solution.\r\nPersonally, I consider React Native closer to native side, as Facebook officially claims.</p>\n<p><strong>_ We designed React Native such that it is possible for you to write real native code and have access to the full power of the platform._</strong></p>\n<p>You can side with or against me, but React Native still rocks, so does React.</p>"}},{"node":{"frontmatter":{"title":"Challenge & Solution (Highcharts)","description":"While working at Sigsense Technologies, I was","slug":"/blog/challenge-and-solution","date":"2020-04-09T00:00:00.000Z","tags":["Blogging","Tech"],"draft":false},"html":"<p>While working at <a href=\"http://www.sigsensetech.com/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Sigsense Technologies</a>, I was badly stuck with unseen customization of Highcharts graph.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 600px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/21c3c3882e70ee8227e41e771c0a8e7d/ff59c/sigsense_machine_learning.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 43.42857142857143%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAIAAAC9o5sfAAAACXBIWXMAAAsTAAALEwEAmpwYAAABd0lEQVQoz3XQTW/UMBAG4PzVVmr/3qLuhUu5wAkhFWlFKbtb0O4maew49jiO7fFXBhLg0EOfw1xG86G30lqnlLzziIghmsmmlIjIOQdKalhIKYUQADCIAQDatt3v94yxCkDPpYwrIgohGGO01maaphAwYM7ZrWKKPvhSym632263x+Oxal4ug5JKKmPMsmCtehwlZ8PTD96ymJAWc8nF6VBKIZqJyHtfffz0oetZUzdipZTK69vlfPh1ffu4vSdi87wOp/L17jn6PBPlXCZrK3othIDez0TldHi+vnnYvC+p9T6HgOjwy+a7Mz7lhIgAUOWccs7lvxDQWutnwp9Ph6ubh3f3OXX/hn34vHl0BnMp1jrG+0opuYSxss6PxkqYGmHaTp6+HU9nzmHspGPSMulOZ+iGiSnLwZvJVqIXMUZEjDFKJeUgJEwXrpvBNuDrfqy5qbk+M6j7sRnMheulK8xoTAUAf8+mlLTWvejXPGmNdKa3/Un7N9v7+o425or1AAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Machine Learning UI\"\n        title=\"Machine Learning UI\"\n        src=\"/static/21c3c3882e70ee8227e41e771c0a8e7d/ff59c/sigsense_machine_learning.png\"\n        srcset=\"/static/21c3c3882e70ee8227e41e771c0a8e7d/1aaec/sigsense_machine_learning.png 175w,\n/static/21c3c3882e70ee8227e41e771c0a8e7d/98287/sigsense_machine_learning.png 350w,\n/static/21c3c3882e70ee8227e41e771c0a8e7d/ff59c/sigsense_machine_learning.png 600w\"\n        sizes=\"(max-width: 600px) 100vw, 600px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>Highcharts graph needed to be made bi-directional, which meant end-users being able to draw different types of plots using their mouse.\r\nIn addition, already-drawn plots were to be resized by the end-users’ dragging of the plot edges. (you could notice the colorful pillars from the above figure)\r\nGiven the primary purpose of Highcharts, it implied heavy customization and an elaborate manipulation of the available interfaces to the graph.</p>\n<p>Google it! That was my first response to this challenge.\r\nIt was not very successful, as there were no such use cases discussed or answered publicly.\r\nSo there came the realization -</p>\n<p><strong>_ I need the top-down approach_</strong></p>\n<p>Here’s how I broke the issue down to smaller pieces.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 581px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/c7b8469a9dc108e3c0e4703a864788d4/13a45/top-down-sigsense.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 74.28571428571428%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEPElEQVQ4y01Ta2gcVRQ+k9iSNK1JbJQEfPyIotVaEPyRFcVHQ7GI4g9BaX7VUFpDaokoNiEWHyBEKPaHzySCBqs2GrPZZDdpdrOPJPuYnX3vziY7uzszO4+dfc1OZrubbrXNlUmp9MDHd+53Dpd7v8MBPOPEvKwTm5j5AVvyGDHlX7kBIQSKorhKpRLKZrNIkiQkiuIua1BVFRUKhWGtT91W9oxPf4d5mHXMzTgwoG+RUEYiTMx9C/bkEnz608dQrVVBluUvZFk2i6I4l8vl5gRBMEiSNCdJkr5Sqdjy+fybW9cU6Jt8FcZnv4EiygCPkgAFlG5G6Oa+s5+c6bx0eezg6fMn2wCgCQAwAGjs6Ohompqa2qvT6VoRQg0A0Ay3o7H3jRf3X5z68uDAyKmum2irZQdt74WVkJk3uY3i3Kq+YHIv5FdJeywoejv/QXUolUrHMplMgSCIbDAYzG9sbBRkWQ5P/jzR5mcJcKfWP1vCTVW942/J6FzIWiKLNLgS64ll4mpyJWjZtIZWGILBfWw12RVJhqBYKvaWy+VMPB5P4Ti+yXEcr6qq17BoaJ2xT4OPxS9Yg5aSLWzdsPjMKVvcHAPGswMXTyzDj6dwmP+ahEq5DprZdwAA2jcb79buRlm4DuapKJx9yAAudwQA+RD8es4HhGACw4xpnyzL77Ise14QhA9VVR3w+XxtOp0O9Ho9ZDKZxxVF+UBRlPcTicSwqqrn5JI8GIvE72dLcYiHGAy+t38ORNjdQEZJCIVCj9I0jRiGQRRFIS0PBALPCrwAhVwBOI77KJVK/V/Tco2zUvZoKS8Dy9ONMDY2BpFIBILBIBAE0SYIwng6nZ6hKOoKy7KXE4lEV6GYB67IQIbhnqfT9GwqmfqDoqjZJJWcZmjmN54RHskUaBBzArZ74eDgIAwMDEBPTw82OjoKGIY1t7e37z36ci+8dvx1TPOqjkr3TjoutXYff6AVHoZ7NO250e6mB4+1HvjT98t9O0ht2fV8ZGQEUqlUI0VR4HQ63yZJshIIBIRoNCrE4/Gan/CfsZeNHWukg1kJWkRtqu6Ek3ClHSdWYw7eFlrJWoOW4lrc4fAWrS2gvahWqzXW63Wgafo0z/MoFoshkiR3veQ5YdTA/N5p8ZuRmVhGJpcR2cNWxRZffs/oMiJNX/IsIpPbKEWqzgPQ19cHuawEkiBBOBjer17bemLxqvEZi818RMwJh5gk0/oVPoxtViKHEtXo4eR27HCs7H/MwztaktvkkxuV8FNULfZ0ohrt3t2f/v5+wFlnQyCLQ0DyHrGGLc55p8FldC+s26NW3Mu5XiI4N2RvccBeTwN3gwFK3QCvsAbcDRqY7RRwdY2T8M6FVwCGhobAw6w1BEQcAln8hSXfPJp3zyL92l9oyb+ACM71lo93g4dZ3xPgiQYNft6LOWkb3Dnf1nDsim8c/gOVyQ9LErxYYAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Flight History Simulator\"\n        title=\"Flight History Simulator\"\n        src=\"/static/c7b8469a9dc108e3c0e4703a864788d4/13a45/top-down-sigsense.png\"\n        srcset=\"/static/c7b8469a9dc108e3c0e4703a864788d4/1aaec/top-down-sigsense.png 175w,\n/static/c7b8469a9dc108e3c0e4703a864788d4/98287/top-down-sigsense.png 350w,\n/static/c7b8469a9dc108e3c0e4703a864788d4/13a45/top-down-sigsense.png 581w\"\n        sizes=\"(max-width: 581px) 100vw, 581px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>At the end of the day, the challenge boiled down to resolving <strong>3 leaf issues</strong>(the green ones on the above) :</p>\n<ul>\n<li>Catch mouse events on Highcharts canvas</li>\n<li>Add plots after the graph is rendered</li>\n<li>Remove plots after the graph is rendered</li>\n</ul>\n<p>Then, with the issue broken down to tangible, atomic and easy-to-solve pieces, I did the dreaded and contributed to the original value of the product.</p>"}},{"node":{"frontmatter":{"title":"Docker Compose Error","description":"docker-compose version discrepancies","slug":"/blog/docker-error","date":"2019-12-13","tags":["WordPress","Docker"],"draft":false},"html":"<h2>Problem</h2>\n<p>Recently while updating with <a href=\"https://github.com/Upstatement/skela-wp-theme\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Skela</a> with webpack, I encountered a weird error where I wasn't able to run a simple script:</p>\n<div class=\"gatsby-code-title\">bin/composer</div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token shebang important\">#!/bin/bash</span>\r\n<span class=\"token function\">docker-compose</span> <span class=\"token builtin class-name\">exec</span> <span class=\"token parameter variable\">-w</span> /var/www/html/wp-content/themes/skela wordpress <span class=\"token function\">composer</span> <span class=\"token string\">\"<span class=\"token variable\">$@</span>\"</span></code></pre></div>\n<p>When trying to run this script via <code class=\"language-text\">./bin/composer install</code>, I got this error in my terminal:</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">ERROR: Setting workdir <span class=\"token keyword\">for</span> <span class=\"token builtin class-name\">exec</span> is not supported <span class=\"token keyword\">in</span> API <span class=\"token operator\">&lt;</span> <span class=\"token number\">1.35</span> <span class=\"token punctuation\">(</span><span class=\"token number\">1.30</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>The error was coming from the <code class=\"language-text\">-w</code> flag in the <code class=\"language-text\">docker-compose exec</code> command in the <code class=\"language-text\">composer</code> script.</p>\n<h2>Solution</h2>\n<p>Turns The fix was to update the version in my <code class=\"language-text\">docker-compose.yml</code> file to from version <code class=\"language-text\">3.5</code> to <code class=\"language-text\">3.6</code>. It's strange because 3.5 isn't anywhere close to the API version <code class=\"language-text\">1.35</code> from the error message 🤷‍♀️</p>\n<div class=\"gatsby-code-title\">docker-compose.yml</div>\n<div class=\"gatsby-highlight\" data-language=\"yaml\"><pre class=\"language-yaml\"><code class=\"language-yaml\"><span class=\"gatsby-highlight-code-line\"><span class=\"token key atrule\">version</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'3.6'</span>\r</span><span class=\"token key atrule\">services</span><span class=\"token punctuation\">:</span>\r\n  <span class=\"token key atrule\">wordpress</span><span class=\"token punctuation\">:</span>\r\n    build<span class=\"token punctuation\">:</span></code></pre></div>"}},{"node":{"frontmatter":{"title":"WordPress Publishing Error","description":"Trying to create a simple post in WordPress","slug":"/blog/wordpress-publish-error","date":"2019-12-03T00:00:00.000Z","tags":["WordPress"],"draft":false},"html":"<h2>Problem</h2>\n<p>Recently while working on a WordPress project with <a href=\"https://github.com/Upstatement/ups-dock\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Ups Dock</a>, I encountered a weird error where I wasn't able to update or publish a simple post in my local WP admin.</p>\n<p>It looked something like this:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 700px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/9a92c868095081fef605169d5c41eaee/8e621/draft-fail.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 32.57142857142857%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA40lEQVQY05WOyU7DMBRF/cH8Gqt+ATtWqBICMUitEuJMTeKMtt/zGxCFFS0Ljq50V3cwCMjMCZOqioiK6B9sQB5IIdzuDze7h93dvXGHI9iSm4abVtoT1Q2W1RVVVciLU9UUdWvbznbDMM6mtbbO8qXvXdNWWbb0vQJICJfSGLthfM3Lfhi+b5oPW768veeFPWbZ49Pz4NzP/2sgot82EUGS0YNhlpQIMRExEccIwr+TRBQjMHMEXDcfAPppXQIaIk5fUCI6O10OiiqfGxFxnpd5mhKAqhr9D0TkvV+d8+MYYvgEBF+Tsm3JYE8AAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Draft fail\"\n        title=\"Draft fail\"\n        src=\"/static/9a92c868095081fef605169d5c41eaee/39600/draft-fail.png\"\n        srcset=\"/static/9a92c868095081fef605169d5c41eaee/1aaec/draft-fail.png 175w,\n/static/9a92c868095081fef605169d5c41eaee/98287/draft-fail.png 350w,\n/static/9a92c868095081fef605169d5c41eaee/39600/draft-fail.png 700w,\n/static/9a92c868095081fef605169d5c41eaee/57cd1/draft-fail.png 1050w,\n/static/9a92c868095081fef605169d5c41eaee/4af54/draft-fail.png 1400w,\n/static/9a92c868095081fef605169d5c41eaee/8e621/draft-fail.png 2234w\"\n        sizes=\"(max-width: 700px) 100vw, 700px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>Sometimes the error message would be slightly more helpful: <code class=\"language-text\">Publishing failed. Error message: The response is not a valid JSON response.</code></p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 700px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/ac418cb7402b96be332b88c4505db1b1/04410/publish-error.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 12%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAIAAADXZGvcAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAU0lEQVQI113LQQ6AIAwEQP7/O1u6W8MRFEriH9SQePA6yaRwryKn4TQb4CA70FSne5BHzt0s6NP3DnSzV4CqepWSVm6avzzIukmQQV/+z4Yq8uQbiGdm6Od9qWQAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Publish error\"\n        title=\"Publish error\"\n        src=\"/static/ac418cb7402b96be332b88c4505db1b1/39600/publish-error.png\"\n        srcset=\"/static/ac418cb7402b96be332b88c4505db1b1/1aaec/publish-error.png 175w,\n/static/ac418cb7402b96be332b88c4505db1b1/98287/publish-error.png 350w,\n/static/ac418cb7402b96be332b88c4505db1b1/39600/publish-error.png 700w,\n/static/ac418cb7402b96be332b88c4505db1b1/04410/publish-error.png 956w\"\n        sizes=\"(max-width: 700px) 100vw, 700px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>And if I popped open the console, I saw these errors:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 700px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/d342131a17d748d605395cbdcc072a7f/fb77c/console-errors.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 20.571428571428573%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA2UlEQVQI1x3Jy26CQBQAUDaujImaIgzzvndwRoLpso90wVOYPkBAY///S5r0bE9QPYW9FBfGWs4LSr+MKSktEAutG6UuAC2AN6ZkrFKqA2ikbAF6rT/iOHjdbK4APo7H43GxdrZ2dm45nUaAQevFmFHrK+Kg1GzMjDghDoglIW+7XVDt956xJgw7Quoo+haiORxqKRvO2yTxQngpP4Woo6hlzHPeM9b91/t2G7ys1w+ABWB07pZl9zx/nM9Lnv8g3q29Wzul6c25yZgpTX+zrEySktKKkOfV6g/zcCorsTYI8QAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Console errors\"\n        title=\"Console errors\"\n        src=\"/static/d342131a17d748d605395cbdcc072a7f/39600/console-errors.png\"\n        srcset=\"/static/d342131a17d748d605395cbdcc072a7f/1aaec/console-errors.png 175w,\n/static/d342131a17d748d605395cbdcc072a7f/98287/console-errors.png 350w,\n/static/d342131a17d748d605395cbdcc072a7f/39600/console-errors.png 700w,\n/static/d342131a17d748d605395cbdcc072a7f/57cd1/console-errors.png 1050w,\n/static/d342131a17d748d605395cbdcc072a7f/fb77c/console-errors.png 1185w\"\n        sizes=\"(max-width: 700px) 100vw, 700px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<h2>Solution</h2>\n<p>Since the error message had to do with a JSON response, I initially thought it was a Gutenberg or ACF issue. But it turned out this was happening because I was on the https WP admin (i.e. <a href=\"https://project.ups.dock/wp-admin\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://project.ups.dock/wp-admin</a>), not the unsecure WP admin (<a href=\"http://project.ups.dock/wp-admin\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">http://project.ups.dock/wp-admin</a>).</p>\n<p>It was a CORS error!! I was trying to modify a non-https domain from a https domain. Switching to a non-https WP admin allowed me to publish posts with no problem.</p>"}}]}},"pageContext":{}},
    "staticQueryHashes": ["2009693873","2077189868","3303540520","3505212370","3825832676"]}