<?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: Stefan Nieuwenhuis</title>
    <description>The latest articles on DEV Community by Stefan Nieuwenhuis (@stefannieuwenhuis).</description>
    <link>https://dev.to/stefannieuwenhuis</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%2F296496%2Fc8be9804-6281-4632-8783-239914516694.jpeg</url>
      <title>DEV Community: Stefan Nieuwenhuis</title>
      <link>https://dev.to/stefannieuwenhuis</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/stefannieuwenhuis"/>
    <language>en</language>
    <item>
      <title>Gaussian Naive Bayes: Part 2 — Mathematical Deep Dive and Optimization</title>
      <dc:creator>Stefan Nieuwenhuis</dc:creator>
      <pubDate>Mon, 19 May 2025 00:00:00 +0000</pubDate>
      <link>https://dev.to/stefannieuwenhuis/gaussian-naive-bayes-part-2-mathematical-deep-dive-and-optimization-13m0</link>
      <guid>https://dev.to/stefannieuwenhuis/gaussian-naive-bayes-part-2-mathematical-deep-dive-and-optimization-13m0</guid>
      <description>&lt;h3&gt;
  
  
  Series: Gaussian Naive Bayes Classifier
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="///2025/05/15/math-behind-naive-bayes-part1.html"&gt;Gaussian Naive Bayes: Part 1 — Introduction and Bayes Theorem Refresher&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gaussian Naive Bayes: Part 2 — Mathematical Deep Dive and Optimization&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the second part of the series, we dive into the mathematics behind Gaussian Naive Bayes. We’ll derive the class-conditional probability density functions, explore why log-probabilities are used, and show how the entire prediction process can be transformed into a fast, vectorized dot-product computation. Along the way, we’ll clarify common assumptions—such as constant variance across classes—and examine their practical consequences.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Bayes to Naive Bayes
&lt;/h2&gt;

&lt;p&gt;Bayes’ Theorem offers a formal way of updating our beliefs given new evidence. However, applying it directly in real-world classification tasks often becomes computationally intractable, especially dealing with high-dimensional data where we want to &lt;strong&gt;estimate the joint probability distribution&lt;/strong&gt; (P(x_1, x_2, \dots,x_n\vert y)). It’s the &lt;a href="https://en.wikipedia.org/wiki/Combinatorial_explosion" rel="noopener noreferrer"&gt;combinatorial explosion problem&lt;/a&gt;, where the number of possible combinations of feature values grows exponentially with the number of features.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Quick Primer: Independent vs. Conditionally Independent Events
&lt;/h3&gt;

&lt;p&gt;Let’s break down the concepts of &lt;strong&gt;independence&lt;/strong&gt; and &lt;strong&gt;conditional independence&lt;/strong&gt; , as they’re crucial for understanding the &lt;em&gt;“naivety”&lt;/em&gt; in Naive Bayes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Independent events
&lt;/h4&gt;

&lt;p&gt;Two events, (A) and (B), are &lt;strong&gt;independent&lt;/strong&gt; if the occurrence of one has no effect on the probability of the other:&lt;/p&gt;

&lt;p&gt;[P(A\cap B)=P(A)\cdot P(B)]&lt;/p&gt;

&lt;p&gt;Or, equivalently:&lt;/p&gt;

&lt;p&gt;[P(A\vert B) = P(A)]&lt;/p&gt;

&lt;p&gt;, and&lt;/p&gt;

&lt;p&gt;[P(B\vert A) = P(B)]&lt;/p&gt;

&lt;h5&gt;
  
  
  Example: Tossing two fair coins; The result of the first toss doesn’t affect the second.
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkfjipgmstd3b0idadqi2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkfjipgmstd3b0idadqi2.jpg" alt="Quarter dollar head and tail" width="800" height="533"&gt;&lt;/a&gt;&lt;small&gt;Image by &lt;a href="https://www.greatamericancoincompany.com/cdn/shop/articles/front-and-back_a6e2bed8-21a7-4f3f-b765-7ddf3570a7d7.jpg?v=1736183719&amp;amp;width=1400" rel="noopener noreferrer"&gt;Great American Coin Co.&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;When&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(A={x\vert x = \text{first coin is heads}}), and&lt;/li&gt;
&lt;li&gt;(B={x\vert x = \text{second coin is heads}}),&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then&lt;/p&gt;

&lt;p&gt;[P(A\cap B)=P(A)\cdot P(B) = \frac{1}{2} \cdot \frac{1}{2} = \frac{1}{4}]&lt;/p&gt;

&lt;h4&gt;
  
  
  Conditional independent events
&lt;/h4&gt;

&lt;p&gt;Two events (A) and (B) are &lt;strong&gt;conditionally independent given a third event (C)&lt;/strong&gt; if, once we know (C) has occurred, learning about (A) gives us &lt;strong&gt;no additional information about (B)&lt;/strong&gt;, and vice-versa. In other words, once we know the &lt;em&gt;“cause”&lt;/em&gt;, the symptoms are treated as &lt;strong&gt;independent&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Formally:&lt;/p&gt;

&lt;p&gt;[P(A\cap B\vert C)=P(A\vert C)\cdot P(B\vert C)]&lt;/p&gt;

&lt;p&gt;Or, equivalently:&lt;/p&gt;

&lt;p&gt;[P(A\vert B, C)=P(A\vert C)]&lt;/p&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;p&gt;[P(B\vert A, C)=P(B\vert C)]&lt;/p&gt;

&lt;h5&gt;
  
  
  Example: Spam Email classifier
&lt;/h5&gt;

&lt;p&gt;Let’s say we’re building a spam email classifier, where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(C): Email is &lt;code&gt;spam&lt;/code&gt; or &lt;code&gt;not spam&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;(A): Email contains the word &lt;em&gt;“Viagra”&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;(B): Email contains the words &lt;em&gt;“Money-back guarantee”&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In general, the presence of the words &lt;em&gt;“Viagra”&lt;/em&gt;, and &lt;em&gt;“Money-back guarantee”&lt;/em&gt; might be correlated, since spammy phrases often appear together. Knowing the presence of (A) might increase the likelihood of (B). This means that both events are &lt;em&gt;dependent&lt;/em&gt; in isolation.&lt;/p&gt;

&lt;p&gt;But here’s the key. Once we conditioned on (C) (email is &lt;code&gt;spam&lt;/code&gt;), the presence of (A) no longer gives us new infromation on the likelihood of (B). Why? Both events are already explained by the fact the email is spam. The common cause (C) makes the co-occurrence of the symptoms more likely.&lt;/p&gt;

&lt;p&gt;In other words,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Once we know that an email is spam, it does not matter wheter (A) and (B) often appear together in general. The only relevant question is how likely each word appears in spam emails?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So (A) and (B) become conditionally independent given (C). This is the &lt;strong&gt;Naive Bayes assumption&lt;/strong&gt; in action. It’s what allows the model to break down complex joint probabilities into simpler, individual conditional probabilities (one per feature).&lt;/p&gt;

&lt;h2&gt;
  
  
  The “Naive” assumption
&lt;/h2&gt;

&lt;p&gt;Now that we understand how Bayes’ Theorem updates our beliefs given evidence, we face a practical question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How do we estimate (P(e\vert H)) when (e) is a high-dimensional feature vector?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Given the hypothesis (H), and dependent feature (or evidence) vector (\vec{e} = \begin{bmatrix}e_1 &amp;amp; \dots &amp;amp; e_n\end{bmatrix}), Bayes’ Theorem states:&lt;/p&gt;

&lt;p&gt;[P(H\vert e_1 \cap e_2 \cap \dots\cap e_n) = \frac{(e_1 \cap e_2 \cap \dots\cap e_n \vert H)\cdot P(H)}{P(e_1 \cap e_2 \cap \dots\cap e_n)}]&lt;/p&gt;

&lt;p&gt;In high-dimensional spaces, modelling this full joint probability distribution (P(e_1 \cap e_2 \cap \dots\cap e_n\vert H)) becomes often computationally intractable, especially with limited training data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is it hard?
&lt;/h3&gt;

&lt;p&gt;The number of parameters required to model a joint distribution grows &lt;strong&gt;exponentially&lt;/strong&gt; with the number of features in a dataset. For example, suppose we wanted to model dependencies between just 100 binary features conditioned on a class label. This would require estimating probabilities for (2^{100}) possible feature combinations per class - an astronomically large number (&lt;small&gt;(1,2676506002×10^{30})&lt;/small&gt;). Even for continuous features, estimating a full, multivariate distribution requires computing high-dimensional covariance matrices, and ensuring they are invertible and well-conditioned. These tasks are computationally expensive and statistically fragile unless we have massive datasets.&lt;/p&gt;

&lt;p&gt;This is known as the &lt;a href="https://www.datacamp.com/blog/curse-of-dimensionality-machine-learning" rel="noopener noreferrer"&gt;curse of dimensionality&lt;/a&gt;: as the number of dimensions (features) increases, the amount of data required to reliably estimate densities increases exponentially. In practice, we rarely have enough data to estimate these complex joint distributions without overfitting or introducting heavy regularization.&lt;/p&gt;

&lt;h3&gt;
  
  
  The “naive” simplification
&lt;/h3&gt;

&lt;p&gt;The “naive” assumption circumvents this by treating each feature as conditionally independent given the class label:&lt;/p&gt;

&lt;p&gt;[P(e_i\vert H\cap e_1\cap\dots\cap e_{i-1}\cap e_{i+1}\cap\dots\cap e_n) = P(e_i\vert H)]&lt;/p&gt;

&lt;p&gt;, and for all (i) this relation is simplified to:&lt;/p&gt;

&lt;p&gt;[P(H\vert e_1\cap\dots\cap e_n) = \frac{P(H)\cdot\prod\limits_{i=1}^n P(e_i | H)}{P(e_1\cap\dots\cap e_n)}]&lt;/p&gt;

&lt;p&gt;The denominator normalizes the nominator, and &lt;strong&gt;integrates over all possible class labels&lt;/strong&gt; , since it does not depend on (H) to be computed - i.e. it doesn’t affect which class has the highest probability. So we can rewrite the classification rule using just the numerator:&lt;/p&gt;

&lt;p&gt;[P(H\vert e_1\cap\dots\cap e_n) \varpropto P(H)\cdot\prod\limits_{i=1}^n P(e_i | H)]&lt;/p&gt;

&lt;p&gt;, and we can use (\arg \max) to find the class that &lt;strong&gt;gives the highest posterior probability&lt;/strong&gt; for feature vector (\vec{x}):&lt;/p&gt;

&lt;p&gt;[\hat{y}=\arg \max_{y} P(y)\cdot\prod\limits_{i=1}^n P(x_i | y)]&lt;/p&gt;

&lt;p&gt;Estimating the posterior probabilities from training data is done via &lt;strong&gt;Maximum A Posteriori (MAP) estimation&lt;/strong&gt;. (P(y)) is estimated as the relative frequency of class (y) in the training set, and each (P(x_i\vert y)) is estimated based on feature distributions in each class.&lt;/p&gt;

&lt;p&gt;Under the hood, it computes (P(y)\cdot\prod\limits_{i=1}^n P(x_i \vert y)) for every class (y), and normalizes the results so they sum to (1).&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does it work?
&lt;/h3&gt;

&lt;p&gt;Naive Bayes often performs surprisingly well in practice, despite its unrealistic independence assumptions. This is because accurate probability estimates are not always required for good classification. What matters is that the decision boundary induced by comparing class scores remains useful. Even when the probabilities themselves are not well calibrated. As long as the incorrect independence assumption does not lead to systematically biased scores, the final predictions can still be highly effective.&lt;/p&gt;

&lt;p&gt;This is why Naive Bayes is often described as&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“wrong, but useful” - A pragmatic trade-off between statistical realism and computational simplicity.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We have to be &lt;strong&gt;cautious with correlations between features&lt;/strong&gt; though, since it breaks down our feature independence assumption, and the model exaggerates or underrepresents the true likelihood, and performance degrades.&lt;/p&gt;

&lt;p&gt;The naive assumption oversimplifies reality. In most real-world datasets, features are not truly independent. However, the simplification offers practical benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tractability&lt;/strong&gt; : We only have to estimate one univariate distribution per feature per class.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sample efficiency&lt;/strong&gt; : We need far fewer samples to get reliable estimates of the probability distributions for each class.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speed&lt;/strong&gt; : The classifier becomes fast to train and evaluate.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  From assumptions to implementations: Handling continuous features
&lt;/h2&gt;

&lt;p&gt;At the heart of Naive Bayes thus lies a simplifying assumption: All features are conditionally independent given the class label, but in order to &lt;strong&gt;compute&lt;/strong&gt; the individual terms (P(x_i \vert y)), we have to make assumptions about each features’ distribution. This is where we can use different Naive Bayes variants. The assumptions remain the same, but the difference is the way the individual probabilities for each (x_i) is computed.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if (x_i) is &lt;strong&gt;categorical&lt;/strong&gt; , we use &lt;strong&gt;frequency counts&lt;/strong&gt; (Multinominal or Bernoulli NB).&lt;/li&gt;
&lt;li&gt;if (x_i) is &lt;strong&gt;continuous&lt;/strong&gt; , we cannot count how often each exact value occurs, since real-valued features are rarely repeated exactly, and this problem grows when the precision (e.g. measurement) increases.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The latter leads us to a natural solution: &lt;strong&gt;Assume a probability distribution over the feature values&lt;/strong&gt;. Enter the Gaussian Naive Bayes classifier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gaussian Naive Bayes Classifier
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fahvz23vg1hmo7dwkrz1b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fahvz23vg1hmo7dwkrz1b.png" alt="Gaussian or Normal distribution plot" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Image by &lt;a href="https://learninglab.rmit.edu.au/maths-statistics/statistics/s10-standard-normal-distribution" rel="noopener noreferrer"&gt;RMIT University&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;The Gaussian distribution is a natural choice, since:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Central Limit Theorem since many features tend to be approximately normal.&lt;/li&gt;
&lt;li&gt;Simplicity: A normal distribution is described with only the &lt;strong&gt;mean&lt;/strong&gt; and &lt;strong&gt;variance&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Mathematical convenience (e.g. closed-form likelihood, stability under transformations, computationally cheap)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is defined for a &lt;strong&gt;continuous variable (x)&lt;/strong&gt; with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mean (\mu)&lt;/strong&gt;: The center of the distribution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Variance (\sigma^2)&lt;/strong&gt;: The spread of the data - i.e. distance from the mean&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Probability density function (PDF)
&lt;/h4&gt;

&lt;p&gt;We can use the &lt;strong&gt;probability density function (PDF)&lt;/strong&gt; to compute the probability of (x) comes from a Gaussian distribution with a given (\mu), and (\sigma^2):&lt;/p&gt;

&lt;p&gt;[P(x_i\vert y) = \frac{1}{\sqrt{2\pi\sigma_{ic}^2}}\cdot\exp(-\frac{(x_i - \mu_{ic})^2}{2\sigma_{ic}^2})]&lt;/p&gt;

&lt;h4&gt;
  
  
  First term: the normalization constant
&lt;/h4&gt;

&lt;p&gt;[\frac{1}{\sqrt{2\pi\sigma_{ic}^2}}]&lt;/p&gt;

&lt;p&gt;In probability theory, a &lt;strong&gt;PDF&lt;/strong&gt; describes how likely a continuous random variable is to take on a value in a given range, but, unlike discrete probabilities, where probabilities like (P(x=3)) are directly meaningful, continuous variables don’t work that way.&lt;/p&gt;

&lt;p&gt;Instead, the probability that a continuous variable fall within a range ([a,b]) is given by &lt;strong&gt;the area under the curve of the PDF between (a) and (b)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;[P(a \leq x \leq b) = \int_{b}^{a}f(x)dx]&lt;/p&gt;

&lt;p&gt;To be a valid PDF, it must satisfy one crucial condition:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;strong&gt;total area under the curve&lt;/strong&gt; across the entire real number line must equal 1.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is&lt;/p&gt;

&lt;p&gt;[\int_{\infty}^{-\infty}f(x)dx=1]&lt;/p&gt;

&lt;p&gt;This renders the distribution &lt;strong&gt;properly normalized&lt;/strong&gt; over all real numbers.&lt;/p&gt;

&lt;h4&gt;
  
  
  Second term: exponential decay
&lt;/h4&gt;

&lt;p&gt;[\exp(-\frac{(x_i - \mu_{ic})^2}{2\sigma_{ic}^2})]&lt;/p&gt;

&lt;p&gt;The exponential term controls &lt;strong&gt;the shape of the bell curve&lt;/strong&gt; - i.e. the kurtosis (how &lt;em&gt;“tall”&lt;/em&gt; or &lt;em&gt;“flat”&lt;/em&gt; is the distribution around (\mu)?). It is called &lt;strong&gt;exponential decay&lt;/strong&gt; , since, as (x) moves away from (\mu), this term &lt;strong&gt;rapidly decreases toward zero&lt;/strong&gt;.&lt;/p&gt;

&lt;h5&gt;
  
  
  Decoding the terms
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;((x - \mu)): Measures the distance of (x) from (\mu)&lt;/li&gt;
&lt;li&gt;((x - \mu)^2): (squared distance): Ensures this value is always positive, and the larger the distance, the larger the value becomes.&lt;/li&gt;
&lt;li&gt;((2\sigma^2)): Scales the squared distance. The larger (\sigma), the more &lt;em&gt;“forgiving”&lt;/em&gt; the distribution is of being far from the mean.&lt;/li&gt;
&lt;li&gt;(-\frac{(x_i - \mu_{ic})^2}{2\sigma_{ic}^2}) (negative sign): This makes the exponent negative, so as the distance increases, the exponent &lt;strong&gt;decays&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;(\exp): Converts the scaled squared distance into a value between 0 and 1 - i.e. a probability estimate.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The expontential decay models the likelihood (x) appears in a Gaussian-distributed class (y).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When (x) is &lt;strong&gt;close to the class mean&lt;/strong&gt; , the exponent is near 0 - i.e. high probability&lt;/li&gt;
&lt;li&gt;When (x) is &lt;strong&gt;far from the class mean&lt;/strong&gt; , the exponent becomes strongly negative - i.e. probability shrinks toward 0.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes the model &lt;strong&gt;sensitive to deviations from the class-specific mean&lt;/strong&gt; , which is what allows Gaussian Naive Bayes to perform classification based on how well a value fits into the distribution learned for each class.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mathematical Optimizations in Gaussian Naive Bayes
&lt;/h2&gt;

&lt;p&gt;When implementing Gaussian Naive Bayes, several mathematical optimizations are employed to &lt;strong&gt;improve both numerical stability and computational efficiency&lt;/strong&gt;. The underlying probability theory remains unchanged but the optimizations make the model more robust and scalable (with high-dimensional or sparse data in particular).&lt;/p&gt;

&lt;h3&gt;
  
  
  Use log probabilities instead of raw probabilities
&lt;/h3&gt;

&lt;p&gt;In the prediction phase, we compute the product of conditional likelihoods&lt;/p&gt;

&lt;p&gt;[P(y=c\vert x)\varpropto P(y=c)\prod\limits_{i=1}^n P(x_i | y=c)]&lt;/p&gt;

&lt;p&gt;However, multiplying many small probabilities can quickly lead to &lt;a href="https://en.wikipedia.org/wiki/Arithmetic_underflow" rel="noopener noreferrer"&gt;numerical underflow&lt;/a&gt;, where the product becomes so small that it rounds to zero in floating-point representation. It becomes a number of more precise absolute value than the computer can actually represent in memory on its central processing unit (CPU).&lt;/p&gt;

&lt;h4&gt;
  
  
  Optimization
&lt;/h4&gt;

&lt;p&gt;Apply the natural &lt;a href="///2025/05/14/logarithms-beginners-guide.html"&gt;logarithm&lt;/a&gt; to the entire expression. Since the logarithm is a monotonically increasing function, maximizing the log of the probabilities yields the same result as maximizing the original product:&lt;/p&gt;

&lt;p&gt;[\hat{y}=\arg \max_{c} \biggl( \log P(y=c)+\sum\limits_{i=1}^n \log P(x_i | y=c)\biggl)]&lt;/p&gt;

&lt;p&gt;This transformation avoids numerical underflow and ensures robust computation.&lt;/p&gt;

&lt;p&gt;But log-space transformations are not just about numerical safety, they also improve &lt;strong&gt;computational efficiency&lt;/strong&gt; , particularly in the context of large-scale or high-dimensional data.&lt;/p&gt;

&lt;p&gt;The primary benefit comes from the mathematical identity&lt;/p&gt;

&lt;p&gt;[log(a\cdot b) = log(a) + log(b)]&lt;/p&gt;

&lt;p&gt;Multiplying many identities - i.e. one for each feature variable - can be computationally expensive and slow. By converting the product into a sum of logarithms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We &lt;strong&gt;reduce the number of operations&lt;/strong&gt; from (O(n)) multiplications to (O(n)) additions. Although modern CPU architectures mitigate the effects, addition is still faster, and less complex than multiplication ((O(n)) vs. (O(n \log n)) time complexity).&lt;/li&gt;
&lt;li&gt;Additions are &lt;strong&gt;faster and more stable&lt;/strong&gt; than floating-point multiplications, especially on hardware like GPUs or vectorized CPUs where addition is heavily optimized. It also limits parallelism, since each multiplication depends on the previous result.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use vectorization via dot-product form
&lt;/h3&gt;

&lt;p&gt;Terms can be re-arranged to fit the structure of a dot-product by transforming the log-likelihood of a Gaussion PDF into an algebraic form. This allows for efficient batch computation, since modern hardware architectures are highly optimized for such calculations.&lt;/p&gt;

&lt;p&gt;Recall the log of a Gaussian PDF&lt;/p&gt;

&lt;p&gt;[log P(x_i \vert y=c) = -\frac{1}{2}log(2\pi\sigma_{ic}^2)-\frac{(x_i - \mu_{ic})^2}{2\sigma_{ic}^2}]&lt;/p&gt;

&lt;p&gt;The total log-probability can be broken down into a &lt;strong&gt;sum of constants&lt;/strong&gt; , &lt;strong&gt;quadratic terms&lt;/strong&gt; , and a &lt;strong&gt;linear dot-product&lt;/strong&gt; between input and model parameters. The class score is represented as&lt;/p&gt;

&lt;p&gt;[log P(y=c \vert x) = log P(y=c)+x+w_c+\text{const}_c]&lt;/p&gt;

&lt;p&gt;Where&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(w_c=\biggl(\frac{\mu_{ic}}{\sigma_{ic}^2}\biggl)),&lt;/li&gt;
&lt;li&gt;The offset (\text{const}_c=-\sum\limits_i\biggl(\frac{\mu_{ic}^2}{2\sigma_{ic}^2}+\frac{1}{2}log(2\pi\sigma_{ic}^2)\biggl))&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This transforms inference into a &lt;strong&gt;single dot-product plus offset per class&lt;/strong&gt; , which allows for &lt;strong&gt;fast batch prediction&lt;/strong&gt; with matrix multiplication ((X\cdot\mathbf{\theta}^\top+b)), and allows the constants to be &lt;strong&gt;cached&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If speed is what you’re after, we can assume equal variance (\sigma_{ic}^2 = \sigma_{c}^2) or (\sigma_{ic}^2 = \sigma^2) so that the &lt;strong&gt;quadratic term&lt;/strong&gt; cancels out in the equation, and the remaining term becomes linear. This is a trade-off between speed and accuracy, and A/B testing is required to objecticvely compare solutions, and pick the best fitting model for a use-case.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Epsilon Variance Smoothing
&lt;/h3&gt;

&lt;p&gt;The Gaussian PDF breaks down if the estimated variance (\sigma_{ic}^2=0), which can happen when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A feature has &lt;strong&gt;zero variance&lt;/strong&gt; in a class (e.g. same value across all training samples of a class).&lt;/li&gt;
&lt;li&gt;A feature has &lt;strong&gt;very low variance&lt;/strong&gt; making the denominator in the exponent extremely small, leading to numerical instability or &lt;a href="https://www.machinelearningmastery.com/exploding-gradients-in-neural-networks/" rel="noopener noreferrer"&gt;exploding gradients&lt;/a&gt; in probabilistic computations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To guard against these issues, a &lt;strong&gt;small constant (\epsilon) is added&lt;/strong&gt; to the variance during computation&lt;/p&gt;

&lt;p&gt;[\tilde{\sigma}_{ic}^2=\sigma_{ic}^2+\epsilon]&lt;/p&gt;

&lt;p&gt;This technique is called &lt;strong&gt;variance smoothing&lt;/strong&gt; , and (\epsilon) is typically on the order of (10^{-9}) to (10^{-5}), depending on the scale of the data. By preventing division by zero and avoiding extremely large exponentials, it guarantees well-behaved computation even for pathological features or small training sets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Gaussian Naive Bayes might seem simple at first glance, but beneath its straight-forward assumptions lies a wealth of mathematical elegance and engineering nuance. By diving deep into the underlying mathematics, we’ve seen how classical probability theory, numerical stability optimizations, and linear algebra come together to create an inference engine that’s both fast and effective.&lt;/p&gt;

&lt;p&gt;Transforming probability products into log-space not only prevents numerical underflow but unlocks powerful computational optimizations: it turns costly multiplications into efficient additions and enables vectorized inference via dot-product formulations. Smoothing tiny variances with epsilon avoids pathological cases where the model becomes overly confident or completely unstable. And through visualizing decision boundaries, we get a tangible sense of how these mathematical choices shape model behavior.&lt;/p&gt;

&lt;p&gt;Ultimately, these optimizations aren’t just about speed or safety — they reflect a mature understanding of how theoretical models meet the real-world imperfections of data and hardware. Whether you’re building a scalable classifier or exploring probabilistic reasoning, mastering these principles ensures your models are not only correct, but robust, interpretable, and production-ready.&lt;/p&gt;

&lt;p&gt;In the next and final part, we’ll implement these ideas in Python, visualize decision boundaries, and compare theoretical insights with empirical results.&lt;/p&gt;

</description>
      <category>gaussiannaivebayes</category>
      <category>probability</category>
      <category>machinelearning</category>
      <category>linearalgebra</category>
    </item>
    <item>
      <title>Gaussian Naive Bayes: Part 1 — Introduction and Bayes Theorem Refresher</title>
      <dc:creator>Stefan Nieuwenhuis</dc:creator>
      <pubDate>Thu, 15 May 2025 00:00:00 +0000</pubDate>
      <link>https://dev.to/stefannieuwenhuis/gaussian-naive-bayes-part-1-introduction-and-bayes-theorem-refresher-4jhg</link>
      <guid>https://dev.to/stefannieuwenhuis/gaussian-naive-bayes-part-1-introduction-and-bayes-theorem-refresher-4jhg</guid>
      <description>&lt;h3&gt;
  
  
  Series: Gaussian Naive Bayes Classifier
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Gaussian Naive Bayes: Part 1 — Introduction and Bayes Theorem Refresher&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="///2025/05/19/math-behind-naive-bayes-part2.html"&gt;Gaussian Naive Bayes: Part 2 — Mathematical Deep Dive and Optimization&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the first part of a multi-part series on Gaussian Naive Bayes, a simple yet surprisingly effective probabilistic classifier. In this post, we’ll explore the foundational concepts behind Bayes’ Theorem and how they apply to machine learning. We’ll also introduce the Naive Bayes assumption, setting the stage for a deeper mathematical dive in the next post.&lt;/p&gt;

&lt;p&gt;In the ever-growing landscape of machine learning algorithms, Naive Bayes stands out due to its elegant probabilistic foundation and surprising effectiveness in various practical applications, especially in text classification and medical diagnosis. Gaussian Naive Bayes, in particular, is a variant tailored for continuous data, assuming a Gaussian distribution for each feature conditioned on the class.&lt;/p&gt;

&lt;p&gt;As part of revisiting foundational concepts in probability and statistics—especially Bayes’ Theorem—I built a machine learning project that implements classifiers from scratch to classify &lt;a href="https://rcs.chemometrics.ru/Tutorials/classification/Fisher.pdf" rel="noopener noreferrer"&gt;Iris flower species&lt;/a&gt;. The first model I implemented was a &lt;a href="https://github.com/StefanNieuwenhuis/iris_species_classifier/blob/80686c92ae6166583bd5f3f7b2c355a139e530f4/src/model/gaussian_naive_bayes.py" rel="noopener noreferrer"&gt;Gaussian Naive Bayes classifier&lt;/a&gt;, which served as both a mathematical refresher and a practical coding exercise.&lt;/p&gt;

&lt;p&gt;This blog post is a deep mathematical dive into the Gaussian Naive Bayes classifier. We will go beyond the intuition and dissect the mathematical components that underpin it. &lt;strong&gt;This post focuses solely on the mathematics behind Gaussian Naive Bayes—not on implementation or model building&lt;/strong&gt;. That will be covered in a dedicated follow-up post.&lt;/p&gt;

&lt;p&gt;Whether you’re an aspiring data scientist, machine learning engineer, or a curious student, this guide aims to offer clarity and precision in understanding the mathematical machinery that drives Gaussian Naive Bayes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Iris Flower Species dataset
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frhumsh0jy9h41x4etgm7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frhumsh0jy9h41x4etgm7.png" alt="Iris Flower Species With Labels" width="800" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Iris flower data set or Fisher’s Iris data set is a multivariate data set used and made famous by the British statistician and biologist Ronald Fisher in his 1936 paper The use of multiple measurements in taxonomic problems as an example of linear discriminant analysis.&lt;/p&gt;

&lt;p&gt;The data set consists of 50 samples from each of three species of Iris (Iris setosa, Iris virginica and Iris versicolor). Four features were measured from each sample: the length and the width of the sepals and petals, in centimeters.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;– Source: &lt;a href="https://en.wikipedia.org/wiki/Iris_flower_data_set" rel="noopener noreferrer"&gt;Wikipedia: Iris Flower Data Set&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Bayes’ Theorem Refresher
&lt;/h2&gt;

&lt;p&gt;Bayes’ Theorem provides a formal method - i.e. mathematical rule for updating probabilities based on new evidence. In other words, with Bayes’ Theorem we can compute how much to revise our probabilities (change our minds) when we learn a new fact or observe new evidence.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fubkdmy5a4gov77ki7uej.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fubkdmy5a4gov77ki7uej.png" alt="Bayes' Theorem formula" width="800" height="487"&gt;&lt;/a&gt;&amp;lt;!-- $$P(H\;\vert\;e) = \frac{P(e\;\vert\;H)\cdot P(H)}{P(e)} \tag{1}$$ --&amp;gt;&lt;/p&gt;

&lt;p&gt;In classification terms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(P(H\vert E)): &lt;strong&gt;Posterior&lt;/strong&gt; - probability of (H) (hypothesis) given (e) (the evidence) is true&lt;/li&gt;
&lt;li&gt;(P(H)): &lt;strong&gt;Prior&lt;/strong&gt; - initial belief about (H) before seeing (e)&lt;/li&gt;
&lt;li&gt;(P(e\vert H)): &lt;strong&gt;Likelihood&lt;/strong&gt; - probability of observing (e) given that (H) is true&lt;/li&gt;
&lt;li&gt;(P(e)): &lt;strong&gt;Marginal probability&lt;/strong&gt; (or evidence) - overall probability of observing (e)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When, for example, a certain Iris Flower species is known to have larger petals, Bayes’ theorem allows a sample to be assessed more accurately by conditioning it relative to its petal size, rather than assuming the sample is typical of the population as a whole. In other words, we reduce the total number of possibilities to make the propability estimates more likely.&lt;/p&gt;

&lt;h3&gt;
  
  
  It is all about information
&lt;/h3&gt;

&lt;p&gt;Bayes’ Theorem is, at its core, a tool for updating beliefs in light of new information. It provides a formal definition how evidence should impact our confidence in different hypothesis. The prior, (P(H)), is our belief before seeing any data. The likelihood, (P(e\vert H)), captures how likely the observed data is under each hypothesis, and combining both terms results in the posterior, (P(H\vert e)), our updated belief after seeing the evidence.&lt;/p&gt;

&lt;p&gt;Bayes’ Theorem is thus about &lt;strong&gt;information flow&lt;/strong&gt; : How new data reshapes our expectations and refines our understanding of the world in a formal, structured way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: Monty Hall Problem
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcux0ln65xfeksrtc8exk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcux0ln65xfeksrtc8exk.png" alt="Monty Hall Problem - Open door" width="800" height="444"&gt;&lt;/a&gt;&lt;small&gt;Image by &lt;a href="https://commons.wikimedia.org/w/index.php?curid=1234194" rel="noopener noreferrer"&gt;Cepheus&lt;/a&gt; - Own work, Public Domain&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;The Monty Hall problem is a brain teaser, in the form of a probability puzzle, based nominally on the American television game show Let’s Make a Deal and named after its original host, Monty Hall. The problem was originally posed (and solved) in a letter by Steve Selvin to the American Statistician in 1975 It became famous as a question from reader Craig F. Whitaker’s letter quoted in Marilyn vos Savant’s &lt;em&gt;“Ask Marilyn”&lt;/em&gt; column in Parade magazine in 1990:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Suppose you’re on a game show, and you’re given the choice of three doors: Behind one door is a car; behind the others, goats. You pick a door, say No. 1, and the host, who knows what’s behind the doors, opens another door, say No. 3, which has a goat. He then says to you, “Do you want to pick door No. 2?” Is it to your advantage to switch your choice?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Savant’s response was that the contestant should switch to the other door. By the standard assumptions, the switching strategy has a ⁠ (\frac{2}{3}) probability of winning the car, while the strategy of keeping the initial choice has only a ⁠(\frac{1}{3}) probability.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;– Source: &lt;a href="https://en.wikipedia.org/wiki/Monty_Hall_problem" rel="noopener noreferrer"&gt;Wikipedia: Monty Hall Problem&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  To switch or not to switch? Bayes to the rescue!
&lt;/h4&gt;

&lt;p&gt;Bayes’ Theorem helps clarify why &lt;strong&gt;switching increases your odds&lt;/strong&gt;.&lt;/p&gt;

&lt;h5&gt;
  
  
  Step 1: Define the hypotheses
&lt;/h5&gt;

&lt;p&gt;Since each door is equally likely to contain the car &lt;strong&gt;before Monty opens any&lt;/strong&gt; , &lt;a href="https://en.wikipedia.org/wiki/Classical_definition_of_probability#:~:text=The%20probability%20of%20an%20event%20is%20the%20ratio%20of%20the%20number%20of%20cases%20favorable%20to%20it%2C%20to%20the%20number%20of%20all%20cases%20possible%20when%20nothing%20leads%20us%20to%20expect%20that%20any%20one%20of%20these%20cases%20should%20occur%20more%20than%20any%20other%2C%20which%20renders%20them%2C%20for%20us%2C%20equally%20possible." rel="noopener noreferrer"&gt;LaPlace definition of probabilty&lt;/a&gt; applies.&lt;/p&gt;

&lt;p&gt;[H_1=H_2=H_3=\frac{n_{favorable}}{n_{total}}=\frac{1}{3}]&lt;/p&gt;

&lt;p&gt;We can also define our priors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(H_1): The car is behind door No. 1 (our original choice)&lt;/li&gt;
&lt;li&gt;(H_2): The car is behind door No. 2 (we’d win if we switch)&lt;/li&gt;
&lt;li&gt;(H_3): The car is behind door No. 3 (ruled out since Monty just revealed a goat behind this door)&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Step 2: Use the evidence
&lt;/h5&gt;

&lt;p&gt;Let’s denote the evidence, (e), as: “Monty opens door No. 3, revealing a goat”.&lt;/p&gt;

&lt;p&gt;Next, we want to compute the &lt;strong&gt;posterior probabilities&lt;/strong&gt; (P(H_1\vert e)), and (P(H_2\vert e)) - i.e. what is the probability the car is behind door No. 1 or No. 2 given that Monty revealed a goat behind door No. 3?&lt;/p&gt;

&lt;p&gt;Applying Bayes’ Theorem:&lt;/p&gt;

&lt;p&gt;(P(H_k\;\vert\;e) = \frac{P(e\;\vert\;H_k)\cdot P(H_k)}{P(e)}), where (k \in {1,2,3}).&lt;/p&gt;

&lt;p&gt;And compute the likelihoods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the car is behind door No. 1, (H_1), Monty could randomly choose door No. 2 or 3. (\Rightarrow P(e\vert H_1)=\frac{1}{2}).&lt;/li&gt;
&lt;li&gt;If the car is behind door No. 2, (H_2), Monty could only pick door No. 3, since we picked the first already (\Rightarrow P(e\vert H_2)=1).&lt;/li&gt;
&lt;li&gt;If the car is behind door No. 3, (H_3), Monty could not open the door, since it reveals the car (\Rightarrow P(e\vert H_3)=0)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the likelihoods computed, we now move forward to calculate the marginal probability, (P(E)), or normalization constant.&lt;/p&gt;

&lt;p&gt;[P(E) = P(e\vert H_1)P(H_1)+P(e\vert H_2)P(H_2)+P(e\vert H_3)P(H_3)] [\Rightarrow (\frac{1}{2}\cdot\frac{1}{3})+(1\cdot\frac{1}{3})+(0\cdot\frac{1}{3})] [=\frac{1}{6}+\frac{1}{3}=\frac{3}{6}=\frac{1}{2}]&lt;/p&gt;

&lt;p&gt;Finally, we compute posteriors for hypothesis 1&lt;/p&gt;

&lt;p&gt;[P(H_1\vert e) =\frac{P(e\vert H_1)P(H_1)}{P(e)}] [\Rightarrow \frac{\frac{1}{2}\cdot\frac{1}{3}}{\frac{1}{2}}=\frac{\frac{1}{6}}{\frac{1}{2}}=\frac{1}{3}]&lt;/p&gt;

&lt;p&gt;And hypothesis 2&lt;/p&gt;

&lt;p&gt;[P(H_2\vert e) =\frac{P(e\vert H_2)P(H_2)}{P(e)}] [\Rightarrow \frac{1\cdot\frac{1}{3}}{\frac{1}{2}}=\frac{\frac{1}{3}}{\frac{1}{2}}=\frac{2}{3}]&lt;/p&gt;

&lt;p&gt;Switching gives you a (\frac{2}{3}) chance of winning the car, while staying with your initial pick gives you only a (\frac{1}{3}) chance, so we switch.&lt;/p&gt;

&lt;p&gt;The Monty Hall Problem demonstrates how Bayesian updating works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with prior beliefs&lt;/li&gt;
&lt;li&gt;Incorporate new evidence&lt;/li&gt;
&lt;li&gt;Normalize and update beliefs accordingly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also challenges our intuition and why probabilistic reasoning is essential in making better decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We’ve seen how Bayes’ Theorem provides a probabilistic framework for classification and how the &lt;em&gt;“naive”&lt;/em&gt;” assumption simplifies modeling joint distributions. In &lt;a href="///2025/05/19/math-behind-naive-bayes-part2.html"&gt;Part 2&lt;/a&gt;, we’ll dive deeper into the mathematical formulation of Gaussian Naive Bayes, including how log-probabilities, vectorization, and variance assumptions impact efficiency and accuracy.&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>bayestheorem</category>
      <category>naivebayes</category>
      <category>probability</category>
    </item>
    <item>
      <title>What is a Logarithm? A Complete Beginner’s Guide</title>
      <dc:creator>Stefan Nieuwenhuis</dc:creator>
      <pubDate>Wed, 14 May 2025 00:00:00 +0000</pubDate>
      <link>https://dev.to/stefannieuwenhuis/what-is-a-logarithm-a-complete-beginners-guide-556a</link>
      <guid>https://dev.to/stefannieuwenhuis/what-is-a-logarithm-a-complete-beginners-guide-556a</guid>
      <description>&lt;p&gt;If you’ve ever asked yourself, &lt;em&gt;“What is a logarithm, and why should I care?”&lt;/em&gt; —you’re in the right place. Whether you’re a student, aspiring data scientist, or just curious about the math behind modern technology, this blog post will give you a solid understanding of logarithms.&lt;/p&gt;

&lt;p&gt;I’ve recently been revisiting my knowledge of statistics and probability, including foundational concepts like Bayes’ Theorem. In the process, I built a machine learning project where I implement different classifiers from scratch to classify &lt;a href="https://rcs.chemometrics.ru/Tutorials/classification/Fisher.pdf" rel="noopener noreferrer"&gt;Iris Flower Species&lt;/a&gt;. The first one was a Gaussian Naive Bayes classifier. While implementing it, I ran into several mathematical optimizations that piqued my curiosity, especially the use of log transforms for numerical stability and computational efficiency. That journey is what led me to write this post.&lt;/p&gt;

&lt;p&gt;This isn’t just a basic introduction—we’ll break everything down from first principles, explaining not just what logarithms are, but why they work, how they’re used, and how they tie into real-world applications like machine learning and data science.&lt;/p&gt;

&lt;p&gt;Let’s start at the very beginning.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a logarithm?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;logarithm&lt;/strong&gt; is a mathematical tool to answer this question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“To what power must I raise a number to get another number?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words, how many times do I have to multiply a number by itself to get another number?&lt;/p&gt;

&lt;p&gt;Like subtraction is the opposite of summation, a logarithm is the &lt;strong&gt;inverse&lt;/strong&gt; of exponentiation. If exponentiation is&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;102=10010^2 = 100&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;Then the logarithmic version is&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log⁡10(100)=2\log_{10}(100) = 2&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Intuition&lt;/strong&gt; : “I have to multiply 10 twice to get 100.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Breaking it down
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fja6kqprfarb16amh94a1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fja6kqprfarb16amh94a1.png" alt="Exponents versus Logarithms"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;Here, 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log⁡\log&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 stands for logarithm. The right side part of the arrow is read to be &lt;em&gt;“Logarithm of 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;xx&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 to the base 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;bb&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 is equal to 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;aa&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
“&lt;/em&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Base(b)&lt;/strong&gt;: The number we are multiplying by itself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exponent(a)&lt;/strong&gt;: How many times we multiply the base.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Argument(x)&lt;/strong&gt;: The number that we are taking the logarithm of.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Restrictions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log⁡b(x)=a  if and only if  ba=x\log_{b}(x) = a \;\text{if and only if}\; b^a = x&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt;if and only if&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;a&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
. This is the basic definition of a logarithm.&lt;/li&gt;
&lt;li&gt;The base 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;bb&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 of a logarithm is always a positive real number (
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;b∈R  ∣  x&amp;gt;0b \in \mathbb{R} \;\vert\; x &amp;gt; 0&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;∈&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathbb"&gt;R&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;∣&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
)&lt;/li&gt;
&lt;li&gt;The argument 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;xx&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 is always a positive real number (
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;x∈R  ∣  x&amp;gt;0x \in \mathbb{R} \;\vert\; x &amp;gt; 0&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;∈&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathbb"&gt;R&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;∣&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Why do we use logarithms?
&lt;/h2&gt;

&lt;p&gt;Logarithms show up all over math, science, engineering, and computing. Here’s why:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;They scale down large numbers&lt;/li&gt;
&lt;li&gt;They convert multiplication into addition&lt;/li&gt;
&lt;li&gt;They reverse exponentiation&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  They scale down large numbers
&lt;/h3&gt;

&lt;p&gt;Many real-world phenomena grow or shrink exponentially (e.g. population growth, viral infections, radioactive decay, financial interest, …). These changes happen so fast that it’s hard to describe them with linear math.&lt;/p&gt;

&lt;p&gt;Why? Linear math assumes steady, additive growth. It’s like climbing stairs, flight over flight. Exponential growth is like climbing the same stairs but skipping increasingly more and more flights with every step. Each step is &lt;strong&gt;multiplicative&lt;/strong&gt; in stead of additive.&lt;/p&gt;

&lt;p&gt;Continuous multiplicative growth quickly outpaces our ability to model or interpret it with simple arithmetic, and that’s where logarithms come in, since they convert exponential relationships into linear relationships (but do not change the underlying data).&lt;/p&gt;

&lt;p&gt;In other words, logarithms &lt;strong&gt;linearize exponential growth&lt;/strong&gt; : They &lt;em&gt;“compress”&lt;/em&gt; fast-growing data into a scale we can handle more easily.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fye6qkeiw2an9bdv3u0ly.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fye6qkeiw2an9bdv3u0ly.png" alt="Comparing Exponential, Linear, and Logarithmic Curves"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For an interactive version of this image, see &lt;a href="https://www.geogebra.org/graphing/ppgejxu5" rel="noopener noreferrer"&gt;GeoGebra&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What do we see graphed?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linear functions grow at a steady, continuous pace&lt;/li&gt;
&lt;li&gt;All logarithmic functions pass through the point 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;(1,0)(1,0)&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;Logarithmic functions grow slowly&lt;/li&gt;
&lt;li&gt;Exponentials (
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;exe^x&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
) grow rapidly&lt;/li&gt;
&lt;li&gt;Logarithms are the inverse of exponentials&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compared to exponential growth like 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;exe^x&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, logarithmic functions such as 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log(x)log(x)&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 grow very slowly. This &lt;em&gt;“compression”&lt;/em&gt; of scale makes it less-complex to analyze, as the curve flattens out and almost behaves linearly across a wide range of input values. This allows us to apply simpler, linear arithmetic to model and work with phenomena that are otherwise exponential.&lt;/p&gt;
&lt;h3&gt;
  
  
  They turn multiplication into addition
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Product Rule&lt;/strong&gt; is one of the most powerful features of logarithms:&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log⁡(a⋅b)=log⁡(a)+log⁡(b)\log(a\cdot b) = \log(a) + \log(b)&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;It tells us that the logarithm of a product is equal to the sum of the logarithms of the individual factors. To put it simply: &lt;strong&gt;Multiplying values inside a logarithm is the same as adding their logarithms&lt;/strong&gt;. This might seem a little abstract at first, so let’s use a simple analogy and then dive deeper into the math.&lt;/p&gt;

&lt;p&gt;Why does the Product Rule work?&lt;/p&gt;

&lt;p&gt;Logarithms are the inverse of exponentiation, and exponentiation has the same property: When you multiply numbers in the base of an exponential, you add their exponents, given that the base of all numbers is the same.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;bx⋅by=bx+yb^x\cdot b^y = b^{x+y}&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;x&lt;/span&gt;&lt;span class="mbin mtight"&gt;+&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;This is just a basic property of exponents: when you multiply powers of the same base, you add the exponents. Don’t worry, I have added examples below. If we take the logarithm of both sides of the equation above, we get:&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;logb(bx⋅by)=log(bx+y)log_{b}(b^x\cdot b^y) = log(b^{x+y})&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;x&lt;/span&gt;&lt;span class="mbin mtight"&gt;+&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;Using the &lt;strong&gt;logarithm rule for powers&lt;/strong&gt; , we can simplify the right-hand side:&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;logb(bx⋅by)=x+ylog_{b}(b^x\cdot b^y) = x+y&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;Now, from the &lt;strong&gt;product rule&lt;/strong&gt; , we can see that:&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;logb(bx⋅by)=logb(bx)+logb(by)log_{b}(b^x\cdot b^y) = log_{b}(b^x) + log_{b}(b^y)&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;Which results in:&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;logb(bx⋅by)=x+y=logb(bx)+logb(by)log_{b}(b^x\cdot b^y) = x+y = log_{b}(b^x) + log_{b}(b^y)&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;And this is exactly the product rule.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;

&lt;p&gt;Let’s make this more concrete with numbers. We have two numbers, 100 and 10, and we want to compute the logarithm of their product:&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log10(100⋅10)=log10(1000)log_{10}(100\cdot10)=log_{10}(1000)&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;10&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;1000&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;Now. using the &lt;strong&gt;product rule&lt;/strong&gt;&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log10(100)+log10(10)log_{10}(100) + log_{10}(10)&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;10&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;We compute that&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log10(100)=2log_{10}(100) = 2&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
 


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log10(10)=1log_{10}(10) = 1&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;10&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;Hence,&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log10(100)+log10(10)=3log_{10}(100) + log_{10}(10)=3&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;10&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;And, indeed:&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log10(1000)=3⇔103=1000log_{10}(1000) = 3 \Leftrightarrow 10^3=1000&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;1000&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;⇔&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1000&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;h4&gt;
  
  
  Why is this useful?
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Simplifying Calculations&lt;/strong&gt; : The Product Rule makes complex logarithmic expressions easier to simplify and calculate, especially when dealing with large numbers or unknowns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Breaking Down Multiplications&lt;/strong&gt; : If you need to multiply two values but want to avoid directly multiplying them (e.g. to avoid complexity), you can first take their logarithms, add them, and then take the antilog (inverse logarithm) to find the product. This was especially useful before calculators, when logarithmic tables were common.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dealing with Exponentials in Data&lt;/strong&gt; : In real-world applications like data science, physics, or machine learning, many processes involve multiplying values that could be better handled with logarithms. By breaking multiplication into addition, it often becomes computationally simpler and more stable.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  They Reverse Exponentiation
&lt;/h3&gt;

&lt;p&gt;Logarithms &lt;strong&gt;undo&lt;/strong&gt; exponentials and this help solve equations where the unknown is an exponent. For example, if you know&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;2x=162^x=16&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;16&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;You can solve for 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;xx&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 with&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log2(16)=x=4log_{2}(16) = x = 4&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;16&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;So, logarithms help you solve for exponents — the exact inverse operation of exponentiation. This is why:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A logarithm is the inverse of an exponential function.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Why it matters
&lt;/h4&gt;

&lt;p&gt;In many equations, especially in science and engineering, you know the argument and the base, but you need to find the exponent. That’s when you turn to logarithms.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three Common Types of Logarithms
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Common Logarithm (Base 10)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Written as 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log⁡(x)\log(x)&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;Used in scientific notation and calculators&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Natural Logarithm (Base e)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Written as 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;ln(x)ln(x)&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 where 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;e≈2.718e \approx 2.718&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;≈&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;2.718&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;Found in continuous growth/decay processes and advanced mathematics&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Binary Logarithm (Base 2)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Written as 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log⁡2(x)\log_{2}(x)&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;Used in computer science (e.g. data structures and algorithms)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Real-World Applications of Logarithms
&lt;/h2&gt;

&lt;p&gt;Logarithms aren’t just abstract math — they’re part of everyday technologies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Machine Learning &amp;amp; AI&lt;/strong&gt; : Algorithms like Naive Bayes use logarithms to make probability computations more stable and efficient.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search Engines&lt;/strong&gt; : &lt;a href="https://en.wikipedia.org/wiki/Tf%E2%80%93idf" rel="noopener noreferrer"&gt;TF-IDF scores&lt;/a&gt; for search relevance use logarithmic scaling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audio &amp;amp; Sound&lt;/strong&gt; : Decibels (dB) are a logarithmic measure of sound intensity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Earthquakes&lt;/strong&gt; : The Richter scale is logarithmic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Finance&lt;/strong&gt; : Compound interest is modeled exponentially; logs help reverse it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Computer Science&lt;/strong&gt; : Binary logarithms appear in time complexity, especially in search and sort algorithms (e.g., binary search: O(log n)).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The 7 laws of logarithms
&lt;/h2&gt;

&lt;p&gt;The 7 laws (also called properties or identities) of logarithms are used to simplify, expand, or condense them. Depending on the situation, the laws can be applied to make computations easier.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Product rule
&lt;/h3&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log⁡(a⋅b)=log⁡(a)+log⁡(b)\log(a\cdot b) = \log(a) + \log(b)&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;The logarithm of a product is the sum of the logarithms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log⁡10(100⋅1000)=log⁡10\log_{10}(100\cdot1000)=\log_{10}&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1000&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  2. Quotient rule
&lt;/h3&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log⁡b(xy)=log⁡b(x)−log⁡b(y)\log_{b}(\frac{x}{y}) = \log_{b}(x) - \log_{b}(y)&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;The logarithm of a quotient is the difference of the logarithms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log⁡2(432)=log⁡2(32)−log⁡2(4)=5−2=3\log_{2}(\frac{4}{32})=\log_{2}(32) - \log_{2}(4) = 5 - 2 = 3&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;32&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;32&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;4&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;5&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  3. Power rule
&lt;/h3&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log⁡b(xp)=plog⁡b(x)\log_{b}(x^p)=p\log_{b}(x)&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;p&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;The logarithm of a power is the exponent times the logarithm of 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;xx&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log⁡10(1003)=3⋅log⁡10(100)=3⋅2=6\log_{10}(100^3) = 3\cdot\log_{10}(100) = 3\cdot2=6&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;10&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;100&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;6&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  4. Change-of-Base rule
&lt;/h3&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log⁡b(x)=log⁡k(x)log⁡k(b)\log_{b}(x) = \frac{\log_{k}(x)}{\log_{k}(b)}&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;The Change-of-Base rule allows changing the base of a logarithm to a different base.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log⁡2(8)=log⁡10(8)log⁡10(2)≈0.9030.301≈3\log_{2}(8)=\frac{\log_{10}(8)}{\log_{10}(2)}\approx\frac{0.903}{0.301}\approx3&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;8&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;8&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;≈&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;0.301&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;0.903&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;≈&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  5. Zero Exponent rule
&lt;/h3&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log⁡b(1)=0\log_{b}(1)=0&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;Regardless of its base, the logarithm of 1 is always 0.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Log of 1 rule
&lt;/h3&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;log⁡b(b)=1\log_{b}(b)=1&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;The logarithm of the base to itself is always 1.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Log of base rule
&lt;/h3&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;blog⁡b(x)=xb^{\log_{b}(x)}=x&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;b&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mop mtight"&gt;&lt;span class="mop mtight"&gt;&lt;span class="mtight"&gt;l&lt;/span&gt;&lt;span class="mtight"&gt;o&lt;/span&gt;&lt;span class="mtight"&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size3 size1 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;b&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen mtight"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;x&lt;/span&gt;&lt;span class="mclose mtight"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;The base raised to the log of a number returns the number&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;2log⁡2(10)=102^{\log_{2}(10)}=10&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mop mtight"&gt;&lt;span class="mop mtight"&gt;&lt;span class="mtight"&gt;l&lt;/span&gt;&lt;span class="mtight"&gt;o&lt;/span&gt;&lt;span class="mtight"&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size3 size1 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen mtight"&gt;(&lt;/span&gt;&lt;span class="mord mtight"&gt;10&lt;/span&gt;&lt;span class="mclose mtight"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  History of Logarithms
&lt;/h2&gt;

&lt;p&gt;Logarithms were invented by &lt;a href="https://en.wikipedia.org/wiki/John_Napier" rel="noopener noreferrer"&gt;John Napier&lt;/a&gt; in the early 1600s to simplify calculations. Before calculators, scientists used logarithm tables to perform long multiplications and divisions. The invention of the slide rule, which used logarithmic scales, revolutionized engineering and astronomy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Logarithms are one of the most elegant tools in mathematics. They allow us to simplify multiplication, deal with exponential growth, and make real-world problems manageable—from data science to earthquake measurement. Even if you start with zero math background, understanding logarithms gives you access to a whole new world of problem-solving techniques.&lt;/p&gt;

&lt;p&gt;If you’re learning machine learning, algorithms, or even just trying to understand scientific scales, logs will be your friend. And now, you know exactly what they are and why they matter.&lt;/p&gt;

</description>
      <category>math</category>
      <category>logarithm</category>
      <category>beginners</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>From Neural Nets to Hashmaps — Why I’m Relearning the Fundamentals</title>
      <dc:creator>Stefan Nieuwenhuis</dc:creator>
      <pubDate>Wed, 09 Apr 2025 00:00:00 +0000</pubDate>
      <link>https://dev.to/stefannieuwenhuis/from-neural-nets-to-hashmaps-why-im-relearning-the-fundamentals-777</link>
      <guid>https://dev.to/stefannieuwenhuis/from-neural-nets-to-hashmaps-why-im-relearning-the-fundamentals-777</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“You don’t really understand a concept until you’ve taught it.”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I recently set out on a mission to revisit fundamental data structures—not just to refresh my knowledge, but to better articulate and document them as part of my public learning journey. This post kicks off a new series where I’ll be blogging my notes and learnings as I dive deeper into Data Structures &amp;amp; Algorithms (DSA).&lt;/p&gt;

&lt;p&gt;In this first entry, we’ll explore one of the most essential and elegant structures: &lt;strong&gt;hashmaps&lt;/strong&gt; (also known as dictionaries in Python).&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 Why Start with Hashmaps?
&lt;/h2&gt;

&lt;p&gt;As a Machine Learning Engineer, I often interact with complex distributed systems and large-scale data pipelines. But I’ve learned over the years that &lt;strong&gt;deep mastery of foundational data structures&lt;/strong&gt; gives you an edge when debugging, optimizing, or explaining complex systems.&lt;/p&gt;

&lt;p&gt;Hashmaps are ubiquitous in machine learning codebases, from feature stores and caches to logging metadata, configs, and parameter storage.&lt;/p&gt;

&lt;p&gt;Let’s break them down from the ground up.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧩 Why Hashmaps Matter (Even in ML)
&lt;/h2&gt;

&lt;p&gt;You might ask: &lt;strong&gt;Why should someone working on multi-armed bandits or collaborative filtering care about hashmaps?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because maps — aka dictionaries or hash tables — are &lt;strong&gt;everywhere&lt;/strong&gt; in production ML:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Counting term frequencies or user-item interactions? → Use a hashmap.&lt;/li&gt;
&lt;li&gt;Storing cached embedding vectors for reuse? → Use a hashmap.&lt;/li&gt;
&lt;li&gt;Implementing a feature store or a key-value-based retrieval backend? → Definitely a hashmap.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And beyond ML, hashmaps are the go-to tool for engineers working on performance-critical backend systems — just like the ones powering Booking.com’s search, availability, and personalization flows.&lt;/p&gt;

&lt;p&gt;So instead of just skimming the docs, I sat down and re-implemented the core operations, step by step. What I found was surprisingly delightful.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔧 How a Hashmap Actually Works
&lt;/h2&gt;

&lt;p&gt;At a high level, a hashmap is a &lt;strong&gt;key-value&lt;/strong&gt; store that lets you do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;prices = {'hotel_1': 89, 'hotel_2': 120}
print(prices['hotel_1']) # → 89

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But under the hood?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The key (&lt;code&gt;'hotel_1'&lt;/code&gt;) is passed through a &lt;strong&gt;hash function&lt;/strong&gt; , turning it into a numeric index.&lt;/li&gt;
&lt;li&gt;That index maps to a &lt;strong&gt;bucket&lt;/strong&gt; in an array.&lt;/li&gt;
&lt;li&gt;If two keys map to the same index (a &lt;strong&gt;collision&lt;/strong&gt; ), the hashmap resolves it — often using &lt;strong&gt;chaining&lt;/strong&gt; , where multiple key-value pairs are stored in a list at that index.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This simple trick makes &lt;strong&gt;average-case lookup, insert, and delete all O(1)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It’s blazing fast. And it’s why modern feature stores, caching layers, and even graph algorithms use them constantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔄 When I Relearned It, I Noticed…
&lt;/h2&gt;

&lt;p&gt;Something clicked. Not in a “textbook” way, but in a &lt;strong&gt;real-world recommender system&lt;/strong&gt; kind of way.&lt;/p&gt;

&lt;p&gt;Take the &lt;a href="https://leetcode.com/problems/group-anagrams" rel="noopener noreferrer"&gt;“Group Anagrams”&lt;/a&gt; problem. It feels abstract at first, but then you realize it’s just a question of &lt;strong&gt;key design&lt;/strong&gt;. You hash on a sorted string — a clever fingerprint — and group words accordingly.&lt;/p&gt;

&lt;p&gt;That’s exactly what we do in ML when creating &lt;strong&gt;hashed feature buckets&lt;/strong&gt; or &lt;strong&gt;aggregating click events&lt;/strong&gt; by session ID.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Revisiting these problems now feels like seeing old friends through a new lens: with the eyes of someone who has fought latency bugs and wrangled production data.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🧪 My Practice Flow
&lt;/h2&gt;

&lt;p&gt;As part of this DSA refresh, I’ve been solving classic hashmap-related LeetCode problems, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;a href="https://leetcode.com/problems/two-sum" rel="noopener noreferrer"&gt;Two Sum&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;✅ &lt;a href="https://leetcode.com/problems/group-anagrams" rel="noopener noreferrer"&gt;Group Anagrams&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;✅ &lt;a href="https://leetcode.com/problems/longest-consecutive-sequence" rel="noopener noreferrer"&gt;Longest Consecutive Sequence&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;✅ &lt;a href="https://leetcode.com/problems/subarray-sum-equals-k" rel="noopener noreferrer"&gt;Subarray Sum Equals K&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m not just solving them to get green ticks. I’m solving them to &lt;strong&gt;understand what makes solutions elegant, efficient, and robust enough to scale&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  📈 Complexity Recap
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;Average Case&lt;/th&gt;
&lt;th&gt;Worst Case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Insert&lt;/td&gt;
&lt;td&gt;O(1)&lt;/td&gt;
&lt;td&gt;O(n)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lookup&lt;/td&gt;
&lt;td&gt;O(1)&lt;/td&gt;
&lt;td&gt;O(n)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete&lt;/td&gt;
&lt;td&gt;O(1)&lt;/td&gt;
&lt;td&gt;O(n)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Yes, worst case is linear due to collisions — but with good hash functions and low load factors, you rarely hit it. Modern languages (Python, Java, Go, etc.) optimize aggressively here.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠️ Common Use Cases in ML Engineering
&lt;/h2&gt;

&lt;p&gt;Here’s where I see hashmaps in practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Feature lookup&lt;/strong&gt; in online prediction services&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Embedding tables&lt;/strong&gt; (backed by a key-value store)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Experiment tracking configs&lt;/strong&gt; (e.g., logging which variant a user saw)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hyperparameter tuning frameworks&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding how they behave under the hood helps me reason about performance bottlenecks—especially when dealing with large-scale or high-throughput services.&lt;/p&gt;

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

&lt;p&gt;Revisiting the hashmap wasn’t just a refresher for me—it was a reminder of how much power lies in simplicity. As I continue this DSA refresher series, I’ll keep connecting the dots between textbook knowledge and real-world machine learning engineering.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Why I’m Sharing This Publicly
&lt;/h2&gt;

&lt;p&gt;I’m building this blog as a transparent record of my learning process — not just to prep for interviews, but to sharpen my engineering instincts.&lt;/p&gt;

&lt;p&gt;It’s part of a larger project where I’m also:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Building a real-time recommender system from scratch with &lt;strong&gt;FastAPI + Redis + Spark&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Deploying everything to my bare-metal &lt;strong&gt;Kubernetes homelab&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Measuring end-to-end performance with &lt;strong&gt;Prometheus + Grafana&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Open-sourcing the entire thing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So whether you’re a fellow ML engineer, a systems-minded developer, or a recruiter curious about my thought process — welcome aboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  📣 Let’s Learn Together
&lt;/h2&gt;

&lt;p&gt;If you’re also revisiting the fundamentals — or if you’re deep in the weeds of ranking models and want to get more hands-on with infra — I’d love to connect.&lt;/p&gt;

&lt;p&gt;This is just the first in a series of DSA posts. Next up: Sliding windows, prefix sums, and graph traversal for recommender systems, and much more.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;👉 Check out the &lt;a href="https://stefannieuwenhuis.github.io/categories/#dsa" rel="noopener noreferrer"&gt;DSA series here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;👉 Follow the full &lt;a href="https://stefannieuwenhuis.github.io/categories/#recommender-system" rel="noopener noreferrer"&gt;Recommender From Scratch project here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;👉 Let’s connect on &lt;a href="https://www.linkedin.com/in/stefannhs" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; and &lt;a href="https://github.com/StefanNieuwenhuis" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See you in the next post.&lt;/p&gt;

</description>
      <category>dsa</category>
      <category>hashmaps</category>
      <category>datastructures</category>
      <category>fundamentals</category>
    </item>
    <item>
      <title>Shadow DOM: What it is and how it works</title>
      <dc:creator>Stefan Nieuwenhuis</dc:creator>
      <pubDate>Fri, 03 Mar 2023 15:43:39 +0000</pubDate>
      <link>https://dev.to/stefannieuwenhuis/shadow-dom-what-it-is-and-how-it-works-4d4h</link>
      <guid>https://dev.to/stefannieuwenhuis/shadow-dom-what-it-is-and-how-it-works-4d4h</guid>
      <description>&lt;p&gt;The web has come a long way since the early days. Today, developers can create complex web applications using a variety of tools and frameworks. However, with this complexity comes a new set of challenges, such as ensuring that the styles and behavior of a web application are consistent across different browsers and platforms. This is where the Shadow DOM comes in. &lt;/p&gt;

&lt;p&gt;In this article, we'll explore the Shadow DOM in more detail, including its syntax, use cases, advantages, and disadvantages.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Shadow DOM?
&lt;/h2&gt;

&lt;p&gt;Shadow DOM is a technology that enables developers to create encapsulated DOM trees, which are separate from the main document tree. These DOM trees are attached to &lt;a href="https://nhswd.com/blog/web-components-101-what-are-web-components" rel="noopener noreferrer"&gt;custom elements&lt;/a&gt;, and provide a way to isolate the styles and behavior of the custom element from the rest of the document. This means that styles and behaviors defined in the Shadow DOM will only affect the custom element, and not any other elements on the page.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does it work?
&lt;/h2&gt;

&lt;p&gt;When a custom element is defined with Shadow DOM, it creates a new Document Fragment that is attached to the custom element. This Document Fragment contains a new DOM tree that is separate from the main document tree. Any styles or behaviors defined in the Shadow DOM will only affect elements within this new DOM tree.&lt;/p&gt;

&lt;p&gt;To attach Shadow DOM to a custom element, developers use the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow" rel="noopener noreferrer"&gt;attachShadow()&lt;/a&gt; method of the &lt;a href="https://html.spec.whatwg.org/multipage/dom.html#htmlelement" rel="noopener noreferrer"&gt;HTMLElement class&lt;/a&gt;. This method takes an object with two properties: &lt;code&gt;mode&lt;/code&gt; and &lt;code&gt;delegatesFocus&lt;/code&gt;. The mode property determines whether the Shadow DOM tree is &lt;strong&gt;open&lt;/strong&gt; or &lt;strong&gt;closed&lt;/strong&gt;, while the delegatesFocus property determines whether the custom element can receive keyboard focus.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyElement&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HTMLElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shadow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attachShadow&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;open&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="c1"&gt;// Add elements to shadow DOM tree here&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;Once we've created the Shadow DOM tree, we can add elements to it just like we would with the regular DOM. Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyElement&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HTMLElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shadow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attachShadow&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;open&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello, Shadow DOM!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;div&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 this example, we've created a custom element called MyElement, and attached a Shadow DOM tree to it with the mode set to &lt;em&gt;'open'&lt;/em&gt;. We've then created a new &lt;code&gt;&amp;lt;div/&amp;gt;&lt;/code&gt; element, set its text content to 'Hello, Shadow DOM!', and added it to the Shadow DOM tree using the &lt;code&gt;appendChild()&lt;/code&gt; method.&lt;/p&gt;

&lt;h2&gt;
  
  
  Examples of how it can be used
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Custom input element
&lt;/h3&gt;

&lt;p&gt;Let's say you want to create a custom input element that looks and behaves differently from the standard HTML input element. You can define a custom element with Shadow DOM, and use CSS to style the input element within the Shadow DOM. Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyInputElement&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HTMLElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shadow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attachShadow&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;open&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;placeholder&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Enter text here&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;inline-block&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;border&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1px solid #ccc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;padding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;5px&lt;/span&gt;&lt;span class="dl"&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;span class="nx"&gt;customElements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MyInputElement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we've created a new custom input element called MyInputElement. We've attached Shadow DOM to this element using the &lt;code&gt;attachShadow()&lt;/code&gt; method, and set the mode to &lt;em&gt;'open'&lt;/em&gt;. We then created a new input element within the Shadow DOM, and added some styling using CSS.&lt;/p&gt;

&lt;p&gt;To use this custom input element, we simply use the &lt;code&gt;&amp;lt;my-input&amp;gt;&lt;/code&gt; tag in our HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;my-input&amp;gt;&amp;lt;/my-input&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Custom button element
&lt;/h3&gt;

&lt;p&gt;Another example of using Shadow DOM is to create a custom button element. Let's say you want to create a button that has a different look and feel from the standard HTML button element. You can define a custom element with Shadow DOM, and use CSS to style the button within the Shadow DOM. Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyButtonElement&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HTMLElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shadow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attachShadow&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;open&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;label&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;inline-block&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;border&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1px solid #ccc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;padding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;5px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backgroundColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#f0f0f0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;border&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backgroundColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#f0f0f0
  }
}

customElements.define(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;my&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;, MyButtonElement);
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To use this custom input element, we simply use the &lt;code&gt;&amp;lt;my-button&amp;gt;&lt;/code&gt; tag in our HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;my-button&amp;gt;&amp;lt;/my-button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Use cases
&lt;/h2&gt;

&lt;p&gt;The Shadow DOM has several use cases, including:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Creating reusable web components&lt;/strong&gt;: With the Shadow DOM, developers can create encapsulated web components that can be used in any web application without interfering with the styles and behavior of other components.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Styling web components&lt;/strong&gt;: The Shadow DOM provides a way to encapsulate the styles of a web component, so that they don't interfere with the styles of other components on the page.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Creating custom elements with default styles&lt;/strong&gt;: The Shadow DOM allows developers to define default styles for a custom element, which are applied only to the elements within the Shadow DOM tree.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Advantages of Shadow DOM
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Encapsulation
&lt;/h3&gt;

&lt;p&gt;One of the main advantages of Shadow DOM is that it allows developers to encapsulate the styles and behavior of a custom element, preventing it from being affected by styles and scripts outside of its DOM tree. This makes it easier to maintain and reuse custom elements across different parts of the web application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Improved Styling
&lt;/h3&gt;

&lt;p&gt;With Shadow DOM, developers can use CSS to style their custom elements, without affecting the rest of the document. This means that they can use class names and selectors that would otherwise conflict with styles in the rest of the document.&lt;/p&gt;

&lt;h3&gt;
  
  
  Improved Performance
&lt;/h3&gt;

&lt;p&gt;Shadow DOM can also improve the performance of web applications by reducing the amount of CSS and JavaScript that needs to be loaded and executed. This is because styles and scripts can be defined within the Shadow DOM tree, rather than in the main document tree.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disadvantages of Shadow DOM
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Complexity
&lt;/h3&gt;

&lt;p&gt;Shadow DOM can be a complex technology to work with, and may require a deep understanding of the web platform and JavaScript to use effectively. This can make it difficult for less experienced developers to use in their web applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Legacy Browser Support
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F12104589%2F222395060-c80525bd-de57-4897-bc45-4ff23e5b2f7a.png" class="article-body-image-wrapper"&gt;&lt;img alt="Shadow DOM Brower Support" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F12104589%2F222395060-c80525bd-de57-4897-bc45-4ff23e5b2f7a.png" width="800" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another potential disadvantage of Shadow DOM is that it is not supported in legacy browsers. This can limit the reach of web applications that rely on Shadow DOM, and may require developers to use fallbacks or alternative solutions for unsupported browsers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessibility
&lt;/h3&gt;

&lt;p&gt;Finally, Shadow DOM can have implications for accessibility, as it may prevent users from being able to navigate or interact with the custom element using keyboard navigation. This can be mitigated by ensuring that the custom element is accessible using alternative methods, such as &lt;a href="https://web.dev/learn/accessibility/aria-html" rel="noopener noreferrer"&gt;ARIA attributes&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Shadow DOM is a powerful web technology that can provide many advantages to web developers, including improved encapsulation, styling, and performance. However, it also has some potential disadvantages, such as complexity, limited browser support, and accessibility issues.&lt;/p&gt;

&lt;p&gt;Despite these challenges, Shadow DOM remains an important tool in the web developer's toolbox, and can be used effectively in many web applications. To use Shadow DOM effectively, it is important to have a deep understanding of the technology and its implications for web development, and to carefully consider the needs of the application and its users.&lt;/p&gt;

</description>
      <category>gratitude</category>
    </item>
    <item>
      <title>Fake news: 6 false claims about Web Components</title>
      <dc:creator>Stefan Nieuwenhuis</dc:creator>
      <pubDate>Tue, 01 Jun 2021 13:57:58 +0000</pubDate>
      <link>https://dev.to/stefannieuwenhuis/fake-news-6-false-claims-about-web-components-4n2o</link>
      <guid>https://dev.to/stefannieuwenhuis/fake-news-6-false-claims-about-web-components-4n2o</guid>
      <description>&lt;h2&gt;
  
  
  6 False claims about Web Components
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Web Components aren't supported by browsers&lt;/li&gt;
&lt;li&gt;Web Components can't be used in JavaScript Frameworks and Libraries&lt;/li&gt;
&lt;li&gt;Web Components are dead&lt;/li&gt;
&lt;li&gt;Web Components cannot accept complex data&lt;/li&gt;
&lt;li&gt;You are forced to use Shadow DOM&lt;/li&gt;
&lt;li&gt;Web Components are Google Technology&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  About the author
&lt;/h2&gt;

&lt;p&gt;Stefan is a JavaScript Web Developer with more than 10 years of experience. He loves to play sports, read books and occasionally jump out of planes (with a parachute that is).&lt;/p&gt;

&lt;p&gt;☞ If you like this article, please support Stefan &lt;a href="https://www.buymeacoffee.com/stefannhs" rel="noopener noreferrer"&gt;by buying him a coffee&lt;/a&gt; ❤️.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Web Components aren't supported by browsers
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ddgv8m5rnhnqqs9v9iv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ddgv8m5rnhnqqs9v9iv.png" alt="Most browsers support Web Components completely" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This screenshot was taken on May 20, 2021, from &lt;a href="https://www.webcomponents.org" rel="noopener noreferrer"&gt;WebComponents.org&lt;/a&gt;, and most browsers, except for &lt;a href="https://nhswd.com/blog/web-components-101-what-are-web-components/#internet-explorer" rel="noopener noreferrer"&gt;IE11&lt;/a&gt; and &lt;a href="https://nhswd.com/blog/web-components-101-what-are-web-components/#safari" rel="noopener noreferrer"&gt;Safari&lt;/a&gt;, offer full support for Web Components.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Web Components can't be used in JavaScript Frameworks and Libraries
&lt;/h2&gt;

&lt;p&gt;The support for Web Components in frameworks and libraries like Angular and VueJs is excellent and ever-growing! Just a quick peek at &lt;a href="https://custom-elements-everywhere.com" rel="noopener noreferrer" title="A series of test suites against JavaScript frameworks to verify Custom Elements support"&gt;Custom Elements Everywhere&lt;/a&gt; tells you that Custom Elements are fully supported by almost every popular framework and library. The only caveat is React. It does support Web Components, but &lt;a href="https://nhswd.com/blog/web-components-101-what-are-web-components/#web-components-and-framework-support" rel="noopener noreferrer"&gt;not entirely&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Web Components are dead
&lt;/h2&gt;

&lt;p&gt;Many people claim that Web Components are dead, not supported completely and will never find a place in &lt;em&gt;mainstream development&lt;/em&gt;, whatever that may be.&lt;/p&gt;

&lt;p&gt;But, in fact, the opposite is true. Custom Elements are more popular than ever! More than &lt;a href="https://nhswd.com/blog/web-components-101-what-are-web-components" rel="noopener noreferrer"&gt;10 percent of all page loads in Google Chrome&lt;/a&gt; are pages that contain Web Components.&lt;/p&gt;

&lt;p&gt;Besides that, companies like Mc Donalds, Apple, GitHub, Twitter, Google, Salesforce, ING &amp;amp; SAP are using Web Components for both their public-facing applications as internal tools.&lt;/p&gt;

&lt;p&gt;Browser support is flourishing as well as JavaScript framework support. I think that we safely could say: Web Components have never been so alive!&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Web Components cannot accept complex data
&lt;/h2&gt;

&lt;p&gt;This idea originates from a fundamental misunderstanding of the DOM and its inner workings. Four misconceptions are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Custom Elements are HTML Elements.&lt;/li&gt;
&lt;li&gt;HTML Elements don't have properties; only attributes.&lt;/li&gt;
&lt;li&gt;Attributes can only be strings.&lt;/li&gt;
&lt;li&gt;Web Components can only accept strings in attributes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Custom Elements are indeed HTML Elements but are &lt;strong&gt;DOM nodes&lt;/strong&gt; as well, and because of that, accept &lt;strong&gt;complex data&lt;/strong&gt; as properties, using JavaScript and the DOM.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. You are forced to use Shadow DOM
&lt;/h2&gt;

&lt;p&gt;Never used Custom Elements without the Shadow DOM? Think again. Just go to &lt;a href="https://github.com" rel="noopener noreferrer" title="GitHub.com"&gt;GitHub&lt;/a&gt;, open the Developer's console and paste the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isCustomElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;tagName&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;tagName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`-`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;usesShadowDom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;shadowRoot&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;shadowRoot&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allCustomElements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`*`&lt;/span&gt;&lt;span class="p"&gt;)].&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;isCustomElement&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`All Custom Elements: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;allCustomElements&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="s2"&gt;`All Custom Elements w/ Shadow DOM: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;allCustomElements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;usesShadowDom&lt;/span&gt;
  &lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&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;a href="https://nhswd.com/blog/web-components-101-what-are-web-components/#3-shadow-dom" rel="noopener noreferrer"&gt;Shadow DOM is extremely powerful&lt;/a&gt;, because it encapsulates your components and prevents CSS and JavaScript from leaking in and out, but is completely optional. Here's a simple, and shadowless, example that works perfectly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ElementWithoutShadowDom&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HTMLElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;div&amp;gt;A Custom Element without Shadow DOM&amp;lt;/div&amp;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;span class="nx"&gt;customElements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`no-shadow`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ElementWithoutShadowDOM&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Web Components are Google Technology
&lt;/h2&gt;

&lt;p&gt;The Web Components specs are &lt;strong&gt;open standards&lt;/strong&gt; with multiple contributors, and stakeholders.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;a href="https://github.com/WICG/webcomponents/blob/gh-pages/proposals/html-modules-proposal.md" rel="noopener noreferrer" title="The HTML Modules proposal by MS"&gt;HTML Module proposal&lt;/a&gt; was picked up by Microsoft.&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://github.com/WICG/webcomponents/blob/gh-pages/proposals/Template-Instantiation.md" rel="noopener noreferrer" title="The HTML Template instantiation by Apple"&gt;HTML Template Instantiation&lt;/a&gt; was proposed by Apple.&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://github.com/WICG/webcomponents/issues/776" rel="noopener noreferrer" title="IDE standardization for Custom Elements by the VSCode Team"&gt;IDE standardization for Web Components initiative&lt;/a&gt; was lead by the Visual Studio Code (VSCode) Team.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;There are lots of false claims about Web Components, and today, we've debunked six of them. With support from (almost all) browsers, major JavaScript Frameworks and Libraries, and (big tech) companies, its popularity is growing every day. There is no reason why you shouldn't use it.&lt;/p&gt;

&lt;p&gt;I hope you'll try this fully native, interoperable, flexible, and reusable technology soon!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>webcomponents</category>
    </item>
    <item>
      <title>[tutorial] How to create a Web Component?</title>
      <dc:creator>Stefan Nieuwenhuis</dc:creator>
      <pubDate>Tue, 25 May 2021 16:32:54 +0000</pubDate>
      <link>https://dev.to/stefannieuwenhuis/tutorial-how-to-create-a-web-component-32cm</link>
      <guid>https://dev.to/stefannieuwenhuis/tutorial-how-to-create-a-web-component-32cm</guid>
      <description>&lt;p&gt;Welcome back to the Web Components 101 Series! We're going to discuss the state of Web Components, provide expert advice, give tips and tricks and reveal the inner workings of Web Components.&lt;/p&gt;

&lt;p&gt;In today's tutorial, we're going to teach you the fundamentals of Web Components by building a &lt;code&gt;&amp;lt;name-tag&amp;gt;&lt;/code&gt; component step by step!&lt;/p&gt;

&lt;p&gt;First, we have to learn the rules. Then, we're going to set up our development environment.&lt;/p&gt;

&lt;p&gt;Next, we'll define a new HTML element, going to learn how to pass attributes, create and use the &lt;a href="https://nhswd.com/blog/web-components-101-what-are-web-components/#3-shadow-dom" rel="noopener noreferrer"&gt;Shadow DOM&lt;/a&gt;, and use &lt;a href="https://nhswd.com/blog/web-components-101-what-are-web-components/#2-html-templates" rel="noopener noreferrer"&gt;HTML templates&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  About the author
&lt;/h2&gt;

&lt;p&gt;Stefan is a JavaScript Web Developer with more than 10 years of experience. He loves to play sports, read books and occasionally jump out of planes (with a parachute that is).&lt;br&gt;
☞ If you like this article, please support me by &lt;a href="https://www.buymeacoffee.com/stefannhs" rel="noopener noreferrer"&gt;buying me a coffee&lt;/a&gt; ❤️.&lt;/p&gt;
&lt;h2&gt;
  
  
  Other posts in the Web Components 101 series
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nhswd.com/blog/web-components-101-what-are-web-components" rel="noopener noreferrer"&gt;What are Web Components?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nhswd.com/blog/web-components-101-why-use-web-components" rel="noopener noreferrer"&gt;Why use Web Components?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[Tutorial] How to create a Web Component? (&lt;em&gt;this post&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The basic rules
&lt;/h2&gt;

&lt;p&gt;Even Web Components have basic rules and if we play by them, the possibilities are endless! We can even include emojis or non-Latin characters into the names, like &lt;code&gt;&amp;lt;animal-😺&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;char-ッ&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;These are the rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You can't register a &lt;strong&gt;Custom Element&lt;/strong&gt; more than once.&lt;/li&gt;
&lt;li&gt;Custom Elements cannot be &lt;a href="https://dev.w3.org/html5/html-author/#start-tag" title="What are self closing HTML tags?" rel="noopener noreferrer"&gt;self-closing&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;To prevent name clashing with existing HTML elements, &lt;a href="https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name" title="Naming conventions for custom elements" rel="noopener noreferrer"&gt;valid names&lt;/a&gt; should:

&lt;ul&gt;
&lt;li&gt;Always include a hyphen (-) in its name.&lt;/li&gt;
&lt;li&gt;Always be lower case.&lt;/li&gt;
&lt;li&gt;Not contain any uppercase characters.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Setting up our development environment
&lt;/h2&gt;

&lt;p&gt;For this tutorial, we're going to use the Components IDE from the good folks at WebComponents.dev. No set up required! Everything is already in place and properly configured, so we can start developing our component straight away. It even comes with &lt;a href="https://storybook.js.org/" title="Storybook: Open source UI tool for building UI components in isolation" rel="noopener noreferrer"&gt;Storybook&lt;/a&gt; and &lt;a href="https://mochajs.org/" title="Mocha is a BDD Testing Framework" rel="noopener noreferrer"&gt;Mocha&lt;/a&gt; preinstalled and preconfigured.&lt;/p&gt;
&lt;h3&gt;
  
  
  Steps to set up our dev env
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to the &lt;a href="https://webcomponents.dev/edit/VGwFgdGkk1ayG8xf5p7h" title="Link to the Components IDE" rel="noopener noreferrer"&gt;Components IDE&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Click the &lt;em&gt;Fork&lt;/em&gt; button in the top right of the screen to create your copy.&lt;/li&gt;
&lt;li&gt;Profit! Your environment is set up successfully.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Defining a new HTML Element
&lt;/h2&gt;

&lt;p&gt;Let's have a look at &lt;code&gt;index.html&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    highlight-next-line
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./dist/name-tag.js"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Hello World&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
    highlight-next-line
    &lt;span class="nt"&gt;&amp;lt;name-tag&amp;gt;&amp;lt;/name-tag&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On line 5, we include our component with a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;. This allows us to use our component, just like any other HTML elements in the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; (line 10) of our page.&lt;/p&gt;

&lt;p&gt;But we don't see anything yet, our page is empty. This is because our name tag isn't a proper HTML Tag (yet). We have to define a new HTML Element and this is done with JavaScript.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;code&gt;name-tag.js&lt;/code&gt; and create a class that extends the &lt;a href="https://html.spec.whatwg.org/multipage/dom.html#htmlelement" title="HTML Spec on base HTMLElement class" rel="noopener noreferrer"&gt;base HTMLElement class&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Call &lt;code&gt;super()&lt;/code&gt; in the class constructor. Super sets and returns the component's &lt;code&gt;this&lt;/code&gt; scope and ensures that the right property chain is inherited.&lt;/li&gt;
&lt;li&gt;Register our element to the &lt;a href="https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-api" title="HTML Spec on Custom Elements Registry" rel="noopener noreferrer"&gt;Custom Elements Registry&lt;/a&gt; to teach the browser about our new component.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is how our class should look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserCard&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HTMLElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&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="nx"&gt;customElements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name-tag&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;UserCard&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congrats! You've successfully created and registered a new HTML Tag!&lt;/p&gt;

&lt;h2&gt;
  
  
  Passing values to the component with HTML attributes
&lt;/h2&gt;

&lt;p&gt;Our name tag doesn't do anything interesting yet. Let's change that and display the user's name, that we pass to the component with a &lt;code&gt;name&lt;/code&gt; attribute.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Attributes provide extra information about HTML tags, always come in name/value pairs, and could only contain strings.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First, we have to add a &lt;code&gt;name&lt;/code&gt; attribute to the &lt;code&gt;&amp;lt;name-tag&amp;gt;&lt;/code&gt; in &lt;em&gt;index.html&lt;/em&gt;. This enables us to pass and read the value from our component&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;name-tag&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"John Doe"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/name-tag&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we've passed the attribute, it's time to retrieve it! We do this with the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute" title="MDN Reference to the Element.getAttribute method" rel="noopener noreferrer"&gt;Element.getAttribute() method&lt;/a&gt; that we add to the components &lt;code&gt;constructor()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally, we're able to push the attribute's value to the components inner HTML. Let's wrap it between a &lt;code&gt;&amp;lt;h3&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is how our components class should look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserCard&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HTMLElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;h3&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/h3&amp;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;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our component now outputs "John Doe".&lt;/p&gt;

&lt;h3&gt;
  
  
  Add global styling
&lt;/h3&gt;

&lt;p&gt;Let's add some global styling to see what happens.&lt;/p&gt;

&lt;p&gt;Add the following CSS to the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; in &lt;code&gt;index.html&lt;/code&gt; and see that the component's heading color changes to Rebecca purple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;h3&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rebeccapurple&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create and use the Shadow DOM
&lt;/h2&gt;

&lt;p&gt;Now it's time to get the Shadow DOM involved! This ensures the encapsulation of our element and prevents CSS and JavaScript from leaking in and out.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add &lt;code&gt;this.attachShadow({mode: 'open'});&lt;/code&gt; to the component's constructor (&lt;a href="https://nhswd.com/blog/web-components-101-what-are-web-components/#3-shadow-dom" rel="noopener noreferrer"&gt;read more about Shadow DOM modes here&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;We also have to attach our &lt;code&gt;innerHTML&lt;/code&gt; to the shadow root. Replace &lt;code&gt;this.innerHTML&lt;/code&gt; with &lt;code&gt;this.shadowRoot.innerHTML&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is the diff of our &lt;em&gt;constructor&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;...
&lt;span class="p"&gt;constructor() {
&lt;/span&gt;  super();
  this.attachShadow({mode: 'open'});
&lt;span class="gd"&gt;- this.innerHTML = `&amp;lt;h3&amp;gt;${this.getAttribute('name')}&amp;lt;/h3&amp;gt;`;
&lt;/span&gt;&lt;span class="gi"&gt;+ this.shadowRoot.innerHTML = `&amp;lt;h3&amp;gt;${this.getAttribute('name')}&amp;lt;/h3&amp;gt;`;
&lt;/span&gt;}
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that the global styling isn't affecting our component anymore. The Shadow DOM is successfully attached and our component is successfully encapsulated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create and use HTML Templates
&lt;/h2&gt;

&lt;p&gt;The next step is to create and use &lt;a href="https://nhswd.com/blog/web-components-101-what-are-web-components/#2-html-templates" rel="noopener noreferrer"&gt;HTML Templates&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First, we have to create a &lt;code&gt;const template&lt;/code&gt; outside our components class in &lt;em&gt;name-tag.js&lt;/em&gt;, create a new &lt;em&gt;template&lt;/em&gt; element with the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement" title="MDN Reference to the Document.createElement() method" rel="noopener noreferrer"&gt;Document.createElement() method&lt;/a&gt; and assign it to our const.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;template&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
  &amp;lt;style&amp;gt;
    h3 {
      color: darkolivegreen; //because I LOVE olives
    }
  &amp;lt;/style&amp;gt;

  &amp;lt;div class="name-tag"&amp;gt;
    &amp;lt;h3&amp;gt;&amp;lt;/h3&amp;gt;
  &amp;lt;/div&amp;gt;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the template in place, we're able to clone it to the components Shadow Root. We have to replace our previous "HTML Template" solution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;...
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;class UserCard extends HTMLElement {
&lt;/span&gt;  constructor(){
    super();
    this.attachShadow({mode: 'open'});
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-   this.shadowRoot.innerHTML = `&amp;lt;h3&amp;gt;${this.getAttribute('name')}&amp;lt;/h3&amp;gt;`;
&lt;/span&gt;&lt;span class="gi"&gt;+   this.shadowRoot.appendChild(template.content.cloneNode(true));
&lt;/span&gt;  }
}
...
&lt;span class="err"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What about passing attributes?!
&lt;/h3&gt;

&lt;p&gt;Although we've added some styles, we see a blank page again. Our attribute values aren't rendered, so let's change that.&lt;/p&gt;

&lt;p&gt;We have to get out attribute's value to the template somehow. We don't have direct access to the components scope in the template, so we have to do it differently.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"name-tag"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;${this.getAttribute('name')}&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;This won't work since we don't have access to the component's scope in the template.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;We have to query the Shadow DOM for the desired HTML Element (i.e. &lt;code&gt;&amp;lt;h3&amp;gt;&lt;/code&gt;) and push the value of the attribute to its inner HTML.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;constructior&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shadowRoot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&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;The result is that we see &lt;em&gt;"John Doe"&lt;/em&gt; again on our page and this time, it's colored differently and the heading on the main page stays Rebecca purple! The styling we've applied works like a charm and is contained to the Shadow DOM. Just like we wanted to: No leaking of styles thanks to our component's encapsulating properties.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bonus: Update styles
&lt;/h3&gt;

&lt;p&gt;Update the &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; in the template to make our component look a bit more appealing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.name-tag&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;25px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f90304&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;arial&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt; &lt;span class="n"&gt;rgba&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="m"&gt;0&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="m"&gt;0.75&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;h3&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2em&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;uppercase&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;h2&gt;
  
  
  Closing thoughts about how to create a Web Component from scratch
&lt;/h2&gt;

&lt;p&gt;The game of Web Components has to be played by a handful of basic rules but when played right, the possibilities are endless! Today, we've learned step by step how to create a simple, &lt;code&gt;&amp;lt;name-tag&amp;gt;&lt;/code&gt; component by defining Custom Elements, passing HTML attributes, connecting the Shadow DOM, defining and cloning HTML templates, and some basic styling with CSS.&lt;/p&gt;

&lt;p&gt;I hope this tutorial was useful and I hope to see you next time!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>webcomponents</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Web Components 101: Why use Web Components?</title>
      <dc:creator>Stefan Nieuwenhuis</dc:creator>
      <pubDate>Fri, 21 May 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/stefannieuwenhuis/web-components-101-why-use-web-components-3me5</link>
      <guid>https://dev.to/stefannieuwenhuis/web-components-101-why-use-web-components-3me5</guid>
      <description>&lt;p&gt;Welcome back to the Web Components 101 Series! We're going to discuss the state of Web Components, provide expert advice, give tips and tricks and reveal the inner workings of Web Components.&lt;/p&gt;

&lt;p&gt;In this article, we'll explain why we're so excited about Web Components and why you want to use them. We also do some myth-busting along the way. Are you excited already?&lt;/p&gt;

&lt;h2&gt;
  
  
  About the author
&lt;/h2&gt;

&lt;p&gt;Stefan is a JavaScript Web Developer with more than 10 years of experience. He loves to play sports, read books and occasionally jump out of planes (with a parachute that is).&lt;br&gt;
☞ If you like this article, please support me by &lt;a href="https://www.buymeacoffee.com/stefannhs" rel="noopener noreferrer"&gt;buying me a coffee&lt;/a&gt; ❤️.&lt;/p&gt;
&lt;h2&gt;
  
  
  Posts in the Web Components 101 series
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nhswd.com/blog/web-components-101-what-are-web-components" rel="noopener noreferrer"&gt;What are Web Components?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Why use Web Components? (&lt;em&gt;this post&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Why use Web Components?
&lt;/h2&gt;

&lt;p&gt;JavaScript frameworks offer lots of advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Save energy&lt;/strong&gt;. Modern JavaSCript frameworks are packed with best practices, scaffolding tools, paradigms, and industry standards, which enables us to build and publish an app in no time. It enables developers to focus on actual development instead of the tools and architecture.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusable code&lt;/strong&gt;. Components built with a JavaScript framework are interchangeable (within applications using the same framework), so teams don't have to invent the square wheel twice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A common language for everyone&lt;/strong&gt;. Using a JavaScript framework generates a common understanding between developers. Everyone &lt;em&gt;"speaks"&lt;/em&gt; the same, common language and is on the same page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's not surprising that almost every JavaScript app is built with a (modern) JavaScript framework or library, so why should we use Web Components instead of using our favorite framework? What problems does providing a native component model solve?&lt;/p&gt;
&lt;h3&gt;
  
  
  (Brand) Consistency
&lt;/h3&gt;

&lt;p&gt;Consistent applications offer user-friendly interfaces and have high conversion rates. Inconsistent applications offer the exact opposite and undermine brand consistency. Having your apps split up into component libraries or a Design System, improves brand consistency but if and only if they are compatible with all different tech stacks.&lt;/p&gt;

&lt;p&gt;Web Components, with its web-standards-based APIs, is interchangeable between all different tech stacks and JavaScript frameworks and libraries and provides the perfect technical base for brand consistency throughout all applications.&lt;/p&gt;
&lt;h3&gt;
  
  
  Maintainability
&lt;/h3&gt;

&lt;p&gt;Building sustainable and maintainable applications is one of the hardest challenges in Web Development. Code is continuously copied from one (part of the) application to another, essentially creating new versions that have to be maintained indefinitely, which results in maintenance hell.&lt;/p&gt;

&lt;p&gt;Web Components can be maintained by one (team of) developers and shared with others. The maintainers take care of the components, while the consumers can fetch updates automatically (e.g. with &lt;a href="https://npmjs.com" rel="noopener noreferrer"&gt;npm&lt;/a&gt;) and continue their work without the fear of maintenance hell.&lt;/p&gt;
&lt;h3&gt;
  
  
  Reusability
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;K&lt;/strong&gt;eep &lt;strong&gt;I&lt;/strong&gt;t &lt;strong&gt;S&lt;/strong&gt;imple &lt;strong&gt;S&lt;/strong&gt;tupid, and &lt;strong&gt;D&lt;/strong&gt;on't &lt;strong&gt;R&lt;/strong&gt;epeat &lt;strong&gt;Y&lt;/strong&gt;ourself are the mantra's that we keep repeating and is a key part of building comprehensible, maintainable, and reusable apps. It is one of the hardest challenges in web development. With Web Components, we're solving this by defining markup in JavaScript. The author is free to change the HTML, CSS, and JavaScript, while the consumer can benefit from the changes automatically without the need of upgrading the code manually.&lt;/p&gt;
&lt;h3&gt;
  
  
  Interoperability
&lt;/h3&gt;

&lt;p&gt;JavaScript frameworks like Angular, React and VueJs are awesome! They are packed with best practices, scaffolding tools, paradigms, and industry standards, which enable us to build and publish an app in no time, but aren't very interoperable - they don't communicate with each other very well. This is because they all have different, non-interchangeable component models.&lt;/p&gt;

&lt;p&gt;Web Components are completely based on web standards and are compatible with (or without) any JavaScript library or framework. That means, that they are completely interoperable between frameworks and applications. It now becomes possible to support multiple applications with UI components from a single codebase (Design Systems and mono repositories).&lt;/p&gt;
&lt;h3&gt;
  
  
  Readability
&lt;/h3&gt;

&lt;p&gt;The most important audience for our code is humans (ourselves and other people), as we are the ones who will make or break the program in the future. Unfortunately, this doesn't always resonate and many HTML pages end up in an expressionless, and unreadable &lt;code&gt;&amp;lt;div/&amp;gt;&lt;/code&gt; soup, like Google's Gmail page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyygfuf36y8w540vyqj3t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyygfuf36y8w540vyqj3t.png" alt="An expressionless, and unreadable HTML DIV soup" width="800" height="623"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Web Components allows us to organize the &lt;code&gt;&amp;lt;div/&amp;gt;&lt;/code&gt; soup into comprehensible, readable, semantic-friendly code by creating custom elements wherever we see fit. Here's an example of how it would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;google-mail&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;mail-list&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;mail-item&lt;/span&gt; &lt;span class="na"&gt;from=&lt;/span&gt;&lt;span class="s"&gt;"john.doe@company.com"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Hello World&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/mail-item&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/mail-list&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/google-mail&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Full encapsulation
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://nhswd.com/blog/web-components-101-what-are-web-components/#3-shadow-dom" rel="noopener noreferrer"&gt;Shadow DOM&lt;/a&gt; allows web browsers to isolate DOM fragments. It means that we don't have to worry about styles and logic leaking to and from our Web Components. In other words: They are fully encapsulated.&lt;/p&gt;

&lt;h3&gt;
  
  
  Web Components are perfectly compatible with any JavaScript framework of library
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0zy8aecfg5hljrsqw435.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0zy8aecfg5hljrsqw435.png" alt="JavaScript Frameworks: React, Angular, and VueJs" width="800" height="390"&gt;&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;As mentioned in &lt;a href="https://nhswd.com/blog/web-components-101-what-are-web-components/#web-components-and-framework-support" rel="noopener noreferrer"&gt;the first article of the Web Components 101 Series&lt;/a&gt;, the support for Web Components from JavaScript frameworks and libraries is excellent and growing! Web Components can be used with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Angular&lt;/li&gt;
&lt;li&gt;AngularJs&lt;/li&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;Vue.js&lt;/li&gt;
&lt;li&gt;Svelte&lt;/li&gt;
&lt;li&gt;Vanilla JavaScript&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Busting myths about Web Components
&lt;/h2&gt;

&lt;p&gt;&lt;a href="" class="article-body-image-wrapper"&gt;&lt;img alt="Mythbusters"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why not use Web Components? There are a lot of myths about why not to use Web Components. The main reason is that they are built on &lt;a href="https://www.w3.org/TR/" rel="noopener noreferrer"&gt;evolving web standards&lt;/a&gt;, which have their flaws and limitations. I've seen some myths go around and now it's time to bust them!&lt;/p&gt;

&lt;h3&gt;
  
  
  Web Components can't be server-side rendered (SRR)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Busted!&lt;/strong&gt; Since Web Components are based on web standards, they can be server site rendered perfectly. It might be hard to do if you build a solution from scratch, but libraries like &lt;a href="https://github.com/skatejs/ssr" rel="noopener noreferrer"&gt;SkateJs&lt;/a&gt; and &lt;a href="https://stenciljs.com" rel="noopener noreferrer"&gt;Stencil&lt;/a&gt; will do all the heavy lifting for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Web Components don't work with JavaScript frameworks/libraries
&lt;/h3&gt;

&lt;p&gt;Both true and false. As mentioned in &lt;a href="https://nhswd.com/blog/web-components-101-what-are-web-components/#web-components-and-framework-support" rel="noopener noreferrer"&gt;the first article of the Web Components 101 Series&lt;/a&gt;, all JavaScript frameworks, except React are fully compatible. React supports Web Components, but passes all data to Custom Elements in the form of HTML attributes. For primitive data this is fine, but the system breaks down when passing rich data, like objects or arrays. Developers will need to reference their Custom Elements using a &lt;code&gt;ref&lt;/code&gt; and manually attach event listeners with &lt;code&gt;addEventListener&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Web Components aren't accessible (a11y)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Busted!&lt;/strong&gt; The main reason why folks think that Web Components aren't accessible is that HTML content is included in the Shadow DOM and not the main DOM, but in reality, this doesn't affect accessibility at all! The a11y information is exposed correctly through the &lt;a href="https://www.w3.org/TR/core-aam-1.1/" rel="noopener noreferrer"&gt;accessibility API&lt;/a&gt; and screenreaders can access content in the Shadow DOM without any difficulties.&lt;/p&gt;

&lt;h3&gt;
  
  
  Web Components aren't production-ready
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Busted!&lt;/strong&gt; Folks assume that because Web Components are built on evolving web standards, they aren't production-ready but that's not true! All W3 standards are continuously evolving and that means that no technology would ever be production-ready, which is nonsense.&lt;/p&gt;

&lt;p&gt;Besides that, &lt;a href="https://dev.to/ionic/apple-just-shipped-web-components-to-production-and-you-probably-missed-it-57pf" rel="noopener noreferrer"&gt;Apple&lt;/a&gt;, &lt;a href="https://dev.to/ionic/apple-just-shipped-web-components-to-production-and-you-probably-missed-it-57pf" rel="noopener noreferrer"&gt;Salesforce&lt;/a&gt;, and &lt;a href="https://github.blog/2021-05-04-how-we-use-web-components-at-github/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; are all using Web Components in production. Do you need more proof?&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing thoughts about why we use Web Components
&lt;/h2&gt;

&lt;p&gt;Although JavaScript frameworks and libraries offer developers many perks, they have their drawbacks as well and this is where Web Components can fill the gap perfectly. Based on web standards, Web Components are perfect for (brand) consistency, are maintainable, reusable, interoperable, and readable. They are also fully compatible with (or without) any JavaScript framework/library and offer full encapsulation.&lt;/p&gt;

&lt;p&gt;Many myths account for a negative image of Web Components and why folks aren't using them, but most of them are busted and nothing stands in the way of you using their full potential!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Web Components 101: What are Web Components?</title>
      <dc:creator>Stefan Nieuwenhuis</dc:creator>
      <pubDate>Thu, 20 May 2021 20:10:36 +0000</pubDate>
      <link>https://dev.to/stefannieuwenhuis/web-components-101-what-are-web-components-3fdi</link>
      <guid>https://dev.to/stefannieuwenhuis/web-components-101-what-are-web-components-3fdi</guid>
      <description>&lt;p&gt;Welcome to the Web Components 101 Series! We're going to discuss the state of Web Components, provide expert advice, give tips and tricks and reveal the inner workings of Web Components.&lt;/p&gt;

&lt;p&gt;Today, more than 10% of all page loads in Google Chrome are pages that contain Web Components! Big tech companies like Apple, Google and Facebook are also investigating ways of using Web Components in their applications and JavaScript Frameworks (e.g. Angular and React). Quite impressive for a technology officially introduced in 2011 and standardized only recently.&lt;/p&gt;

&lt;p&gt;Web Components are getting more popular everyday, that's why this is the perfect moment to start learning about this awesome technology!&lt;/p&gt;

&lt;h2&gt;
  
  
  About the author
&lt;/h2&gt;

&lt;p&gt;Stefan is a JavaScript Web Developer with more than 10 years of experience. He loves to play sports, read books and occasionally jump out of planes (with a parachute that is).&lt;br&gt;
☞ If you like this article, please support me by &lt;a href="https://www.buymeacoffee.com/stefannhs" rel="noopener noreferrer"&gt;buying me a coffee&lt;/a&gt; ❤️.&lt;/p&gt;
&lt;h2&gt;
  
  
  Posts in the Web Components 101 series
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What are Web Components? (&lt;em&gt;this post&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Why do you need Web Components? (&lt;em&gt;coming soon&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What are Web Components?
&lt;/h2&gt;

&lt;p&gt;Web Components are full HTML elements with custom templates, APIs and Tag Names. They allow you to create new HTML tags, extend existing HTML tags or extend the components from other developers. They can be used in any web application, are compatible with (or without) any JavaScript library or framework (e.g. React, Angular, Vue.js, Next.js) and will work with all modern browsers.&lt;/p&gt;

&lt;p&gt;Its foundation is its API, which brings a Web Standards-based way to create reusable components using nothing more than vanilla JavaScript, HTML and CSS.&lt;/p&gt;

&lt;p&gt;The four Standards used are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Custom Elements.&lt;/li&gt;
&lt;li&gt;HTML Templates.&lt;/li&gt;
&lt;li&gt;Shadow DOM.&lt;/li&gt;
&lt;li&gt;ES Modules.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's have a more detailed look at these Web Standards.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Custom Elements
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements" rel="noopener noreferrer"&gt;Custom Elements&lt;/a&gt; is a set of APIs that allows you to create new HTML tags. With this API, we can instruct the parser how to properly create an element and how it reacts to changes.&lt;/p&gt;

&lt;p&gt;There are two types of custom elements:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An &lt;strong&gt;autonomous custom element&lt;/strong&gt;, which can be used to create completely new HTML elements.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;customized built-in element&lt;/strong&gt;, which can be used to &lt;em&gt;extend&lt;/em&gt; existing HTML elements or other Web Components.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, the Custom Elements API is very useful for creating new HTML elements, but for extending existing or other Web Components as well.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. HTML Templates
&lt;/h3&gt;

&lt;p&gt;With HTML templates, we can create reusable code fragments inside a normal HTML flow that aren't rendered immediately. They can be cloned and inserted in the document during runtime with JavaScript and scripts, and resources inside will not be fetched or executed until the template is stamped out. It also doesn't matter how many times a template is used, since it's cloned in the browser and only parsed once; A great performance boost!&lt;/p&gt;

&lt;p&gt;A HTML Template syntax looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Web Components 101&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;HTML Templates are awesome!&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the page renders, a template is empty. The contents are stored in a &lt;code&gt;DocumentFragment&lt;/code&gt; without browsing context. This is done to prevent it from interfering with the rest of the application, meaning that it only renders when requested; Another performance boost!&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Shadow DOM
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnhswd.com%2Fstatic%2F83a8d9e62441891887f045a1bd36958f%2F21b4d%2Fshadow-dom-logo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnhswd.com%2Fstatic%2F83a8d9e62441891887f045a1bd36958f%2F21b4d%2Fshadow-dom-logo.png" alt="The Shadow DOM Logo" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Shadow DOM API allows web browsers to isolate DOM fragments (including all HTML and CSS) from the main documents DOM tree. Its inner working are almost similar to that of an &lt;code&gt;&amp;lt;iframe/&amp;gt;&lt;/code&gt; where the content is isolated from the rest of the document, with the main difference that we still have full control over it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h4&gt;
  
  
  What is the DOM?
&lt;/h4&gt;

&lt;p&gt;With HTML, we're able to easily create pages that have both presentation and structure. It's very easy for us humans to understand, but computers need a bit more help: Enter the &lt;strong&gt;D&lt;/strong&gt;ocument &lt;strong&gt;O&lt;/strong&gt;bject &lt;strong&gt;M&lt;/strong&gt;odel, or DOM.&lt;/p&gt;

&lt;p&gt;When the browser loads a web page, it translates the author's HTML into a data model, which is stored in a tree of nodes. This tree is called the DOM and is a live representation of the page. It has properties, methods and the best part is that it can be manipulated by...JavaScript!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Shadow DOM shields it contents from its surrounding environment (a process called encapsulation), which prevents CSS and JavaScript code from leaking from and to a custom element.&lt;/p&gt;

&lt;h3&gt;
  
  
  ES Modules
&lt;/h3&gt;

&lt;p&gt;Before ES Modules, JavaScript did not have a module system like other programming languages. Developers resorted to using &lt;code&gt;&amp;lt;script/&amp;gt;&lt;/code&gt; tags to load JavaScript files into their applications and later on, several module definitions started (e.g CommonJS, AMD &amp;amp; UMD) to appear but none matured to a standard. This changed with the introduction of ES Modules and we finally have a standard module system.&lt;/p&gt;

&lt;p&gt;The ES Modules API brings a standardized module system to JavaScript, which provides a way of bundling a collection of features into a library that can be reused in other JavaScript files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Web Components and Browser Support
&lt;/h2&gt;

&lt;p&gt;Which browsers support Web Components? Currently, all Evergreen browsers (Chrome, Firefox and Edge) offer full support for Web Components. That means, all APIs (i.e. Custom Elements, HTML Templates, Shadow DOM and ES Modules) are fully supported!&lt;/p&gt;

&lt;p&gt;This screenshot from &lt;a href="https://webcomponents.org" rel="noopener noreferrer"&gt;WebComponents.org&lt;/a&gt; shows the current browser support for Web Components.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnhswd.com%2Fstatic%2F5fd802be3de1a8e7c6e5fb48640330a2%2F71c1d%2Fwhich-browsers-support-web-components.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnhswd.com%2Fstatic%2F5fd802be3de1a8e7c6e5fb48640330a2%2F71c1d%2Fwhich-browsers-support-web-components.png" alt="Which browsers support Web Components?" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Internet Explorer
&lt;/h3&gt;

&lt;p&gt;Unfortunately, Internet Explorer 11 doesn't support Web Components, but &lt;a href="https://techcommunity.microsoft.com/t5/microsoft-365-blog/microsoft-365-apps-say-farewell-to-internet-explorer-11-and/ba-p/1591666" rel="noopener noreferrer"&gt;Microsoft stops supporting IE11&lt;/a&gt; on August 17, 2021, and in the meantime, &lt;a href="https://github.com/webcomponents/polyfills/tree/master/packages/webcomponentsjs" rel="noopener noreferrer"&gt;polyfills&lt;/a&gt; are available to simulate the missing browser capabilities as closely as possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Safari
&lt;/h3&gt;

&lt;p&gt;Safari does support Web Components, but it does &lt;strong&gt;not&lt;/strong&gt; support &lt;em&gt;Customized Built-in Elements&lt;/em&gt;, only &lt;em&gt;Autonomous Elements&lt;/em&gt;. Luckily, the &lt;a href="https://github.com/webcomponents/polyfills/tree/master/packages/webcomponentsjs#browser-support" rel="noopener noreferrer"&gt;polyfills&lt;/a&gt; offer support for Safari as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing thoughts about Web Components
&lt;/h2&gt;

&lt;p&gt;Modern Web Development becomes more complex everyday, and, now that the Web Platform and its standards are maturing, it makes more sense to use them more intensively. Web Components are the perfect example, based on 4 web-standard based APIs (Custom Elements, HTML Templates, Shadow DOM, and ES Modules).&lt;/p&gt;

&lt;p&gt;It's ever increasing popularity proofs that Web Components are here to stay and that now is the perfect time to start learning about this amazing technology!&lt;/p&gt;

&lt;p&gt;In the second post of the series, we're gonna discuss why Web Components are so amazing and why you want to use them.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webcomponents</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Merry Christmas! And a happy new year!</title>
      <dc:creator>Stefan Nieuwenhuis</dc:creator>
      <pubDate>Tue, 24 Dec 2019 14:47:45 +0000</pubDate>
      <link>https://dev.to/stefannieuwenhuis/merry-christmas-and-a-happy-new-year-pid</link>
      <guid>https://dev.to/stefannieuwenhuis/merry-christmas-and-a-happy-new-year-pid</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fhappynewyear2020.club%2Fwp-content%2Fuploads%2F2019%2F08%2F5d0a296866161.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fhappynewyear2020.club%2Fwp-content%2Fuploads%2F2019%2F08%2F5d0a296866161.png" alt="Merry Christmas and a happy new year" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have a break from your work and spend time with your family and the ones you love. It's a holiday, so enjoy it to the fullest.&lt;/p&gt;

&lt;p&gt;With love,&lt;/p&gt;

&lt;p&gt;Stefan&lt;/p&gt;

</description>
      <category>webdev</category>
    </item>
    <item>
      <title>3 reasons why I went framework agnostic and why you should do that too</title>
      <dc:creator>Stefan Nieuwenhuis</dc:creator>
      <pubDate>Fri, 20 Dec 2019 10:06:25 +0000</pubDate>
      <link>https://dev.to/stefannieuwenhuis/3-reasons-why-i-went-framework-agnostic-and-why-you-should-do-that-too-2o37</link>
      <guid>https://dev.to/stefannieuwenhuis/3-reasons-why-i-went-framework-agnostic-and-why-you-should-do-that-too-2o37</guid>
      <description>&lt;p&gt;I’m a web developer since 2003 and I’ve seen lots of tech stacks come and go. Back then there was no such thing as a JavaScript framework and the language was not as advanced as it is today. It was even considered an inferior language, compared to Java and C (while it actually is a completely different thing). With the introduction of frameworks like React, Angular and VueJs JavaScript finally became mainstream and now the web depends on it.&lt;/p&gt;

&lt;p&gt;Today’s web is impossible to imagine without JavaScript frameworks. Building JavaScript applications with the help of a framework provide lot’s of advantages like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Save energy&lt;/strong&gt;. Modern JavaScript frameworks are packed with best practices, scaffolding tools, paradigms and industry standards which enables developers to set up an app in no time. It enables developers to focus on developing the actual app instead of the tools and the architecture required.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusable code&lt;/strong&gt;. Components build with a JavaScript framework are interchangeable, so teams don’t have to invent the square wheel twice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A common language for teams&lt;/strong&gt;. Using a JavaScript framework generates a common understanding between both front- and backend developers. Everyone speaks the same, common language.
It’s because of these benefits that almost all frontend development teams are using JavaScript frameworks to build apps.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzm8lou7npq3ed9dbcib0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzm8lou7npq3ed9dbcib0.png" alt="JavaScript Frameworks: Angular, React &amp;amp; Vue" width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The other side of the coin…
&lt;/h2&gt;

&lt;p&gt;In my time as a web developer, I’ve worked on numerous projects and a new project always starts with choosing a suitable JavaScript framework. What a perfect way to start a project! A framework will solve all of my problems and will save me a lot of time and energy! Other teammates and even other teams will completely understand the architecture and components I’ve built, Right?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1x6zo0furjlcc9t7jvc2.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1x6zo0furjlcc9t7jvc2.jpeg" alt="A JavaScript Framework will solve all my problems!" width="630" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me give you 3 real-world examples from companies I worked for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I used to work for an enterprise-size company where multiple frontend development teams worked on different parts of an app. All teams choose Angular as their preferred JavaScript framework. Together they’ve built a shared components library in Angular (v2) to save time, money and energy, but there was a catch. Angular (v4) came out and a few teams did an upgrade. The new version contains some breaking changes and the teams quickly realized that the shared components became useless. The idea of the shared components library was to save time, money and energy, but the opposite was actually the case. Teams have to invest extra time, money and energy in upgrading the shared components library; A waste and a source of frustration.&lt;/li&gt;
&lt;li&gt;Another project I worked on was for another enterprise company that has developed an app in AngularJs. It still works, but the responsible team has moved on and did other projects and so is their tech stack. They moved forward and switched to Angular as their preferred JavaScript framework. New team members are hired and aren’t expected to learn AngularJs anymore. But guess what? That application, built with AngularJs, which still is going strong needs a new feature to provide a better user experience to the customers.&lt;/li&gt;
&lt;li&gt;I worked for a company where multiple frontend development teams, with different tech stacks, worked on different parts of an app. The teams are known to be self-steering and very autonomous. A challenge for companies that want to provide a consistent user experience and look-and-feel to end-users. The big problem for the teams (and the company) is that components are unexchangeable between teams, which is hugely time-consuming and cost-inefficient.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The common theme running through these real-world examples is inefficiency and I bet that it happens in your company too.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fekaqfwpxzwr60doe8v5w.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fekaqfwpxzwr60doe8v5w.jpeg" alt="There are lots of challenges to face in Web Development" width="800" height="529"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The challenge as a company is to increase autonomy within teams and leave them free in the stack choices they make, but in the meantime, you also want to produce high-quality products without incurring too many costs.&lt;br&gt;
The challenge for development teams is not te be held back by legacy or tech stacks which doesn’t suit the way a team works. Developing must be fun for a team in order to produce high-quality apps.&lt;/p&gt;

&lt;p&gt;Companies where development teams building apps with modern JavaScript frameworks like Angular, React or VueJs will face the following challenges:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Migrating applications to other frameworks or even upgrading them is very time consuming, very costly and very frustrating&lt;/li&gt;
&lt;li&gt;Components can’t be exchanged between teams, resulting in reinventing the wheel several times which results in wasted time, money and energy.&lt;/li&gt;
&lt;li&gt;It’s very time consuming, hence a waste of money and energy, to provide a generic look and feel between different parts of an application developed by several teams with a different tech stack&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How to face those challenges?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Hello framework-agnostic web components!
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: If you’re not familiar with framework-agnostic web components, there is a very good introduction you can read &lt;a href="https://nhswd.com/blog/web-components-101-what-are-web-components" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmy349t56jnyixhhstkps.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmy349t56jnyixhhstkps.png" alt="Web Components" width="350" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Framework agnostic components libraries will provide a solution for the challenges described above. The idea of framework-agnostic components libraries is pretty simple but rather complex to do. Development teams are still able to choose a tech stack fit to their needs and develop their part of an app. In that way, the autonomy of teams is guaranteed and productivity will stay enhanced. At the same time, a company develops a framework independent components library, which components are interchangeable between development teams. The key to success is the interchangeability between teams and the agnostic character of components.&lt;/p&gt;

&lt;h2&gt;
  
  
  3 reasons why you should switch to framework-agnostic components libraries
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9w3t1wl5dmt6l0sc5fui.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9w3t1wl5dmt6l0sc5fui.png" alt="Using Web Components with different JavaScript Frameworks" width="571" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is why you should switch to framework-agnostic components libraries:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;No more legacy code. It’s very easy to migrate or upgrade your stack because all the components in the library are framework agnostic. Hence compatible with every tech stack.&lt;/li&gt;
&lt;li&gt;No more reinventing a square wheel over and over again. Components are compatible with every stack, so there is no need to build the same with different tech stacks. Just imagine how much time, money and frustration that will save!&lt;/li&gt;
&lt;li&gt;With generic components, it’s easy to provide a uniform look and feel to an application, built by several teams with different tech stacks.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Stefan helps developers to become Framework Agnostic. If you find his content helpful, you can buy him a coffee &lt;a href="https://www.buymeacoffee.com/stefannhs" rel="noopener noreferrer"&gt;here&lt;/a&gt; and get his exclusive e-book "10 reasons to go framework-agnostic" for free!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>angular</category>
      <category>react</category>
    </item>
    <item>
      <title>How to build a modal window with Stencil TDD style?</title>
      <dc:creator>Stefan Nieuwenhuis</dc:creator>
      <pubDate>Thu, 19 Dec 2019 11:03:59 +0000</pubDate>
      <link>https://dev.to/stefannieuwenhuis/how-to-build-a-modal-window-with-stencil-tdd-style-3mmb</link>
      <guid>https://dev.to/stefannieuwenhuis/how-to-build-a-modal-window-with-stencil-tdd-style-3mmb</guid>
      <description>&lt;p&gt;Allow me to show you how to build a modal window with Stencil.&lt;/p&gt;

&lt;p&gt;Coding with relatively new tools can be challenging due to the lack of (good) tutorials. Especially when you have a specific thing like a modal overlay in mind.&lt;/p&gt;

&lt;p&gt;So, that’s why I’ve decided to build my own modal overlay component with StencilJS and share my experiences and to write this tutorial to help you understand the possibilities of StencilJS.&lt;/p&gt;

&lt;p&gt;Check out &lt;a href="https://github.com/StefanNieuwenhuis/stenciljs-modal-overlay" rel="noopener noreferrer"&gt;this&lt;/a&gt; repo for the source.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Stencil?
&lt;/h2&gt;

&lt;p&gt;Stencil is a compiler that generates Web Components which combines the best concepts of the most popular frameworks into a simple build-time tool. It provides extra API's that makes writing fast components simpler. APIs like Virtual DOM, JSX, and async rendering make fast, powerful components easy to create, while still maintaining 100% compatibility with Web Components.&lt;/p&gt;

&lt;p&gt;The developer experience is also tuned and comes with life reload and a small dev server baked into the compiler.&lt;/p&gt;

&lt;p&gt;Stencil was created by the &lt;a href="http://ionicframework.com/" rel="noopener noreferrer"&gt;Ionic Framework&lt;/a&gt; team to help build faster, more capable components that worked across all major frameworks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s start building a Modal
&lt;/h2&gt;

&lt;p&gt;One common and frequently used UI component is a modal window, a content container that displays above the rest of the content and contains a clear call to action. It’s sometimes accompanied by an overlay that covers the rest of the web page or app. And that is what we’re going to build today!&lt;/p&gt;

&lt;h3&gt;
  
  
  Component design
&lt;/h3&gt;

&lt;p&gt;The name of our component is &lt;code&gt;my-component&lt;/code&gt;. This is the default name generated by the starter and for convenience and keeping this tutorial in scope, I’ve decided to let the name as is. You’re completely free to rename it at any time.&lt;/p&gt;

&lt;p&gt;It has the following attributes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Open&amp;lt;boolean&amp;gt;&lt;/code&gt;: Shows the modal window component;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Transparent&amp;lt;boolean&amp;gt;&lt;/code&gt;: Toggles transparency of the overlay;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The components has the following method:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;render&lt;/code&gt;: Renders content to the screen.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting up our application
&lt;/h2&gt;

&lt;p&gt;Before we can start building the component we have to set up a development environment, which is very easy with the starter, provided by our friends from Stencil.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: You need npm v6 or higher in order to complete this tutorial!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Stencil can be used to create standalone components or entire apps. Open a new terminal window and run the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm init stencil&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After running init you will be provided with a prompt so that you can choose the type of project to start.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnc08rgmzcs5bq1xwpb5w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnc08rgmzcs5bq1xwpb5w.png" alt="Screenshot of Stencil CLI" width="646" height="136"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since we’re building a single component, select the third option, which generates a development environment, installs all necessary dependencies and scaffolds the component’s code.&lt;/p&gt;

&lt;p&gt;The next step is to provide a name for the project. For this tutorial, it doesn’t really matter which name you pick. I wanted to be extremely original and named my project: &lt;code&gt;my-modal&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Stencil provides the developer with a very basic, hello world example to understand a bit better what’s going on and how an application is organized. It’s not in the tutorial’s scope to elaborate on this, but you can read more about this &lt;a href="https://stenciljs.com/docs/my-first-component" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Alright! We’re done setting up our application’s infrastructure!&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing our first tests
&lt;/h2&gt;

&lt;p&gt;Since we’re creating a component TDD style, let’s start off right away with writing our first tests.&lt;/p&gt;

&lt;p&gt;Stencil provides many utility functions to help test Jest and Puppeteer. For example, a component’s Shadow Dom can be queried and tested with the Stencil utility functions built on top of Puppeteer. Tests can not only be provided mock HTML content, but they can also go to URLs of your app which Puppeteer is able to open up and test on Stencil’s dev server.&lt;/p&gt;

&lt;p&gt;The starter generated a test file already (&lt;code&gt;./src/components/my-component/my-component.e2e.ts&lt;/code&gt;), which contains a few basic unit tests to get the gist on testing Web Components. Open this file, study it and replace it with the following content:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;What happened?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We import the necessary packages from the testing libraries provided in Stencil core.&lt;/li&gt;
&lt;li&gt;We create a my-component element and append it to the DOM. This is done in the beforeEach method, which is called before every unit test.&lt;/li&gt;
&lt;li&gt;We expect that my-component successfully renders in the DOM.&lt;/li&gt;
&lt;li&gt;We expect that we find a div decorated with a class, called overlay.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s run our tests with the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm run test&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;…Only to see that all of them fail. So let’s change that immediately!&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;./src/components/my-component/my-component.tsx&lt;/code&gt;, study the example code and replace it with the following:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Notice the following parts of the component:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;@Component&lt;/code&gt; decorator. This decorator provides metadata about our component to the compiler.&lt;/li&gt;
&lt;li&gt;You find a default &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes" rel="noopener noreferrer"&gt;ES6 JavaScript Class&lt;/a&gt; right under the decorator. This is where you’ll write the bulk of your code to bring the component to life.&lt;/li&gt;
&lt;li&gt;In the class you find the &lt;code&gt;render()&lt;/code&gt; function. This is used by the component to render content to the screen. It returns &lt;a href="http://buildwithreact.com/tutorial/jsx" rel="noopener noreferrer"&gt;JSX&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;In the HTML template, you find a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot" rel="noopener noreferrer"&gt;&lt;code&gt;&amp;lt;slot/&amp;gt;&lt;/code&gt;&lt;/a&gt; container, which is a placeholder inside a web component that you can fill with your own markup.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Learn more about Stencil components &lt;a href="https://stenciljs.com/docs/my-first-component/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If we run the tests again, they all pass. Hooray! Now it’s time to implement more logic and make our component actually useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Opening the modal window
&lt;/h2&gt;

&lt;p&gt;Before we start implementing the logic for opening the modal, let’s write some more tests.&lt;/p&gt;

&lt;p&gt;We want to cover the following cases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It should display the overlay while the modal is open.&lt;/li&gt;
&lt;li&gt;If set, the overlay should be transparent.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This results in the following test cases, which you need to add to the test file:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Whoah! What happened here?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We set different properties (&lt;code&gt;open&lt;/code&gt; &amp;amp; &lt;code&gt;transparent&lt;/code&gt;) with the &lt;code&gt;component.setProperty()&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;We wait for the changes made to the component with the &lt;code&gt;waitForChanges()&lt;/code&gt; method. Both Stencil and Puppeteer have an asynchronous architecture, which is a good thing for performance. Since all calls are async, it's required that &lt;code&gt;await page.waitForChanges()&lt;/code&gt; is called when changes are made to components.&lt;/li&gt;
&lt;li&gt;We check if the element is decorated with the expected CSS classes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Read more about testing Stencil components &lt;a href="https://stenciljs.com/docs/end-to-end-testing" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And, of course, if we run our tests they’ll fail miserably again, so let’s open the component’s code (&lt;code&gt;my-component.tsx&lt;/code&gt;) and make the tests pass.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;What did we do?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We’ve added properties &lt;code&gt;open&lt;/code&gt; &amp;amp; &lt;code&gt;transparent&lt;/code&gt;. They can be recognized by the &lt;code&gt;@Prop()&lt;/code&gt; decorator, a class that’s imported from &lt;code&gt;@stencil/core&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We’ve changed our class definition in the HTML template and check if we need to make the modal visible and make the overlay transparent.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Closing the modal window
&lt;/h2&gt;

&lt;p&gt;In order to close the modal, we need to set the &lt;code&gt;open&lt;/code&gt; property to &lt;code&gt;false&lt;/code&gt;. We’ll implement a method for that in our sample code later.&lt;/p&gt;

&lt;p&gt;Let’s write the tests necessary and make them pass:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;All tests are in green again and we have a fully operating modal, which looks terrible…&lt;/p&gt;

&lt;p&gt;Add the following styling classes to &lt;code&gt;./src/components/my-component/my-component.css&lt;/code&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Looks much better now!&lt;/p&gt;

&lt;h2&gt;
  
  
  The proof is in the pudding
&lt;/h2&gt;

&lt;p&gt;All that we’ve done is writing tests and make them pass by adding code to the component, but the real proof is to check if it actually works, so let’s update our &lt;code&gt;index.html&lt;/code&gt; file.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Here we create an instance of the component itself and decorate it with an id in order to be able to access it later on. We also added a button, which acts as a trigger to open the modal.&lt;/p&gt;

&lt;p&gt;In the script, we created two references. One for the modal component and one for the button. Next, we’ve created two events to test if opening and closing it works properly.&lt;/p&gt;

&lt;p&gt;Last, but not least, we added an &lt;code&gt;eventListener&lt;/code&gt; to the modal itself, which listens for a &lt;code&gt;click&lt;/code&gt; event. If it’s triggered, the modal will close.&lt;/p&gt;

&lt;h2&gt;
  
  
  It’s a wrap
&lt;/h2&gt;

&lt;p&gt;That’s it! There’s much room to improve this component, like extending the modal content container template with a header and footer, cancel/confirmation buttons, etc. etc. If you see any points for improvement or spot a mistake in my code, please please leave create a pull request or leave a message in the comments!&lt;/p&gt;

&lt;p&gt;Feel free to check out the code in &lt;a href="https://github.com/StefanNieuwenhuis/stenciljs-modal-overlay" rel="noopener noreferrer"&gt;this git repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Stefan helps developers to become Framework Agnostic. If you find his content helpful, you can buy him a coffee &lt;a href="https://www.buymeacoffee.com/stefannhs" rel="noopener noreferrer"&gt;here&lt;/a&gt; and get his exclusive e-book "10 reasons to go framework-agnostic" for free!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tdd</category>
      <category>webcomponents</category>
      <category>stenciljs</category>
    </item>
  </channel>
</rss>
