<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Grant Watson</title>
    <description>The latest articles on DEV Community by Grant Watson (@grantwatsondev).</description>
    <link>https://dev.to/grantwatsondev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F294613%2F060f7ac0-d9dd-472b-a1a2-26c98afaad0b.jpeg</url>
      <title>DEV Community: Grant Watson</title>
      <link>https://dev.to/grantwatsondev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/grantwatsondev"/>
    <language>en</language>
    <item>
      <title>Earned Complexity: A Disciplined, Evidence-Based Framework</title>
      <dc:creator>Grant Watson</dc:creator>
      <pubDate>Mon, 19 Jan 2026 01:10:28 +0000</pubDate>
      <link>https://dev.to/grantwatsondev/earned-complexity-a-disciplined-evidence-based-framework-54pn</link>
      <guid>https://dev.to/grantwatsondev/earned-complexity-a-disciplined-evidence-based-framework-54pn</guid>
      <description>&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;p&gt;Modern software engineering organizations increasingly struggle not because of insufficient technical skill or innovation, but due to a systemic over-accumulation of complexity that is introduced faster than it can be justified, understood, governed, or operated. This phenomenon—often mislabeled as &lt;em&gt;technical ambition&lt;/em&gt;, &lt;em&gt;future-proofing&lt;/em&gt;, or &lt;em&gt;scalability planning&lt;/em&gt;—has been repeatedly identified as a root cause of degraded system reliability, declining delivery velocity, organizational burnout, and unsustainable maintenance cost.&lt;/p&gt;

&lt;p&gt;This paper formalizes &lt;strong&gt;Earned Complexity&lt;/strong&gt;, an evidence-based decision framework designed explicitly for &lt;strong&gt;software teams&lt;/strong&gt; to determine &lt;em&gt;when&lt;/em&gt; architectural or systemic complexity is warranted and &lt;em&gt;how&lt;/em&gt; such complexity must be constrained, monitored, and revisited over time. The framework synthesizes principles from well-established engineering literature, including &lt;em&gt;Choose Boring Technology&lt;/em&gt;, &lt;em&gt;You Are Not Google&lt;/em&gt;, and the maxim &lt;em&gt;Code Is Read More Than It Is Written&lt;/em&gt;, alongside operational insights from reliability engineering, systems thinking, and organizational psychology.&lt;/p&gt;

&lt;p&gt;By reframing complexity as a &lt;strong&gt;scarce resource that must be earned and continuously paid for&lt;/strong&gt;, this work proposes a practical, repeatable discipline that aligns technical decision-making with long-term organizational performance. The intended outcome is not minimalism for its own sake, but &lt;strong&gt;sustained peak execution through disciplined restraint&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Introduction: Why Complexity Requires Study
&lt;/h2&gt;

&lt;p&gt;Software systems do not fail randomly. They fail predictably, following well-understood patterns associated with unmanaged complexity: cascading failures, brittle abstractions, opaque behavior, and disproportionate operational overhead. Despite decades of industry experience, many teams continue to repeat the same mistakes, introducing advanced architectures prematurely and assuming that sophistication is synonymous with professionalism.&lt;/p&gt;

&lt;p&gt;The study of complexity in software engineering is not new. Brooks’ &lt;em&gt;No Silver Bullet&lt;/em&gt; established early that essential complexity cannot be eliminated, only managed &lt;sup id="fnref1"&gt;1&lt;/sup&gt;. However, modern development practices—cloud infrastructure, distributed systems, and rapidly evolving frameworks—have dramatically lowered the &lt;em&gt;activation energy&lt;/em&gt; required to introduce complexity, while simultaneously increasing the cost of operating it.&lt;/p&gt;

&lt;p&gt;This asymmetry has created an environment in which teams can add complexity far more easily than they can remove it.&lt;/p&gt;

&lt;p&gt;The motivation for this study is therefore pragmatic: &lt;strong&gt;how can software teams systematically distinguish between necessary complexity and optional complexity, and how can they govern the latter to prevent long-term harm?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Intellectual Origins of Earned Complexity
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 Choose Boring Technology
&lt;/h3&gt;

&lt;p&gt;Dan McKinley’s essay &lt;em&gt;Choose Boring Technology&lt;/em&gt; articulates a central insight: most business problems do not require novel solutions, and novelty disproportionately increases risk relative to its benefit. McKinley argues that mature organizations succeed not by adopting cutting-edge tools, but by selecting technologies that are well-understood, widely supported, and operationally predictable.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“If the problem you are solving is not unique, your solution should probably not be either.”&lt;br&gt;&lt;br&gt;
— McKinley, &lt;em&gt;Choose Boring Technology&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://mcfunley.com/choose-boring-technology" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://mcfunley.com/choose-boring-technology" rel="noopener noreferrer"&gt;https://mcfunley.com/choose-boring-technology&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This work establishes the foundational idea that &lt;strong&gt;engineering maturity manifests as restraint&lt;/strong&gt;, not maximal sophistication.&lt;/p&gt;




&lt;h3&gt;
  
  
  2.2 You Are Not Google
&lt;/h3&gt;

&lt;p&gt;The essay commonly referred to as &lt;em&gt;You Are Not Google&lt;/em&gt; (popularized through multiple iterations and talks) critiques the widespread tendency for organizations to emulate the architectures of hyperscale technology companies without possessing the corresponding scale, staffing, or operational maturity.&lt;/p&gt;

&lt;p&gt;The key contribution of this perspective is the concept of &lt;strong&gt;scale proportionality&lt;/strong&gt;: architectural decisions must be justified by &lt;em&gt;actual constraints&lt;/em&gt;, not aspirational ones.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Premature scaling is just another form of premature optimization.”&lt;br&gt;&lt;br&gt;
&lt;a href="https://blog.bradfieldcs.com/you-are-not-google-84912cf44afb" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://blog.bradfieldcs.com/you-are-not-google-84912cf44afb" rel="noopener noreferrer"&gt;https://blog.bradfieldcs.com/you-are-not-google-84912cf44afb&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This work directly informs the &lt;em&gt;Evidence Gate&lt;/em&gt; in the Earned Complexity framework.&lt;/p&gt;




&lt;h3&gt;
  
  
  2.3 Code Is Read More Than It Is Written
&lt;/h3&gt;

&lt;p&gt;The assertion that &lt;em&gt;code is read more than it is written&lt;/em&gt; reframes software as a long-lived communicative artifact rather than a short-lived construction task. While often attributed informally, this principle is supported by empirical research showing that maintenance accounts for the majority of software lifecycle cost &lt;sup id="fnref2"&gt;2&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Readable, predictable code reduces onboarding time, error rates, and recovery time during incidents. Conversely, clever or opaque implementations amplify cognitive load and slow organizational response.&lt;/p&gt;

&lt;p&gt;This principle informs the framework’s emphasis on &lt;strong&gt;cognitive cost&lt;/strong&gt; as a first-class consideration.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Complexity as an Organizational Liability
&lt;/h2&gt;

&lt;p&gt;Complexity introduces costs that are frequently underestimated or ignored during design discussions. These costs fall into four primary categories:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Cognitive Load&lt;/strong&gt; – The mental effort required to understand, modify, and debug a system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operational Load&lt;/strong&gt; – The ongoing effort required to deploy, monitor, and recover the system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failure Surface Area&lt;/strong&gt; – The number of distinct ways a system can fail, including partial or silent failures.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependency Risk&lt;/strong&gt; – The fragility introduced by external libraries, platforms, vendors, or coordination mechanisms.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Importantly, these costs &lt;strong&gt;compound over time&lt;/strong&gt;. Each additional layer of abstraction increases the difficulty of future changes, often non-linearly.&lt;/p&gt;

&lt;p&gt;Research in systems engineering consistently demonstrates that increased system complexity correlates with decreased reliability unless mitigated by proportional investment in controls and expertise &lt;sup id="fnref3"&gt;3&lt;/sup&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. The Law of Earned Complexity
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Complexity must be earned by measurable pain, and paid for with controls.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This law formalizes two necessary conditions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Justification Condition:&lt;/strong&gt; A demonstrable, current problem exists that cannot be addressed through simpler means.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Governance Condition:&lt;/strong&gt; The organization is willing and able to fund the mechanisms required to safely operate the added complexity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If either condition is unmet, complexity should not be introduced.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. The Earned Complexity Framework
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1 Gate 0: Problem Definition
&lt;/h3&gt;

&lt;p&gt;Teams must articulate proposed complexity in a single sentence:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“We propose adding &lt;strong&gt;X&lt;/strong&gt; to address &lt;strong&gt;Y&lt;/strong&gt;, measured by &lt;strong&gt;Z&lt;/strong&gt;, with rollback &lt;strong&gt;R&lt;/strong&gt;.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This constraint enforces clarity and prevents ambiguity-driven scope creep.&lt;/p&gt;




&lt;h3&gt;
  
  
  5.2 Gate 1: Evidence of Pain
&lt;/h3&gt;

&lt;p&gt;Acceptable evidence includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Recurrent production incidents&lt;/li&gt;
&lt;li&gt;SLO or error-budget violations&lt;/li&gt;
&lt;li&gt;Quantified performance ceilings&lt;/li&gt;
&lt;li&gt;Measured delivery bottlenecks&lt;/li&gt;
&lt;li&gt;Documented compliance requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Speculative future needs are explicitly excluded.&lt;/p&gt;




&lt;h3&gt;
  
  
  5.3 Gate 2: Alternatives Analysis
&lt;/h3&gt;

&lt;p&gt;Teams must demonstrate that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Procedural remedies were attempted&lt;/li&gt;
&lt;li&gt;Localized technical optimizations were evaluated&lt;/li&gt;
&lt;li&gt;Architectural escalation is unavoidable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This step enforces &lt;strong&gt;graduated response&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  5.4 Gate 3: Cost Modeling
&lt;/h3&gt;

&lt;p&gt;Each proposal is scored across four dimensions (0–5):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cognitive Load&lt;/li&gt;
&lt;li&gt;Operational Load&lt;/li&gt;
&lt;li&gt;Failure Modes&lt;/li&gt;
&lt;li&gt;Dependency Risk&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Total Cost Score: 0–20&lt;/p&gt;




&lt;h3&gt;
  
  
  5.5 Gate 4: Benefit Modeling
&lt;/h3&gt;

&lt;p&gt;Benefits are similarly scored:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reliability Improvement&lt;/li&gt;
&lt;li&gt;Performance or Cost Efficiency&lt;/li&gt;
&lt;li&gt;Delivery Velocity&lt;/li&gt;
&lt;li&gt;Security or Compliance Risk Reduction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Total Benefit Score: 0–20&lt;/p&gt;




&lt;h3&gt;
  
  
  5.6 Gate 5: Controls Requirement
&lt;/h3&gt;

&lt;p&gt;Complexity must ship with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Observability (metrics, logs, traces)&lt;/li&gt;
&lt;li&gt;Alerting aligned to user impact&lt;/li&gt;
&lt;li&gt;Rollback and kill-switch mechanisms&lt;/li&gt;
&lt;li&gt;Named ownership and runbooks&lt;/li&gt;
&lt;li&gt;Failure-mode testing&lt;/li&gt;
&lt;li&gt;A stated complexity budget&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  6. Decision Rule
&lt;/h2&gt;

&lt;p&gt;Complexity may be approved only if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Evidence and Alternatives gates pass, and&lt;/li&gt;
&lt;li&gt;Benefit − Cost ≥ +4, &lt;strong&gt;or&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Compliance mandates the change and controls are funded&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Otherwise, the proposal is rejected or deferred.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Practical Team Applications
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7.1 Architecture Reviews
&lt;/h3&gt;

&lt;p&gt;Replace subjective debates with structured scoring and evidence review.&lt;/p&gt;

&lt;h3&gt;
  
  
  7.2 Code Reviews
&lt;/h3&gt;

&lt;p&gt;Use the framework to challenge unnecessary abstractions early.&lt;/p&gt;

&lt;h3&gt;
  
  
  7.3 Incident Retrospectives
&lt;/h3&gt;

&lt;p&gt;Tie complexity reduction directly to incident prevention.&lt;/p&gt;

&lt;h3&gt;
  
  
  7.4 Engineering Governance
&lt;/h3&gt;

&lt;p&gt;Adopt Earned Complexity as a formal policy or ADR requirement.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Case Study: Microservices Adoption
&lt;/h2&gt;

&lt;p&gt;A mid-sized team experiencing deployment conflicts considered migrating to microservices.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Evidence: No scaling constraints, no incident correlation&lt;/li&gt;
&lt;li&gt;Alternatives: Modular monolith not attempted&lt;/li&gt;
&lt;li&gt;Cost: High operational and cognitive load&lt;/li&gt;
&lt;li&gt;Decision: Rejected&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Outcome: Delivery velocity improved after refactoring boundaries without architectural escalation.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Sustaining Peak Performance
&lt;/h2&gt;

&lt;p&gt;Peak engineering performance is not achieved through maximal output or technical bravado. It emerges from &lt;strong&gt;predictable systems, calm operations, and disciplined decision-making&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Earned Complexity provides teams with a repeatable mechanism to protect these outcomes.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. Conclusion
&lt;/h2&gt;

&lt;p&gt;Complexity is neither inherently good nor bad. It is &lt;strong&gt;expensive&lt;/strong&gt;. Like any scarce organizational resource, it must be justified, governed, and revisited.&lt;/p&gt;

&lt;p&gt;By adopting Earned Complexity as a formal discipline, software teams can align technical ambition with operational reality—achieving sustainable excellence without unnecessary risk.&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://ieeexplore.ieee.org/document/1663532" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://ieeexplore.ieee.org/document/1663532" rel="noopener noreferrer"&gt;https://ieeexplore.ieee.org/document/1663532&lt;/a&gt;&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Brooks, F. P. (1987). &lt;em&gt;No Silver Bullet—Essence and Accidents of Software Engineering&lt;/em&gt;. IEEE Computer. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;Lehman, M. M. (1980). &lt;em&gt;Programs, Life Cycles, and Laws of Software Evolution&lt;/em&gt;. Proceedings of the IEEE. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;Perrow, C. (1984). &lt;em&gt;Normal Accidents: Living with High-Risk Technologies&lt;/em&gt;. Basic Books. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>ai</category>
      <category>learning</category>
    </item>
    <item>
      <title>12 Powerful React Libraries Every Developer Should Master in 2025</title>
      <dc:creator>Grant Watson</dc:creator>
      <pubDate>Mon, 21 Jul 2025 16:52:21 +0000</pubDate>
      <link>https://dev.to/grantwatsondev/12-powerful-react-libraries-every-developer-should-master-in-2025-4po</link>
      <guid>https://dev.to/grantwatsondev/12-powerful-react-libraries-every-developer-should-master-in-2025-4po</guid>
      <description>&lt;h1&gt;
  
  
  12 Powerful React Libraries Every Developer Should Master in 2025
&lt;/h1&gt;

&lt;p&gt;React continues to lead the frontend world in 2025, but with its simplicity comes the challenge of choosing the right tools. Whether you're a solo developer or working on a team, these 12 libraries will help you work faster, write better code, and build more dynamic web apps.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. React Router
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Declarative routing for single-page React apps.&lt;/p&gt;

&lt;p&gt;React Router is still the industry standard for managing routes in React. It supports nested layouts, lazy loading, and dynamic route parameters.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://reactrouter.com/" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Zustand
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Minimal state management using hooks.&lt;/p&gt;

&lt;p&gt;Zustand is gaining popularity for being tiny, fast, and avoiding boilerplate. It works great for global state in small-to-medium apps.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://docs.pmnd.rs/zustand" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3. React Hook Form
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Performant, hook-based form management.&lt;/p&gt;

&lt;p&gt;React Hook Form simplifies validation and reduces re-renders in complex forms. It’s a must-have for building accessible, fast forms.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://react-hook-form.com/" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  4. TanStack Query (React Query)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Fetch, cache, and sync server state.&lt;/p&gt;

&lt;p&gt;React Query (now TanStack Query) helps you manage API requests with automatic caching, background updates, and retry logic.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://tanstack.com/query/latest" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Framer Motion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Declarative animations for React.&lt;/p&gt;

&lt;p&gt;Framer Motion is a high-performance library for creating animations, gestures, and transitions without writing CSS keyframes.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://www.framer.com/motion/" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  6. React Helmet
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Control your document’s &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;React Helmet lets you dynamically set meta tags, page titles, and social tags—essential for SEO in single-page apps.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/nfl/react-helmet" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  7. React Markdown
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Render Markdown content as React components.&lt;/p&gt;

&lt;p&gt;Perfect for blogs, docs, or CMS-driven sites where content is stored in Markdown. It supports plugins like remark-gfm.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/remarkjs/react-markdown" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  8. React Testing Library
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Tests components like a user would interact with them.&lt;/p&gt;

&lt;p&gt;It encourages good testing practices by focusing on user behavior, not implementation details.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://testing-library.com/docs/react-testing-library/intro/" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Recharts
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Charting with React components.&lt;/p&gt;

&lt;p&gt;If you need bar, line, or pie charts quickly without dealing with D3 directly, Recharts is clean and customizable.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://recharts.org/" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  10. Formik
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Form state management with validation support.&lt;/p&gt;

&lt;p&gt;Formik provides a structured way to handle form inputs, validation, and submission logic—often used with Yup.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://formik.org/" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  11. React Icons
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Use icon packs (FontAwesome, Material, etc.) as components.&lt;/p&gt;

&lt;p&gt;React Icons makes it easy to import and style only the icons you need. Works great with Tailwind and other styling libraries.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://react-icons.github.io/react-icons/" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  12. React DnD
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; Drag-and-drop interface with full control.&lt;/p&gt;

&lt;p&gt;Built by the React community, this gives you precise control over draggable interfaces like Kanban boards.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://react-dnd.github.io/react-dnd/" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The React ecosystem is thriving, but that also means constant change. The libraries above are ones you can trust—actively maintained, battle-tested, and developer-friendly.&lt;/p&gt;

&lt;p&gt;Save this post, revisit it throughout the year, and let me know which libraries you’re using in production!&lt;/p&gt;




&lt;p&gt;📝 Originally published at &lt;a href="https://www.grantwatson.dev/blog/12-powerful-react-libraries-every-developer-should-master-in-2025" rel="noopener noreferrer"&gt;grantwatson.dev/blog&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Mastering Automation: 5 Real-World n8n Workflow Examples (With Step-by-Step Guides)</title>
      <dc:creator>Grant Watson</dc:creator>
      <pubDate>Mon, 21 Jul 2025 16:42:09 +0000</pubDate>
      <link>https://dev.to/grantwatsondev/mastering-automation-5-real-world-n8n-workflow-examples-with-step-by-step-guides-fmc</link>
      <guid>https://dev.to/grantwatsondev/mastering-automation-5-real-world-n8n-workflow-examples-with-step-by-step-guides-fmc</guid>
      <description>&lt;h1&gt;
  
  
  Mastering Automation: 5 Real-World n8n Workflow Examples (With Step-by-Step Guides)
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.grantwatson.dev/blog" rel="noopener noreferrer"&gt;This and other articles of mine can be found here&lt;/a&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  📌 Overview
&lt;/h2&gt;

&lt;p&gt;n8n is an open-source workflow automation tool that allows you to connect services (APIs, webhooks, databases, CRMs, and more) into powerful automations without writing boilerplate glue code. Whether you're a beginner or seasoned power user, this article provides &lt;strong&gt;5 comprehensive, real-world workflows&lt;/strong&gt; to launch your n8n journey or deepen your automation chops.&lt;/p&gt;

&lt;p&gt;Each example includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use case breakdown&lt;/li&gt;
&lt;li&gt;Step-by-step setup&lt;/li&gt;
&lt;li&gt;Real-world benefits&lt;/li&gt;
&lt;li&gt;JSON download (optional)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔧 Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before diving in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install n8n (self-hosted Docker or cloud-based)&lt;/li&gt;
&lt;li&gt;Have credentials ready (e.g., Gmail, Notion, GitHub)&lt;/li&gt;
&lt;li&gt;Know how to use the &lt;a href="https://docs.n8n.io" rel="noopener noreferrer"&gt;n8n Editor UI&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 Workflow 1: Automatic Lead Collection from Typeform to Notion CRM
&lt;/h2&gt;

&lt;h3&gt;
  
  
  💡 Use Case
&lt;/h3&gt;

&lt;p&gt;You want to capture leads from a Typeform form and store them in your Notion CRM database automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧱 Tools
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Trigger: Typeform Trigger&lt;/li&gt;
&lt;li&gt;Action: Notion node (Database row creation)&lt;/li&gt;
&lt;li&gt;Optional: Email confirmation via Gmail&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🛠 Step-by-Step
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a Typeform&lt;/strong&gt; with fields like Name, Email, Company.&lt;/li&gt;
&lt;li&gt;In n8n:

&lt;ul&gt;
&lt;li&gt;Add &lt;strong&gt;Typeform Trigger&lt;/strong&gt; → Select your form&lt;/li&gt;
&lt;li&gt;Add &lt;strong&gt;Notion&lt;/strong&gt; node:

&lt;ul&gt;
&lt;li&gt;Choose your database&lt;/li&gt;
&lt;li&gt;Map &lt;code&gt;answers.fields&lt;/code&gt; from Typeform to Notion properties&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;(Optional) Add &lt;strong&gt;Gmail&lt;/strong&gt; node to email the lead a thank-you note.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  ✅ Real-World Impact
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Eliminates manual copy-pasting.&lt;/li&gt;
&lt;li&gt;Keeps your CRM always up-to-date.&lt;/li&gt;
&lt;li&gt;Saves time for your sales team.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🗓 Workflow 2: Google Calendar Event → Slack Notification + Mattermost Alert
&lt;/h2&gt;

&lt;h3&gt;
  
  
  💡 Use Case
&lt;/h3&gt;

&lt;p&gt;Notify your team in both Slack and Mattermost whenever a new calendar event is added.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧱 Tools
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Trigger: Google Calendar node (polling)&lt;/li&gt;
&lt;li&gt;Actions: Slack, Mattermost&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🛠 Step-by-Step
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Add &lt;strong&gt;Google Calendar&lt;/strong&gt; node (polling every 10 minutes)&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;Slack&lt;/strong&gt; node:

&lt;ul&gt;
&lt;li&gt;Format: "New Event: &lt;code&gt;{{summary}}&lt;/code&gt; at &lt;code&gt;{{start}}&lt;/code&gt;"&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Add &lt;strong&gt;Mattermost&lt;/strong&gt; node:

&lt;ul&gt;
&lt;li&gt;Webhook URL&lt;/li&gt;
&lt;li&gt;Use same message template&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  ✅ Real-World Impact
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Ensures every team member is notified, no matter their preferred chat app.&lt;/li&gt;
&lt;li&gt;Prevents missed meetings.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📝 Workflow 3: GitHub Issue → Create Jira Ticket → Email Developer
&lt;/h2&gt;

&lt;h3&gt;
  
  
  💡 Use Case
&lt;/h3&gt;

&lt;p&gt;New GitHub issues automatically create Jira tasks and notify the assigned dev by email.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧱 Tools
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Trigger: GitHub (Webhook)&lt;/li&gt;
&lt;li&gt;Actions: Jira Software, Gmail&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🛠 Step-by-Step
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Add &lt;strong&gt;GitHub Trigger&lt;/strong&gt; → Connect webhook to repo&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;Jira node&lt;/strong&gt; to create an issue:

&lt;ul&gt;
&lt;li&gt;Project, Summary, Description from GitHub payload&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;Gmail node&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Subject: &lt;code&gt;New Issue Assigned: {{issue.title}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Body: Include GitHub and Jira links&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  ✅ Real-World Impact
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;DevOps automation: from bug discovery to tracking in one sweep.&lt;/li&gt;
&lt;li&gt;Instant communication loop.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧾 Workflow 4: Daily Digest of New RSS Articles to Email
&lt;/h2&gt;

&lt;h3&gt;
  
  
  💡 Use Case
&lt;/h3&gt;

&lt;p&gt;Receive a curated daily email of tech news articles from multiple RSS feeds.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧱 Tools
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Trigger: Schedule (Daily)&lt;/li&gt;
&lt;li&gt;Actions: Multiple RSS Feed nodes, Merge, Gmail&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🛠 Step-by-Step
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Add &lt;strong&gt;Schedule node&lt;/strong&gt;: daily at 8 AM&lt;/li&gt;
&lt;li&gt;Add multiple &lt;strong&gt;RSS Feed Read nodes&lt;/strong&gt; (e.g., Ars Technica, Hacker News, TechCrunch)&lt;/li&gt;
&lt;li&gt;Merge them using &lt;strong&gt;Merge node&lt;/strong&gt; (combine mode)&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;Set node&lt;/strong&gt; to format email body with titles + links&lt;/li&gt;
&lt;li&gt;Send email via &lt;strong&gt;Gmail&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  ✅ Real-World Impact
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Daily inbox summaries, no feed bloat.&lt;/li&gt;
&lt;li&gt;Saves hours of scrolling.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧮 Workflow 5: Auto Backup New Notion Pages to Google Drive as Markdown
&lt;/h2&gt;

&lt;h3&gt;
  
  
  💡 Use Case
&lt;/h3&gt;

&lt;p&gt;When a new page is created in Notion, export and save it as a Markdown file on Google Drive.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧱 Tools
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Trigger: Notion Trigger&lt;/li&gt;
&lt;li&gt;Actions: Notion → HTTP node (for Markdown conversion), Google Drive&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🛠 Step-by-Step
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Add &lt;strong&gt;Notion Trigger&lt;/strong&gt; for new pages in a workspace&lt;/li&gt;
&lt;li&gt;Retrieve content using &lt;strong&gt;Notion Content node&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;HTTP node&lt;/strong&gt; to convert content to Markdown (or use JS function to clean format)&lt;/li&gt;
&lt;li&gt;Save the &lt;code&gt;.md&lt;/code&gt; file using &lt;strong&gt;Google Drive&lt;/strong&gt; upload node&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  ✅ Real-World Impact
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Version-controlled documentation.&lt;/li&gt;
&lt;li&gt;Local backups for regulatory or compliance reasons.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧩 Bonus Ideas for Advanced Users
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;th&gt;Tools&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Auto-post job listings from RSS to LinkedIn&lt;/td&gt;
&lt;td&gt;RSS → HTTP (LinkedIn API)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Daily DB backup to S3&lt;/td&gt;
&lt;td&gt;PostgreSQL node → AWS S3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sync rows between Airtable &amp;amp; Google Sheets&lt;/td&gt;
&lt;td&gt;Airtable → Google Sheets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ChatGPT Summarizer for new YouTube uploads&lt;/td&gt;
&lt;td&gt;YouTube → HTTP (OpenAI) → Email&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trigger webhook from Mattermost slash command&lt;/td&gt;
&lt;td&gt;Webhook → Custom Logic → Response&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  📥 Best Practices for Workflow Building
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use Namespaces&lt;/strong&gt; – Name every node clearly (&lt;code&gt;getIssueDetails&lt;/code&gt;, &lt;code&gt;sendSlackAlert&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Group with Notes&lt;/strong&gt; – Add descriptive notes to each logic block.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error Handling&lt;/strong&gt; – Use the &lt;strong&gt;Error Trigger&lt;/strong&gt; to catch and report errors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version Control&lt;/strong&gt; – Export workflows as JSON to Gitea or GitHub.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt; – Never expose credentials in plain text. Use secrets and environment variables.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🎓 Where to Learn More
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.n8n.io/" rel="noopener noreferrer"&gt;n8n Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://community.n8n.io/" rel="noopener noreferrer"&gt;n8n Community Forum&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ivov/n8n-resources" rel="noopener noreferrer"&gt;Awesome n8n GitHub List&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;n8n is more than just a no-code tool—it's a &lt;strong&gt;logic engine&lt;/strong&gt; that empowers creators, developers, and teams to build &lt;strong&gt;tailored automations&lt;/strong&gt; that match their workflows precisely. Whether you’re building a SaaS platform, syncing internal tools, or just automating your morning, these workflows give you a strong launchpad.&lt;/p&gt;

&lt;p&gt;Save this article. Build from these. Then go create something remarkable.&lt;/p&gt;

</description>
      <category>sql</category>
      <category>programming</category>
    </item>
    <item>
      <title>Sell Yourself as a Developer: Creating a Personal Brand That Stands Out</title>
      <dc:creator>Grant Watson</dc:creator>
      <pubDate>Tue, 27 May 2025 22:37:47 +0000</pubDate>
      <link>https://dev.to/grantwatsondev/sell-yourself-as-a-developer-creating-a-personal-brand-that-stands-out-mmf</link>
      <guid>https://dev.to/grantwatsondev/sell-yourself-as-a-developer-creating-a-personal-brand-that-stands-out-mmf</guid>
      <description>&lt;p&gt;In a world full of portfolios, GitHub profiles, and online résumés, it’s easy to feel like one developer in a sea of sameness. But here’s the truth: if you want better opportunities, better projects, and more control over your career—you need to sell yourself. And that starts with a personal brand.&lt;/p&gt;

&lt;p&gt;You might think “branding” is just for influencers and startups. Not true. As a developer, your brand is your reputation made visible.&lt;/p&gt;

&lt;p&gt;Here’s how to build it, own it, and let it open doors.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;🧭 Know What You Want to Be Known For&lt;/p&gt;

&lt;p&gt;Before you can create a personal brand, you need clarity. Ask yourself:&lt;br&gt;
    • What kind of problems do I love solving?&lt;br&gt;
    • Which technologies excite me most?&lt;br&gt;
    • Do I want to be known for front-end creativity, backend mastery, architecture, teaching, or something else?&lt;/p&gt;

&lt;p&gt;Your brand should be a reflection of both your skills and your passions. You can’t be the “everything” dev. Be the dev people remember for something specific.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;🌐 Build a Home for Your Work&lt;/p&gt;

&lt;p&gt;Every strong brand needs a place to live. For developers, this is your personal website or blog. It should include:&lt;br&gt;
    • A clean, focused portfolio with 2–4 strong projects&lt;br&gt;
    • A professional “About Me” section that shows personality and clarity&lt;br&gt;
    • Links to your GitHub, LinkedIn, Twitter, and blog&lt;/p&gt;

&lt;p&gt;If you want bonus points? Add a blog. Write about the things you’re learning or building. Teach what you know. It reinforces your brand and builds trust.&lt;/p&gt;

&lt;p&gt;Developers who blog consistently get noticed. Not just for what they build, but for how they think.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;📣 Talk About What You Do (Even If No One’s Listening Yet)&lt;/p&gt;

&lt;p&gt;Share progress on Twitter, LinkedIn, or dev communities. You don’t need to have a massive audience—you’re documenting your journey for future you and for the one person watching who might open a door.&lt;br&gt;
    • Share a cool solution to a problem you hit&lt;br&gt;
    • Post a demo or screenshot of a feature in progress&lt;br&gt;
    • Reflect on a challenge and how you overcame it&lt;/p&gt;

&lt;p&gt;This isn’t bragging. It’s visibility.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;💼 LinkedIn and GitHub: Signal vs. Noise&lt;/p&gt;

&lt;p&gt;Too many developers ignore or underuse these platforms.&lt;/p&gt;

&lt;p&gt;LinkedIn:&lt;br&gt;
    • Keep your headline crisp: “C# Backend Developer | Blazor + .NET Enthusiast” is better than “Software Engineer.”&lt;br&gt;
    • Fill out your “About” with what you do best and what you want next&lt;br&gt;
    • Share articles, comment on posts, be visible&lt;/p&gt;

&lt;p&gt;GitHub:&lt;br&gt;
    • Pin 3–6 repos that best reflect your skills&lt;br&gt;
    • Keep READMEs sharp and clean&lt;br&gt;
    • Avoid noisy commit histories on weak toy projects&lt;/p&gt;

&lt;p&gt;These platforms aren’t just your résumé—they’re your billboard.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;🔍 Be Searchable, and Make It Easy to Connect&lt;/p&gt;

&lt;p&gt;Use your full name consistently across platforms (or your brand handle). Make sure people can find you by name, GitHub handle, or blog title.&lt;/p&gt;

&lt;p&gt;Add contact forms. Post a professional email. Link to your site in your GitHub bio. Make it easy for someone to reach out after they see your work.&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;💥 The X-Factor: Authenticity&lt;/p&gt;

&lt;p&gt;The strongest brands aren’t fake. They’re focused. You don’t need to pretend to be a 10x genius or tweet in memes. You just need to show up consistently, share your work, and make your value obvious.&lt;/p&gt;

&lt;p&gt;Let people see:&lt;br&gt;
    • What you care about&lt;br&gt;
    • What problems you solve well&lt;br&gt;
    • Why you’re worth working with&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;🚀 Final Thought&lt;/p&gt;

&lt;p&gt;Your brand is already forming, whether you’re shaping it or not. Every project you ship, every post you write, and every way you show up online adds to that signal.&lt;/p&gt;

&lt;p&gt;The question is—are you curating it? Or leaving it to chance?&lt;/p&gt;

&lt;p&gt;If you want to stand out as a developer, don’t just write good code.&lt;/p&gt;

&lt;p&gt;Sell it. Shape it. Share it.&lt;/p&gt;

&lt;p&gt;That’s your personal brand.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>One Way Binding in Blazor Components</title>
      <dc:creator>Grant Watson</dc:creator>
      <pubDate>Sun, 25 Jul 2021 03:36:49 +0000</pubDate>
      <link>https://dev.to/grantwatsondev/one-way-binding-in-blazor-components-1j3o</link>
      <guid>https://dev.to/grantwatsondev/one-way-binding-in-blazor-components-1j3o</guid>
      <description>&lt;p&gt;&lt;a href="https://www.grantwatson.app/blog/blazor-components-one-way-binding" rel="noopener noreferrer"&gt;ORIGINAL POST&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Blazor Components: One Way Data Binding
&lt;/h2&gt;

&lt;p&gt;One of the major roles of a developer is on how they can make a static page either in a desktop, mobile or web application dynamic, or even if it needs to be. Binding data is a fundamental task in any single page applications (SPAs). At some point every application needs to either display data in form of labels, or receive data in the form of input fields and select boxes. &lt;/p&gt;

&lt;p&gt;While most SPA frameworks have similar concepts for data binding, either one way binding or two way binding, the way they work and are implemented varies widely. In this post, we're going to have a good look at how one way and two way binding work in Blazor.&lt;/p&gt;

&lt;h3&gt;
  
  
  One Way Binding
&lt;/h3&gt;

&lt;p&gt;One way bindings have a unidirectional flow, meaning that updates to the value only flow one way. A couple of examples of one way binding are rendering a label dynamically or dynamically outputting a CSS class name in markup. &lt;/p&gt;

&lt;p&gt;One way bindings can be constant and not change, but often the value will have a reason to be updated. Otherwise it would probably be better to avoid using a bound value altogether and just type the value out directly. &lt;/p&gt;

&lt;p&gt;In Blazor, when modifying a one way binding the application is going to be responsible for making the change. This could be in response to user action or event such as a button click. The point being, that the user will never be able to modify the value directly, hence one way binding.&lt;/p&gt;

&lt;p&gt;Now that we have a rudimentary idea of what one way binding is, let’s take a look of it in the form of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;@Title&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;@code&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Banging Title Mate!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, we have a component which displays a heading. The contents of that heading, Title, is a one way bound value. In order to bind one way values we use the @ symbol followed by the property, the field or even the method we want to bind too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;@Title&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="n"&gt;@onclick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"UpdateTitle"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Click&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;Update&lt;/span&gt; &lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;@code&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hello, World!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;UpdateTitle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Greeting, Blazor Friends!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the first example the value is set and never changed, in this example we've added a method which updates the value of Title when the button is clicked. &lt;/p&gt;

&lt;p&gt;As we talked about previously, values can only be updated in one direction and here we can see that in action. When the buttons onclick event is triggered the UpdateTitle method is called and Title property is updated to the new value. Executing event handlers in Blazor triggers a re-render which updates the UI.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;One Way Binding Between Components&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the previous examples, we looked at one way binding inside of a component. But what if we want one way binding across components? Using our previous example, say we wanted to display the title of a parent component in a child component, how could we achieve this? By using component parameters.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;!--&lt;/span&gt; &lt;span class="n"&gt;Parent&lt;/span&gt; &lt;span class="n"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;--&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;@Title&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="n"&gt;@onclick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"UpdateTitle"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Update&lt;/span&gt; &lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ChildComponent&lt;/span&gt; &lt;span class="n"&gt;ParentsTitle&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Title"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;@code&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hello, World!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;UpdateTitle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hello, Blazor!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;!--&lt;/span&gt; &lt;span class="n"&gt;Child&lt;/span&gt; &lt;span class="n"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;--&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Parent&lt;/span&gt; &lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;@ParentsTitle&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;@code&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Parameter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;ParentsTitle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example, the parent component is passing its title into the child component via the child components ParentsTitle component parameter. When then components are first rendered the headings will be the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;!--&lt;/span&gt; &lt;span class="n"&gt;Parent&lt;/span&gt; &lt;span class="n"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;--&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;World&lt;/span&gt;&lt;span class="p"&gt;!&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;!--&lt;/span&gt; &lt;span class="n"&gt;Child&lt;/span&gt; &lt;span class="n"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;--&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Parent&lt;/span&gt; &lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;World&lt;/span&gt;&lt;span class="p"&gt;!&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the Update Title button is pressed then the output will become the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;!--&lt;/span&gt; &lt;span class="n"&gt;Parent&lt;/span&gt; &lt;span class="n"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;--&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Blazor&lt;/span&gt;&lt;span class="p"&gt;!&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;!--&lt;/span&gt; &lt;span class="n"&gt;Child&lt;/span&gt; &lt;span class="n"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;--&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Parent&lt;/span&gt; &lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Blazor&lt;/span&gt;&lt;span class="p"&gt;!&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similar to what happened with the earlier example inside a single component. The button click event calls the UpdateTitle method and the Title property is updated. Then the running of the event handler triggers a re-render of the parent component. &lt;/p&gt;

&lt;p&gt;This also updates the Title parameter passed to the child component. Updating the component parameter triggers a re-render of the child component, updating its UI with the new title.&lt;/p&gt;

&lt;p&gt;I cannot wait to start working on the next post for 2 way binding. If you would like to have me as your personal coach for learning how to program, feel free to email me &lt;a href="https://www.grantwatson.app/contact" rel="noopener noreferrer"&gt;here&lt;/a&gt; or email me directly at &lt;a href="mailto:info@grantwatson.dev"&gt;info@grantwatson.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>blazor</category>
      <category>microsoft</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Blazor Components</title>
      <dc:creator>Grant Watson</dc:creator>
      <pubDate>Tue, 20 Jul 2021 21:22:47 +0000</pubDate>
      <link>https://dev.to/grantwatsondev/blazor-components-3fa</link>
      <guid>https://dev.to/grantwatsondev/blazor-components-3fa</guid>
      <description>&lt;p&gt;&lt;a href="https://www.grantwatson.app/blog/blazor-components" rel="noopener noreferrer"&gt;ORIGINAL POST&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Blazor Components Basics and Simple Structure:
&lt;/h1&gt;

&lt;h3&gt;
  
  
  What are Blazor components?
&lt;/h3&gt;

&lt;p&gt;A Blazor component is an independent part of the Blazor Application. These entities can be as simple or as complex as the application calls for. Blazor applications are made utilizing parts that are adaptable, lightweight, and can be settled, reused, and shared between ventures. A component is the base component of the Blazor application, i.e., each page is considered as a segment in Blazor.&lt;/p&gt;

&lt;p&gt;It utilizes the mix of Razor, HTML, and C# code as a part. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;@page&lt;/span&gt; &lt;span class="s"&gt;"/counter"&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;@currentCount&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="err"&gt;="&lt;/span&gt;&lt;span class="nc"&gt;btn&lt;/span&gt; &lt;span class="n"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;primary&lt;/span&gt;&lt;span class="s"&gt;" onclick="&lt;/span&gt;&lt;span class="n"&gt;@IncrementCount&lt;/span&gt;&lt;span class="s"&gt;"&amp;gt;Click me&amp;lt;/button&amp;gt;
&lt;/span&gt;
&lt;span class="n"&gt;@functions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;currentCount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;IncrementCount&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;currentCount&lt;/span&gt;&lt;span class="p"&gt;++;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Blazor segments are executed in *.cshtml records utilizing a mix of C# and HTML markup. The UI for a segment is characterized utilizing HTML while dynamic delivering rationale like circles, conditionals, articulations are included utilizing an installed C# language structure called Razor.&lt;/p&gt;

&lt;p&gt;In the work square, we can characterize all the properties that are utilized in see markup, and the techniques are bound with control as an occasion.&lt;/p&gt;

&lt;p&gt;At the point when a Blazor application is assembled, the HTML markup and C# delivering rationale are changed over into a part class, and the name of the produced class coordinates the name of the record.&lt;/p&gt;

&lt;h3&gt;
  
  
  Component Members
&lt;/h3&gt;

&lt;p&gt;Individuals from the segment class are characterized in a @functions square, and you can utilize more than one @functions obstruct in a part. In the @functions square, segment states, for example, properties and fields are determined alongside strategies for occasion taking care of or for characterizing other part rationales. Segment individuals would then be able to be utilized as a major aspect of the part's delivering rationale utilizing C# articulations that start with &lt;em&gt;@&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;All rendered Blazor views descend from the ComponentBase class, this includes Layouts, Pages, and also Components.&lt;/p&gt;

&lt;p&gt;A Blazor page is essentially a component with a &lt;em&gt;&lt;a class="mentioned-user" href="https://dev.to/page"&gt;@page&lt;/a&gt;&lt;/em&gt; directive that specifies the URL the browser must navigate to in order for it to be rendered. In fact, if we compare the generated code for a component and a page there is very little difference. The following generated source code can be found in &lt;em&gt;Counter.razor.g.cs&lt;/em&gt; in the folder &lt;em&gt;obj\Debug\netcoreapp3.0\Razor\Pages&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;SomeBlazorApp.Client.Pages&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Microsoft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AspNetCore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Components&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LayoutAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MainLayout&lt;/span&gt;&lt;span class="p"&gt;))]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Microsoft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AspNetCore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Components&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RouteAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/counter"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Microsoft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AspNetCore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Components&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComponentBase&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;BuildRenderTree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Microsoft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AspNetCore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Components&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderTree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderTreeBuilder&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Code omitted for simplicity&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;IncrementCounter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;++;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;[Microsoft.AspNetCore.Components.RouteAttribute("/counter")]&lt;/em&gt; identifies the URL for the page.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;[Microsoft.AspNetCore.Components.LayoutAttribute(typeof(MainLayout))]&lt;/em&gt; identifies which layout to use.&lt;/p&gt;

&lt;p&gt;In fact, because pages are merely components decorated with additional attributes, if you alter the Pages/Index.razor file of a default Blazor app, it is possible to embed the Counter page as a component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;@page&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;world&lt;/span&gt;&lt;span class="p"&gt;!&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;Welcome&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When embedding a page within another page, Blazor treats it as a component. The LayoutAttribute on the embedded page is ignored because Blazor already has an explicit container – the parent component that contains it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Components
&lt;/h2&gt;

&lt;p&gt;Depending on your hosting service, and whether you chose Blazor WebAssembly or Blazor Server, the following may be ambiguous. But let’s say for simplicity sake, your main solution has 3 projects: Client/Server/Shared.&lt;/p&gt;

&lt;h4&gt;
  
  
  Under the Client Project:
&lt;/h4&gt;

&lt;p&gt;Make a new folder called Components. This name can be anything that you wish it to be, for it is not a special or “needed” name. Once you have create the folder, create a file within the folder and name it ComponentOne.razor and the following markup is the starting point of any new component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Section 1&lt;/span&gt;
&lt;span class="n"&gt;@page&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt;

&lt;span class="c1"&gt;//Section 2&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="n"&gt;Hello&lt;/span&gt; &lt;span class="n"&gt;World&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="n"&gt;Welcome&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt; &lt;span class="n"&gt;component&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;//Section 3&lt;/span&gt;
&lt;span class="n"&gt;@code&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//empty code block&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s stop for a quick moment to discuss what each section is. If you have ever worked in ReactJS or Angular, this may look familiar to you, and feel free to go forward. If this is your first time working in a front end framework, let’s go over some basics:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Section 1:&lt;/em&gt;&lt;br&gt;
For clarity and simplicity over the structure/architecture of a component, this is where you will post and dictate your using statements for your components. There is a _Import.razor file to where you can place your using statements, but this is beyond the scope of this article. When you need to declare another file from your solution into you component, put them at the top of your component here. This is also where you can call your Nuget packages you specifically want to use in your component.&lt;/p&gt;

&lt;p&gt;The next area you see here is the &lt;a class="mentioned-user" href="https://dev.to/page"&gt;@page&lt;/a&gt; “/”&lt;/p&gt;

&lt;p&gt;Similar with routing in React, we dictate the routing of this particular component as “/”. Again, routing is outside the scope of this article, I will have another article covering this in the future.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Section 2:&lt;/em&gt;&lt;br&gt;
This area should look “easy” to you. Especially if your component is a simple display component. This area is where you place your HTML code inside the component.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Section 3:&lt;/em&gt;&lt;br&gt;
This area is the fun part of the component in my opinion. This is where we combine C# syntax into the component itself. May it be service calls, httpClient and JSON calls to APIs. In this code block, you as the developer can make you component perform magic here.&lt;/p&gt;

&lt;p&gt;In the next few articles, I will go into more in the depth and breadth of components, and the following is what I am considering covering:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;One Way Binding in Components&lt;/li&gt;
&lt;li&gt;Two Way Binding in Components&lt;/li&gt;
&lt;li&gt;Component Literals, Expressions, and Directives&lt;/li&gt;
&lt;li&gt;Browser DOM and Component Events&lt;/li&gt;
&lt;li&gt;Cascading Values&lt;/li&gt;
&lt;li&gt;Code Generated HTML Attributes&lt;/li&gt;
&lt;li&gt;Capturing Unexpected Parameters&lt;/li&gt;
&lt;li&gt;Replacing Attributes on child components&lt;/li&gt;
&lt;li&gt;Component Lifecycles&lt;/li&gt;
&lt;li&gt;Multi-threaded rendering &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If there is a topic that you would like for me to cover with Blazor, or any language that you would like to see, please feel free to contact me through email at &lt;a href="mailto:info@grantwatson.dev"&gt;info@grantwatson.dev&lt;/a&gt; or on Twitter @granticusdev&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>blazor</category>
      <category>microsoft</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Programming Languages That Will Dominate</title>
      <dc:creator>Grant Watson</dc:creator>
      <pubDate>Mon, 29 Mar 2021 01:31:36 +0000</pubDate>
      <link>https://dev.to/grantwatsondev/programming-languages-that-will-dominate-1kh9</link>
      <guid>https://dev.to/grantwatsondev/programming-languages-that-will-dominate-1kh9</guid>
      <description>&lt;p&gt;&lt;a href="https://www.grantwatson.app/blog/top-programming-languages-2021" rel="noopener noreferrer"&gt;Original Post&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Forecasting the world’s most popular programming languages over the next few years is a difficult task. Oftentimes, bold predictions about a language’s dominance won’t pan out; then you have the languages that seem to come out of nowhere to seize a significant niche (often with a bit of a boost from a major tech company). &lt;/p&gt;

&lt;p&gt;Every so often, though, a language’s spike in popularity makes it easier to predict its rosy future. It’s all about the long term—and you should structure your learning (and mastery) appropriately. “I’d recommend deciding what’s important and building your working culture around it rather than worrying about whether you’re missing out by not using a new language,” he adds. “If you’re an individual engineer and want to know how you can help yourself, double down on the fundamentals of how the languages you currently work in interact with the underlying operating system or runtime. A little focus on the fundamentals goes a long way here, and the fundamentals will still be the same in 2030.”&lt;/p&gt;

&lt;p&gt;So which programming languages will continue to dominate in 2021? &lt;/p&gt;

&lt;h2&gt;
  
  
  Python
&lt;/h2&gt;

&lt;p&gt;Artur Yolchan, Senior Software Engineer and owner of the website Coding Skills, says: “Python will probably be the most favorite programming language for developers in 2021.” &lt;/p&gt;

&lt;p&gt;The increased use of Python in a specialized context has a lot to do with that, suggests Alex Yelenevych, CMO of CodeGym: “In the development of artificial intelligence systems, Python has proven itself. In addition, many modern and safe sites are written in Python, and it is also very often learned in schools. The language is pleasant and quite simple for beginners, so its popularity will only grow.”&lt;/p&gt;

&lt;p&gt;It takes a lot to erode the usage of older, more generalist programming languages, even when newer languages begin to attract a lot of buzz, adds Matt Pillar, VP of Engineering at OneSignal: “Python is an old favorite, and it’s not going away anytime soon. While incumbents like Rust and TypeScript are occupying more and more mindshare, taking some attention away from Python, Python continues to be one of the most loved and most utilized programming languages. With its strong connection to data science toolkits, Python is being taught at an increasing number of programming bootcamps and is well poised to be a favorite first language for developers in the years to come.”&lt;/p&gt;

&lt;p&gt;If you’re totally new to Python, start your learning journey by heading over to Python.org, which offers a handy beginner’s guide. Microsoft has a video series, “Python for Beginners,” with dozens of short, Python-related lessons. There’s also a variety of Python tutorials and books (some of which will cost a monthly fee) that will teach you the nuances of the programming language (and don’t forget your IDEs).&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript
&lt;/h2&gt;

&lt;p&gt;Michael O’Connell, Chief Analytics Officer at TIBCO Software, doesn’t think the ultra-popular JavaScript is going anywhere, especially when it comes to dominating developers’ mindshare in 2021:&lt;/p&gt;

&lt;p&gt;The maturation of JavaScript as a design and development environment has been phenomenal and will accelerate in 2021. Whether you are working on the front-end with JavaScript, apps and frameworks with React, Angular and vue.js, desktop apps with Electron.js, or backend with Node.js, JavaScript is the ticket! You can even develop machine learning with Tensorflow.js. &lt;/p&gt;

&lt;p&gt;I see the worlds of self-service BI and visual analytics becoming ever more mashed up in 2021 with (a) BI and analytics vendors providing seamless experiences for extending their graphics palettes as simple-to-modify native capabilities and deployment; and (b) marketplaces for sharing extensions across broad communities of practice. The maturation of Vega (from the d3 pioneers) as a visualization grammar and platform will help standardize and enforce best practices across these communities.&lt;/p&gt;

&lt;p&gt;Yelenevych agrees, citing JavaScript’s frameworks as a key component to its success. “JavaScript—you can find this language in use on almost every website. I think React, already the most popular JS frontend library, will continue to gain popularity. In general, developers love to create applications in React.”&lt;/p&gt;

&lt;p&gt;Indeed, it seems virtually certain that JavaScript will continue to serve as the engine that powers the web well beyond 2021, especially as new generations of students utilize it for websites’ scripted behavior. Millions of websites will still rely on third-party JavaScript libraries and frameworks. &lt;/p&gt;

&lt;h2&gt;
  
  
  Blazor
&lt;/h2&gt;

&lt;p&gt;With the popularity of C#, I believe deeply that Blazor will become extremely popular this year. Typically speaking, programmers love working in one language, especially if that particular language is used for web development. In previous years, for any form of web development, a developer needed at least 2 different languages, a backend API as well as JavaScript/TypeScript. With Blazor now, you can potentially dismantle all use of JS for the use of C# from the backend to the frontend. They utilized the Razor language and WebAssembly, as well as a server side rendering. To read more, see a few of my previous articles listed below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.grantwatson.app/blog/blazor-dependency-injection" rel="noopener noreferrer"&gt;Data Injection&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.grantwatson.app/blog/blazor-data-binding" rel="noopener noreferrer"&gt;Data Binding&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.grantwatson.app/blog/deep-dive-blazor-routing" rel="noopener noreferrer"&gt;Routing&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.grantwatson.app/blog/deep-dive-blazor-components" rel="noopener noreferrer"&gt;Blazor Components&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.grantwatson.app/blog/deep-dive-blazor-server" rel="noopener noreferrer"&gt;Blazor Server&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.grantwatson.app/blog/deep-dive-blazor-wasm" rel="noopener noreferrer"&gt;Blazor Wasm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.grantwatson.app/blog/blazing-good-time-with-blazor" rel="noopener noreferrer"&gt;What is Blazor&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Why are code reviews important?</title>
      <dc:creator>Grant Watson</dc:creator>
      <pubDate>Mon, 15 Feb 2021 19:39:11 +0000</pubDate>
      <link>https://dev.to/grantwatsondev/why-are-code-reviews-important-995</link>
      <guid>https://dev.to/grantwatsondev/why-are-code-reviews-important-995</guid>
      <description>&lt;p&gt;Original post &lt;a href="https://www.grantwatson.app/blog/code-reviews-are-important" rel="noopener noreferrer"&gt;here&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Define what a code review is:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Code review is a software quality assurance activity in which one or several people check a program mainly by viewing and reading parts of its source code, and they do so after implementation or as an interruption of implementation.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Git Push &amp;amp; Merge Conflicts Galore
&lt;/h2&gt;

&lt;p&gt;Ideas of why it is a good idea to perform code reviews:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sharing of knowledge and new techniques&lt;/li&gt;
&lt;li&gt;Maintainability&lt;/li&gt;
&lt;li&gt;Compliance in quality and requirements&lt;/li&gt;
&lt;li&gt;Committers are motivated to write clean code, minimizing mistakes&lt;/li&gt;
&lt;li&gt;Sharing of knowledge and new techniques&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every project has a host of unwritten rules and tacit understandings. This "institutional knowledge" must be transmitted to all new arrivals on a project. By definition it is impossible (and perhaps not even cost effective) to write down this information or to convey it all in one sitting. The inductee must acquire this information in the first months on the project, usually elicited from experienced developers when he does something wrong.&lt;/p&gt;

&lt;p&gt;Code review can facilitate the communication of institutional knowledge as it relates to code written by the newbie. Experienced team members have the opportunity to impart their wisdom and advice.&lt;/p&gt;

&lt;p&gt;At the heart of all agile teams is unbeatable flexibility: an ability to take work off the backlog and begin execution by all team members. As a result, teams are better able to swarm around new work because no one is the "critical path." Full stack engineers can tackle front-end work as well as server-side work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ensuring maintainability
&lt;/h2&gt;

&lt;p&gt;The expense of developing software is not just in its initial creation but in the ability of developers to use and modify existing code in the future. Software is notoriously difficult and expensive to maintain. This is especially true when a developer leaves a project and a new developer arrives, but it is even true with a single developer looking back on code he wrote six months ago.&lt;/p&gt;

&lt;p&gt;Maintainability is generally achieved by code organization and adequate comments. A person uninvolved in the project should be able to read a portion of code and understand what it does, see the constraints and preconditions of its use and contextual information (e.g. the author used a peculiar technique because of a bug in the OS). In addition, software organizations often have coding guidelines ranging from whitespace conventions to the maximum size of a function. A reviewer can provide the ignorance and objectivity necessary to ensure these goals.&lt;/p&gt;

&lt;p&gt;Shell Research saved an average of 30 hours of maintenance work for every hour invested in inspections.&lt;/p&gt;

&lt;p&gt;— Software Practice and Experience, 22(2):173-182, Feb. 1992.&lt;/p&gt;

&lt;h2&gt;
  
  
  It dramatically improves code quality
&lt;/h2&gt;

&lt;p&gt;Let’s make something clear: this is not about standards and code linting (at least not exclusively). It’s about making code more efficient. In a team where everybody has their own background and strong suits, asking for improvements (because that’s what it’s about) is always a good idea. Someone could suggest a smarter solution, a more appropriate design pattern, a way to reduce complexity or to improve performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Minimizing your mistakes and their impact
&lt;/h2&gt;

&lt;p&gt;This might seem like the most obvious advantage to the code peer review process, but it’s also one of the most important. When you’re working with the real pressures of time and budget, it’s easy to skip this step. Sure, you’re confident in your work, but even the best coders can go crossed-eyed from looking at their own work too long. Code review helps give a fresh set of eyes to identify bugs and simple coding errors before your product gets to the next step, making the process for getting the software to the customer more efficient.&lt;/p&gt;

&lt;p&gt;Simply reviewing someone’s code and identifying errors is great. However, when it comes to the code peer review process there also needs to be a level of follow-up and accountability. Make sure there is process in place for checking back in to confirm code discrepancies have been addressed before moving into production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ensuring project quality and meeting requirements
&lt;/h2&gt;

&lt;p&gt;The scope of any given software project and its requirements might run through the hands of several developers. The code review process can serve as a check and balance against different interpretations of that scope and requirements compared to the code that ends up being delivered. The second set of eyes can ensure you don’t fall into the “pit” you created based on your own understanding of what is being asked and that something important hasn’t been overlooked. Having code scrutinized by your peers can save a lot of time “confronting” QA later on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Improving code performance
&lt;/h2&gt;

&lt;p&gt;Due to the lack of experience, some younger developers might be unaware of optimization techniques that could be applied on their code. The code review process provides an opportunity for these developers to acquire skills and boost the performance of their code. Additionally, it gives these younger developers a chance to hone their skills and become experts in their craft.&lt;/p&gt;

&lt;p&gt;While realizing the required functionalities, many developers also try to pursue optimized code for conciseness and performance efficiency. However, this will result in more code complexity and less readability. (Note: Code conciseness doesn’t mean its logic is simple to understand.) Moreover, the data model that the code is built on might change in later development phases. Thus, such premature optimization will eventually increase the cost of maintenance.&lt;/p&gt;

</description>
      <category>codenewbie</category>
      <category>testing</category>
      <category>reviews</category>
    </item>
    <item>
      <title>A Blazing Good Time in Blazor</title>
      <dc:creator>Grant Watson</dc:creator>
      <pubDate>Mon, 15 Feb 2021 19:28:39 +0000</pubDate>
      <link>https://dev.to/grantwatsondev/a-blazing-good-time-in-blazor-1b5f</link>
      <guid>https://dev.to/grantwatsondev/a-blazing-good-time-in-blazor-1b5f</guid>
      <description>&lt;p&gt;Original post &lt;a href="https://www.grantwatson.app/blog/blazing-good-time-with-blazor" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will be my first attempt at writing an article over something that I am learning on the way. Please be kind. I do think the best way that a person can learn something is to dive in and try and describe it another way, without diverting from the original definition. I am actually utilizing Blazor in an enterprise setting with my current position, so I am looking forward to learning about Blazor as my next step as a developer.&lt;/p&gt;

&lt;p&gt;This article will cover some of the basics of Blazor, as well as an entry point for a series of future articles. What I plan on covering in this article:&lt;/p&gt;

&lt;p&gt;What is Blazor?&lt;br&gt;
What can Blazor be used for?&lt;br&gt;
Blazor Hosting Models&lt;br&gt;
Blazor Architecture&lt;/p&gt;

&lt;p&gt;What do I plan on this series: &lt;/p&gt;

&lt;p&gt;Blazor WASM&lt;br&gt;
Blazor Server&lt;br&gt;
Blazor Components&lt;br&gt;
Data Binding&lt;br&gt;
Routing&lt;br&gt;
Dependency Injections&lt;br&gt;
Lifecycle Methods&lt;br&gt;
Invoke JS Functions&lt;br&gt;
View Logic Separations&lt;br&gt;
Forms and validation&lt;br&gt;
Server Side Rendering &lt;br&gt;
Client Side Rendering&lt;br&gt;
What is Blazor?&lt;/p&gt;

&lt;p&gt;So let’s get into it, what is Blazor. Blazor in of itself is Microsoft’s vision of a frontend framework. Blazor lets you build interactive web UIs using C# instead of JavaScript. Blazor apps are composed of reusable web UI components implemented using C#, HTML, and CSS. Both client and server code is written in C#, allowing you to share code and libraries. And we need to remember that Blazor is a feature of ASP.NET, so it can utilize other libraries of the .NET realm.&lt;/p&gt;

&lt;p&gt;What can Blazor be used for?&lt;/p&gt;

&lt;p&gt;Like I stated before, Blazor is part of Microsoft’s vision to allow it’s community of C# developers to continue in their route to write applications in C# from the backend to the frontend. Blazor allows for C# developers to limit their need of JavaScript. With that being said, there is still a need of JS in Blazor apps, more so in the JS Interop form, but not in as much as it was previously. Blazor should be categorized, and rightfully so, as a SPA framework. Microsoft took the concepts of other SPAs like Vue and React to make Blazor. Let’s build our applications in reusable components that can be utilized across our app(s). &lt;/p&gt;

&lt;p&gt;Being able to code in majority of one language throughout an application’s life cycle, as well as building reusable frontend components so that I can keep up with the DRY philosophy seems like a dream. For these two reason, Blazor is your answer, and this is what Blazor can be used for. If you are strong in your confidence of ASP.NET and Razor page syntax, Blazor will be your new favorite toy to breakout and play with. &lt;/p&gt;

&lt;p&gt;Blazor Hosting Models&lt;/p&gt;

&lt;p&gt;There are two hosting models new developers to this arena need to know about: Blazor Server, and Blazor WebAssembly.  Dependent on the structure of your needs for an new application will depend on the hosting model that you do.&lt;/p&gt;

&lt;p&gt;Blazor Server:&lt;/p&gt;

&lt;p&gt;With this hosting model, the app is executed on the server from withing an ASP.NET Core app. UI updates/changes, as well as some JS calls are handled over SignalR connection. &lt;/p&gt;

&lt;p&gt;There are a lot of benefits from using this model:&lt;/p&gt;

&lt;p&gt;Download size is significantly smaller that a WASM (another name for WebAssembly)&lt;br&gt;
The app takes full advantage of server capabilities, including use of any .Net Core compatible APIs&lt;br&gt;
.Net Core on the server is used to run the app, so existing .Net tooling, such as debugging, works as expected.&lt;br&gt;
Thin clients are supported. For example, Blazor Server apps work with browsers that do not support WebAssembly and on resource-constrained devices&lt;br&gt;
The app’s .Net/C# code base, including the app’s component code, isn’t served to the client&lt;br&gt;
There are some cons of Blazor Server hosting:&lt;/p&gt;

&lt;p&gt;Higher latency usually exists. Every user interaction involves a network hop&lt;br&gt;
There’s no offline support. If the client connection fails, the app stops working.&lt;br&gt;
Scalability is challenging for apps with many users. The server must manage multiple client connections and handle client state.&lt;br&gt;
An ASP.NET Core server is required to serve the app. Serverless development scenarios aren’t possible. &lt;br&gt;
Blazor WebAssembly(also known as WASM):&lt;/p&gt;

&lt;p&gt;If Blazor Server runs on the server, you can safely assume, correctly so, that Blazor WASM runs on the client side inside the browser. This allows your site to be deployed as static files. Despite this, Blazor WASM apps will not directly run from the local file system due o the browser security restrictions. &lt;/p&gt;

&lt;p&gt;Some of the benefits of Blazor WASM hosting:&lt;/p&gt;

&lt;p&gt;Blazor WASM can work offline. When the network connection to the server is lost, the client app can continue to function. We can utilize sessionStorage/localDb/IndexedDB for “saving” items so once the network comes back up, the client app can talk to the server. Client resources and capabilities are fully leveraged.&lt;br&gt;
It can also quite easily run as a Progressive Web App, which means the client can choose to install our app onto their device and run it whenever they wish without any network access at all.&lt;br&gt;
With code running on the client’s machine it means the server load is significantly reduced.&lt;br&gt;
An ASP.NET Core web server isn't required to host the app. Serverless deployment scenarios are possible (for example, serving the app from a CDN).&lt;br&gt;
There's no .NET server-side dependency. The app is fully functioning after it's downloaded to the client.&lt;br&gt;
Some cons/downsides to Blazor WASM hosting:&lt;/p&gt;

&lt;p&gt;The blazor.webassembly.js file bootstraps the client application. It downloads all required .NET DLL assemblies, which makes the start-up time of the application slower than server-side.&lt;br&gt;
The Mono Framework interprets .NET Intermediate Language so is slower than running server-side Blazor. Ahead-of-time (AOT) compilation is planned for a future release.&lt;br&gt;
Blazor Wasm does not yet support more than a single thread, so all processing occurs on the UI thread – although calls to servers / JavaScript etc occur asynchronously, so do not block the UI’s responsiveness.&lt;br&gt;
Additionally, Blazor Wasm only works on newer browsers and is not search-engine friendly (unless we enable server-side pre-rendering).&lt;br&gt;
Download size is larger, and apps take longer to load.&lt;br&gt;
.NET runtime and tooling support is less mature. For example, limitations exist in .NET Standard support and debugging.&lt;/p&gt;

&lt;p&gt;Blazor Architecture&lt;/p&gt;

&lt;p&gt;Traveling backwards a bit, Blazor in itself is strictly a client side web UI framework in nature to JavaScript frameworks like Angular and React. Blazor handles user interactions and renders the necessary UI updates. Blazor isn’t based on a request-reply model. User interactions are handled as events that aren’t in the context of any particular HTTP Request.&lt;/p&gt;

&lt;p&gt;Blazor apps consist of one or more root components that are rendered on an HTML page.&lt;/p&gt;

&lt;p&gt;How the user specifies where components should render and how the components are then wired up for user interactions is hosting model specific.&lt;/p&gt;

&lt;p&gt;Blazor components are .NET classes that represent a reusable piece of UI. Each component maintains its own state and specifies its own rendering logic, which can include rendering other components. Components specify event handlers for specific user interactions to update the component's state.&lt;/p&gt;

&lt;p&gt;After a component handles an event, Blazor renders the component and keeps track of what changed in the rendered output. Components don't render directly to the Document Object Model (DOM). They instead render to an in-memory representation of the DOM called a RenderTree so that Blazor can track the changes. Blazor compares the newly rendered output with the previous output to calculate a UI diff that it then applies efficiently to the DOM.&lt;/p&gt;

&lt;p&gt;Components can also manually indicate that they should be rendered if their state changes outside of a normal UI event. Blazor uses a SynchronizationContext to enforce a single logical thread of execution. A component's lifecycle methods and any event callbacks that are raised by Blazor are executed on this SynchronizationContext.&lt;/p&gt;

&lt;p&gt;I believe that this is a good overview of Blazor for now, and where this article comes to an end. I hope that you found this useful, and keep a look out for my other articles related to this one stated previously. If you have any questions, please comment below and I will reply back. The same goes for emails.&lt;/p&gt;

</description>
      <category>blazor</category>
      <category>ui</category>
    </item>
    <item>
      <title>Exception Handling in C#</title>
      <dc:creator>Grant Watson</dc:creator>
      <pubDate>Wed, 21 Oct 2020 17:41:02 +0000</pubDate>
      <link>https://dev.to/grantwatsondev/exception-handling-in-c-1fpm</link>
      <guid>https://dev.to/grantwatsondev/exception-handling-in-c-1fpm</guid>
      <description>&lt;p&gt;The original post was from my site &lt;a href="https://www.grantwatson.app/blog/csharp-exception-handling" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this post, I will cover, in short, C#’s exception handling. Other than syntax, you can take these principles forward with many OOP languages and utilize them. What are exceptions, and why should we as developers even consider handling them? Consider first what an exception is. Specifically in C#, an exception is a response to an exceptional circumstance that arises while a program is running, such as an attempt to divide by zero. Exceptions provide a way to transfer control from one part of a program to another. Another well thought definitions of an exception is that it is defined as an event that occurs during the execution of a program that is unexpected by the program code.&lt;/p&gt;

&lt;p&gt;Your code runs into an exception when you try to give it a value, or expect an output where either is not known within the program. Exception handling allows a graceful way to handle unwanted events, an exception so that the program code still makes sense to the user.&lt;/p&gt;

&lt;p&gt;The Anatomy of C# Exceptions&lt;br&gt;
Exceptions allow an application to transfer control from one part of the code to another. When an exception is thrown, the current flow of the code is interrupted and handed back to a parent try catch block. C# exception handling is done with the follow keywords: try, catch, finally, and throw&lt;/p&gt;

&lt;p&gt;Try: Used to define a try block. This block holds the code that may throw an exception&lt;/p&gt;

&lt;p&gt;Catch: Used to define the catch block. This block catches the exception thrown by the try block&lt;/p&gt;

&lt;p&gt;Finally: Used to define the finally block. This block holds the default code&lt;/p&gt;

&lt;p&gt;Throw: Used to throw an exception manually&lt;/p&gt;

&lt;p&gt;Example 1:&lt;/p&gt;

&lt;p&gt;using System;&lt;/p&gt;

&lt;p&gt;namespace ErrorHandlingApplication {&lt;br&gt;
   class DivNumbers {&lt;br&gt;
      int result;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  DivNumbers() {
     result = 0;
  }

  public void division(int num1, int num2) {
     try {
        result = num1 / num2;
     } catch (DivideByZeroException e) {
        Console.WriteLine("Exception caught: {0}", e);
     } finally {
        Console.WriteLine("Result: {0}", result);
     }
  }

  static void Main(string[] args) {
     DivNumbers d = new DivNumbers();
     d.division(25, 0);
     Console.ReadKey();
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
}&lt;br&gt;
Output&lt;/p&gt;

&lt;p&gt;Above, we have set the values in a try, and then caught exceptions in the catch. Finally is also set to show the result&lt;/p&gt;

&lt;p&gt;try {&lt;br&gt;
   result = num1 / num2;&lt;br&gt;
} catch (DivideByZeroException e) {&lt;br&gt;
   Console.WriteLine("Exception caught: {0}", e);&lt;br&gt;
} finally {&lt;br&gt;
   Console.WriteLine("Result: {0}", result);&lt;br&gt;
}&lt;br&gt;
Example #2: Exception Filters&lt;br&gt;
One of the new features in C# 6 was exception filters. They allow you have even more control over your catch blocks and further tailor how you handle specific exceptions. This can help you fine-tune exactly how you handle exceptions and which ones you want to catch.&lt;/p&gt;

&lt;p&gt;Before C# 6, you would have had to catch all types of a WebException and handle them. Now you could choose only to handle them in certain scenarios and let other scenarios bubble up to the code that called this method. Here is a modified example with filters:&lt;/p&gt;

&lt;p&gt;WebClient wc = null;&lt;br&gt;
try&lt;br&gt;
{&lt;br&gt;
   wc = new WebClient(); //downloading a web page&lt;br&gt;
   var resultData = wc.DownloadString("&lt;a href="http://google.com%22" rel="noopener noreferrer"&gt;http://google.com"&lt;/a&gt;);&lt;br&gt;
}&lt;br&gt;
catch (WebException ex) when (ex.Status == WebExceptionStatus.ProtocolError)&lt;br&gt;
{&lt;br&gt;
   //code specifically for a WebException ProtocolError&lt;br&gt;
}&lt;br&gt;
catch (WebException ex) when ((ex.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound)&lt;br&gt;
{&lt;br&gt;
   //code specifically for a WebException NotFound&lt;br&gt;
}&lt;br&gt;
catch (WebException ex) when ((ex.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.InternalServerError)&lt;br&gt;
{&lt;br&gt;
   //code specifically for a WebException InternalServerError&lt;br&gt;
}&lt;br&gt;
finally&lt;br&gt;
{&lt;br&gt;
   //call this if exception occurs or not&lt;br&gt;
   wc?.Dispose();&lt;br&gt;
}&lt;br&gt;
Common .NET Exceptions&lt;br&gt;
Proper exception handling is critical to all application code. There are a lot of standard exceptions that are frequently used. The most common being the dreaded null reference exception. These are some of the common C# Exception types that you will see on a regular basis.&lt;/p&gt;

&lt;p&gt;The follow is a list of common .NET exceptions:&lt;/p&gt;

&lt;p&gt;System.NullReferenceException – Very common exception related to calling a method on a null object reference&lt;/p&gt;

&lt;p&gt;System.IndexOutOfRangeException – Occurs attempting to access an array element that does not exist&lt;/p&gt;

&lt;p&gt;System.IO.IOException – Used around many file I/O type operations&lt;/p&gt;

&lt;p&gt;System.Net.WebException – Commonly thrown around any errors performing HTTP calls&lt;/p&gt;

&lt;p&gt;System.Data.SqlClient.SqlException – Various types of SQL Server exceptions&lt;/p&gt;

&lt;p&gt;System.StackOverflowException – If a method calls itself recursively, you may get this exception&lt;/p&gt;

&lt;p&gt;System.OutOfMemoryException – If your app runs out of memory&lt;/p&gt;

&lt;p&gt;System.InvalidCastException – If you try to cast an object to a type that it can’t be cast to&lt;/p&gt;

&lt;p&gt;System.InvalidOperationException – Common generic exception in a lot of libraries&lt;/p&gt;

&lt;p&gt;System.ObjectDisposedException – Trying to use an object that has already been disposed&lt;/p&gt;

&lt;p&gt;Here are a few articles to go into further detail of best practices:&lt;/p&gt;

&lt;p&gt;Exception Handling&lt;/p&gt;

&lt;p&gt;Microsoft Docs on Best Practices&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>exceptionhandling</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>The Realm of Virtual Reality</title>
      <dc:creator>Grant Watson</dc:creator>
      <pubDate>Wed, 19 Aug 2020 06:59:41 +0000</pubDate>
      <link>https://dev.to/grantwatsondev/the-realm-of-virtual-reality-2m87</link>
      <guid>https://dev.to/grantwatsondev/the-realm-of-virtual-reality-2m87</guid>
      <description>&lt;p&gt;Original Post found &lt;a href="https://www.grantwatson.app/blog/vr-part-1" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Definition:&lt;/p&gt;

&lt;p&gt;Virtual reality is a simulated experience that can be similar to or completely different from the real world. Applications of virtual reality can include entertainment and educational purposes. Other, distinct types of VR style technology include augmented reality and mixed reality.&lt;/p&gt;

&lt;p&gt;Contenders of the arena:&lt;/p&gt;

&lt;p&gt;Oculus&lt;/p&gt;

&lt;p&gt;Unity Technologies&lt;/p&gt;

&lt;p&gt;Virtuix&lt;/p&gt;

&lt;p&gt;Limbix&lt;/p&gt;

&lt;p&gt;I am utilizing this space to cover 4 companies in a 4 part series that are contenders in the VR realm. There are quite a few other companies that specialize in VR, but it will be interesting to see what these 4 companies have in common, as well as what makes them starkly different.&lt;/p&gt;

&lt;p&gt;Let’s start with the overall idea of virtual reality. It is not really a new concept. The idea of VR is plant oneself into an alternate realm of possibility. This could be, in essence, reading a book, role playing board games similar what DnD is, playing a video game. Up until maybe 10 years ago, we were unable to digest virtual reality in the context that we are today. &lt;/p&gt;

&lt;p&gt;Let’s expand on what virtual reality is.&lt;/p&gt;

&lt;p&gt;Virtual Reality (VR) is the use of computer technology to create a simulated environment.&lt;/p&gt;

&lt;p&gt;Virtual Reality’s most immediately-recognizable component is the head-mounted display (HMD). Human beings are visual creatures, and display technology is often the single biggest difference between immersive Virtual Reality systems and traditional user interfaces.&lt;/p&gt;

&lt;p&gt;Major players in Virtual Reality include HTC Vive, Oculus Rift and PlayStation VR (PSVR)&lt;/p&gt;

&lt;p&gt;You may ask what the difference between Virtual Reality and Augmented Reality? These two realities are just two sides of the same coin. You can think of Augmented Reality as VR with one foot in the real world: Augmented Reality stimulates artificial objects from the view point of the camera, superimposing the computer-generated images over a user’s view of the real world.&lt;/p&gt;

&lt;p&gt;In Augmented Reality, the computer uses sensors and algorithms to determine the position and orientation of a camera. AR technology than renders the 3D graphics as they would appear from the viewpoint of the camera, superimposing the computer-generated images over a user’s view of the real world.&lt;/p&gt;

&lt;p&gt;In Virtual Reality, the computer users similar sensors and math. However, rather than locating a real camera within a physical environment, the position of the user’s eyes are located within the simulated environment. If the user’s head turns, the graphics react accordingly. Rather than compositing virtual objects and a real scene, VR technology creates a convincing, interactive world for the user.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>WTF is JAMstack???</title>
      <dc:creator>Grant Watson</dc:creator>
      <pubDate>Wed, 19 Aug 2020 06:56:12 +0000</pubDate>
      <link>https://dev.to/grantwatsondev/wtf-is-jamstack-299p</link>
      <guid>https://dev.to/grantwatsondev/wtf-is-jamstack-299p</guid>
      <description>&lt;p&gt;Original post found &lt;a href="https://www.grantwatson.app/blog/wtf-is-jamstack" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am a subscriber to a podcast series called Coding Blocks (&lt;a href="https://www.codingblocks.net/" rel="noopener noreferrer"&gt;https://www.codingblocks.net/&lt;/a&gt;). It is a fun series to listen to for developers from juniors to seniors. And throughout the series, they have made some statements toward JAMstack, but the episode they published February 3, 2019 titled “JAMstack for J.A.M”. This episode inspired me to go into a deep dive of what JAMstack is and where I would used versus other technologies.&lt;/p&gt;

&lt;p&gt;Let’s go into defining what JAMstack is: &lt;/p&gt;

&lt;p&gt;JAMstack stands for JavaScript, APIs, and Markup. The term was coined by Mathias Biilmann to describe “a modern web development architecture based on client-side JavaScript, reusable APIs, and prebuilt Markup.” — from &lt;a href="https://www.contentful.com/r/knowledgebase/jamstack-cms/" rel="noopener noreferrer"&gt;https://www.contentful.com/r/knowledgebase/jamstack-cms/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sites that are similarly built with Jekyll, Hugo, Next and Gatsby, you may have already used, or at least seen sites built on JAMstack. The main selling point for using JAMstack is to host up static sites to the public. &lt;/p&gt;

&lt;p&gt;The JAM of JAMstack stands for JavaScript, API and Markup. Let’s break down what each represent in the stack:&lt;/p&gt;

&lt;p&gt;JavaScript&lt;/p&gt;

&lt;p&gt;Dynamic functionalities are handled by JavaScript. There is no restriction on which framework or library you must use&lt;/p&gt;

&lt;p&gt;APIs&lt;/p&gt;

&lt;p&gt;Server side operations are abstracted into reusable APIs and accessed over HTTPS with JavaScript. These can be third party services or your custom functions&lt;/p&gt;

&lt;p&gt;Markup&lt;/p&gt;

&lt;p&gt;Websites are served as static HTML files. These can be generated from source files, such as Markdown, using a static site generator.&lt;/p&gt;

&lt;p&gt;Well, what are the benefits? Why not use SPAs?&lt;/p&gt;

&lt;p&gt;A single page application (SPA) is a web application that loads a single static HTML page and dynamically hydrates it with new content on user interaction. In this very light definition of an SPA, seeing that it generally serves the user static pages with JS and APIs, they can be considered JAMstack, but should never be assumed to be JAMstack. The long and short of why you may choose JAMstack over SPA is for those wanting better control over SEO. SPAs fall short on SEO.&lt;/p&gt;

&lt;p&gt;Main benefits of JAMstack:&lt;/p&gt;

&lt;p&gt;Faster performance - serve pre built markup and assets over a CDN&lt;/p&gt;

&lt;p&gt;More secure - No need to worry about server or database vulnerabilities&lt;/p&gt;

&lt;p&gt;Less expensive - hosting static files for cheap or even free&lt;/p&gt;

&lt;p&gt;Better developer experience - frontend devs can focus solely on frontend&lt;/p&gt;

&lt;p&gt;Scalability -  If your product goes viral with many users, the CDN compensates&lt;/p&gt;

&lt;p&gt;Foundations of JAMstack&lt;/p&gt;

&lt;p&gt;JAMstack is a set of tools that can be used to build an ecosystem. There are three foundations that are more like conventions rather than a set of specific tools that you have to use to fit in the definition of the term JAMstack.&lt;/p&gt;

&lt;p&gt;JavaScript&lt;/p&gt;

&lt;p&gt;JS is the first foundation of the whole stack. You can love it or you can hate it but you have to admit that JavaScript is one of the most popular programming languages these days with an incredibly vibrant community. The request and response cycles are based on client side thanks to this technology. You can use either pure JavaScript or use any other framework or library available on the market such as React or Vue.&lt;/p&gt;

&lt;p&gt;API&lt;/p&gt;

&lt;p&gt;Though I did mention the static websites, the next foundation of the JAMstack are APIs. Thanks to it you can use backend functionality without having a database or the backend engine on your own server. You still have backend, yes,  but deploy only a static website. You can use any API you want, public or private. There are many third-part sites you can choose from. You can also connect to the other backend app that you have created.&lt;/p&gt;

&lt;p&gt;Markup&lt;/p&gt;

&lt;p&gt;The presentation layer of your website. With the JAMstack ecosystem usually, it’s a static site generator where templated markup is prebuilt at the build time. You can write your own HTML and CSS code or use a framework such as Hugo, Jekyll or Gatsby, which will greatly improve the time of template development.&lt;/p&gt;

&lt;p&gt;History of JAMstack&lt;/p&gt;

&lt;p&gt;It all started with the LAMP stack where LAMP stands for Linux Apache MySQL and PHP. The term refers to the tech stack where a website is running on a Linux server with the MySQL database and PHP programming language. You might hear about WAMP or MAMP which is the same but refers to Windows and Mac OS.&lt;/p&gt;

&lt;p&gt;This movement started in the late ’90s. Back then most of the websites on the Internet were running on MySQL and PHP. Before PHP there was just static HTML which allows building static websites. Since LAMP was coined, static websites were not cool for a long time. In 2016 a small group of developers established the term JAMstack and started to slowly promote it among other developers and the whole dev community.&lt;/p&gt;

&lt;p&gt;A year later, in 2017, the JAMstack community has grown and static websites became something more than just information pages where the content was changed only by editing page files and uploading them on the server. It was possible to build dynamic websites and apps. The new stack has hit the mainstream and it became very popular in a relatively short time.&lt;/p&gt;

&lt;p&gt;Benefits for the developer&lt;/p&gt;

&lt;p&gt;The biggest benefit for the developers using JAMstack is the saved time on every step of the development process. JAMstack provides a great developer experience since generating code is way faster than writing it from scratch. Also, the deployment process is easier because you don’t have to think about the database and other backend stuff, you just deploy a static website where most of the content is usually already present. Let’s have a look at how to build a website with JAMstack.&lt;/p&gt;

&lt;p&gt;Getting started with the JAMstack&lt;/p&gt;

&lt;p&gt;If you’re new to this whole idea of the JAMstack, you might be a little overwhelmed at this point. Knowing where to start is sometimes the hardest part.&lt;/p&gt;

&lt;p&gt;First, remember that we’re talking about frontend-centric development here. If you’re new to web development in general, you’ll want to make sure to sharpen your JavaScript skills. Then learning as much as you can about APIs will allow you to push your projects to the next level.&lt;/p&gt;

&lt;p&gt;Once you've got this covered, well, the sky’s the limit as they say—as long as you can find the tools to match your ambitions.&lt;/p&gt;

&lt;p&gt;New projects&lt;/p&gt;

&lt;p&gt;Starting from scratch is the best way to build a “pure” JAMstack. This way you can really choose all the necessary pieces to create what you want. As I explained earlier, building and hosting are decoupled. The first thing you’ll want to decide is what to use to build your site/app.&lt;/p&gt;

&lt;p&gt;The modern frontend ecosystem may make your life hard here. Not because of a lack of relevant tools. Actually, it’s just the opposite! There are hundreds of possibilities, even if some clearly stand out.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
