<?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: MD Zoheb</title>
    <description>The latest articles on DEV Community by MD Zoheb (@md_zoheb_8386785d6a92cfa2).</description>
    <link>https://dev.to/md_zoheb_8386785d6a92cfa2</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3933786%2F85097bec-507c-496f-a6bd-6b5b000818a3.png</url>
      <title>DEV Community: MD Zoheb</title>
      <link>https://dev.to/md_zoheb_8386785d6a92cfa2</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/md_zoheb_8386785d6a92cfa2"/>
    <language>en</language>
    <item>
      <title>Beyond 'eval()': How I Built a Step-by-Step Math Calculator That Explains Its Work with AI</title>
      <dc:creator>MD Zoheb</dc:creator>
      <pubDate>Fri, 04 Sep 2026 02:10:03 +0000</pubDate>
      <link>https://dev.to/md_zoheb_8386785d6a92cfa2/beyond-eval-how-i-built-a-step-by-step-math-calculator-that-explains-its-work-with-ai-27f7</link>
      <guid>https://dev.to/md_zoheb_8386785d6a92cfa2/beyond-eval-how-i-built-a-step-by-step-math-calculator-that-explains-its-work-with-ai-27f7</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%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7yielqs4h5opoyi4hzzt.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7yielqs4h5opoyi4hzzt.jpeg" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
Building a calculator that returns an answer takes little code.&lt;/p&gt;

&lt;p&gt;Building one that explains &lt;strong&gt;how it reached that answer&lt;/strong&gt; creates a different problem.&lt;/p&gt;

&lt;p&gt;Take this expression:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;12 + 6 × 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JavaScript can calculate the result with simple 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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&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="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// 30&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives the correct answer.&lt;/p&gt;

&lt;p&gt;It does not explain the work.&lt;/p&gt;

&lt;p&gt;A student may need to see this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;12 + 6 × 3

Step 1:
Multiply 6 by 3.

6 × 3 = 18

Step 2:
Add 12 and 18.

12 + 18 = 30

Final answer:
30
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That difference between &lt;strong&gt;calculating&lt;/strong&gt; and &lt;strong&gt;explaining&lt;/strong&gt; became the main challenge when I worked on a step-by-step math calculator.&lt;/p&gt;

&lt;p&gt;I wanted something that could handle more than basic arithmetic.&lt;/p&gt;

&lt;p&gt;The calculator needed to work with equations, fractions, algebra, percentages, calculus, word problems, and other math questions.&lt;/p&gt;

&lt;p&gt;I also wanted clean mathematical notation.&lt;/p&gt;

&lt;p&gt;That meant solving several separate problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;understand the user's input&lt;/li&gt;
&lt;li&gt;solve the problem&lt;/li&gt;
&lt;li&gt;produce useful steps&lt;/li&gt;
&lt;li&gt;format mathematical expressions&lt;/li&gt;
&lt;li&gt;render those expressions in the browser&lt;/li&gt;
&lt;li&gt;check the result where possible&lt;/li&gt;
&lt;li&gt;keep the API secure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I ended up using an AI model together with normal application code, LaTeX, and MathJax.&lt;/p&gt;

&lt;p&gt;The AI handles the flexible reasoning.&lt;/p&gt;

&lt;p&gt;LaTeX describes the math.&lt;/p&gt;

&lt;p&gt;MathJax turns the LaTeX into readable mathematical notation.&lt;/p&gt;

&lt;p&gt;JavaScript handles the interface and application logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why &lt;code&gt;eval()&lt;/code&gt; is not enough
&lt;/h2&gt;

&lt;p&gt;A basic JavaScript calculator often starts with something like this:&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;expression&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;12 + 6 * 3&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;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expression&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="nx"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are two problems with this approach.&lt;/p&gt;

&lt;p&gt;The first problem is security.&lt;/p&gt;

&lt;p&gt;Passing raw user input to &lt;code&gt;eval()&lt;/code&gt; can execute JavaScript. That makes it a poor choice for a public calculator.&lt;/p&gt;

&lt;p&gt;The second problem matters even more here.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;eval()&lt;/code&gt; gives me this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;30
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It does not give me this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;6 × 3 = 18
12 + 18 = 30
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It also cannot explain why multiplication happens before addition.&lt;/p&gt;

&lt;p&gt;The limitation becomes clearer with algebra.&lt;/p&gt;

&lt;p&gt;Consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2x + 5 = 17
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A useful result should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2x + 5 = 17

Subtract 5 from both sides.

2x = 12

Divide both sides by 2.

x = 6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JavaScript does not understand &lt;code&gt;2x + 5 = 17&lt;/code&gt; as a normal JavaScript expression.&lt;/p&gt;

&lt;p&gt;A step-by-step solver needs more than expression evaluation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hard-coding every possible solution gets messy
&lt;/h2&gt;

&lt;p&gt;One option would be to write custom solving logic for every type of math.&lt;/p&gt;

&lt;p&gt;I could start with addition.&lt;/p&gt;

&lt;p&gt;Then subtraction.&lt;/p&gt;

&lt;p&gt;Then multiplication.&lt;/p&gt;

&lt;p&gt;Then division.&lt;/p&gt;

&lt;p&gt;Then fractions.&lt;/p&gt;

&lt;p&gt;Then percentages.&lt;/p&gt;

&lt;p&gt;Then linear equations.&lt;/p&gt;

&lt;p&gt;Then quadratic equations.&lt;/p&gt;

&lt;p&gt;Then powers and roots.&lt;/p&gt;

&lt;p&gt;Then logarithms.&lt;/p&gt;

&lt;p&gt;Then derivatives.&lt;/p&gt;

&lt;p&gt;Then integrals.&lt;/p&gt;

&lt;p&gt;The amount of code would keep growing.&lt;/p&gt;

&lt;p&gt;Even one category contains many different forms.&lt;/p&gt;

&lt;p&gt;A linear equation might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2x + 5 = 17
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It might also look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;4(x - 2) = 20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3x + 7 = x + 19
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The steps change for each case.&lt;/p&gt;

&lt;p&gt;Word problems create another issue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A rectangle has a length of 12 cm and a width of 7 cm.
What is its area?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A normal expression parser first needs to understand the sentence.&lt;/p&gt;

&lt;p&gt;It then needs to identify the correct formula.&lt;/p&gt;

&lt;p&gt;Only after that can it calculate the answer.&lt;/p&gt;

&lt;p&gt;I did not want to create thousands of explanation rules by hand.&lt;/p&gt;

&lt;p&gt;That is where an AI model became useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where AI fits
&lt;/h2&gt;

&lt;p&gt;I do not treat the AI model as the whole application.&lt;/p&gt;

&lt;p&gt;It handles the part that benefits from flexible reasoning and language.&lt;/p&gt;

&lt;p&gt;The rest of the system still uses normal code.&lt;/p&gt;

&lt;p&gt;A simplified flow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User enters a problem
        ↓
Application processes the input
        ↓
Solver receives the problem
        ↓
AI works through the solution
        ↓
AI returns structured output
        ↓
Application checks the response
        ↓
MathJax formats the math
        ↓
Steps appear in the browser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model can understand different forms of math without requiring one hard-coded path for every possible question.&lt;/p&gt;

&lt;p&gt;That does not mean the model gets full control.&lt;/p&gt;

&lt;p&gt;The application still decides how the response should look and how it should reach the screen.&lt;/p&gt;

&lt;h2&gt;
  
  
  I ask for structured output
&lt;/h2&gt;

&lt;p&gt;I do not want the model to return a random block of text.&lt;/p&gt;

&lt;p&gt;A response like this is difficult to control:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Okay! Let's solve this problem. First we need to...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The wording may change on every request.&lt;/p&gt;

&lt;p&gt;The frontend also has to guess where one step ends and another begins.&lt;/p&gt;

&lt;p&gt;Structured output works better.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"finalAnswer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;(x = 6&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"steps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"explanation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Start with the equation."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"math"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;[2x + 5 = 17&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;]"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"explanation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Subtract 5 from both sides."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"math"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;[2x = 12&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;]"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"explanation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Divide both sides by 2."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"math"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;[x = 6&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;]"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the roles stay clear.&lt;/p&gt;

&lt;p&gt;The AI produces the solution data.&lt;/p&gt;

&lt;p&gt;The application controls the interface.&lt;/p&gt;

&lt;p&gt;This gives me much more predictable output.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I use LaTeX
&lt;/h2&gt;

&lt;p&gt;Getting the correct steps from AI solves only part of the problem.&lt;/p&gt;

&lt;p&gt;Math can look bad in plain text.&lt;/p&gt;

&lt;p&gt;Take the quadratic formula.&lt;/p&gt;

&lt;p&gt;The AI could return:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x = (-b +- sqrt(b^2 - 4ac)) / 2a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A human can understand it.&lt;/p&gt;

&lt;p&gt;It does not look like proper mathematical notation.&lt;/p&gt;

&lt;p&gt;LaTeX gives the model a standard way to describe the expression.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tex"&gt;&lt;code&gt;x = &lt;span class="k"&gt;\frac&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;-b &lt;span class="k"&gt;\pm&lt;/span&gt; &lt;span class="k"&gt;\sqrt&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;b&lt;span class="p"&gt;^&lt;/span&gt;2 - 4ac&lt;span class="p"&gt;}}{&lt;/span&gt;2a&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same approach works for fractions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tex"&gt;&lt;code&gt;&lt;span class="k"&gt;\frac&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;3x + 2&lt;span class="p"&gt;}{&lt;/span&gt;x - 5&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Square roots:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tex"&gt;&lt;code&gt;&lt;span class="k"&gt;\sqrt&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;x&lt;span class="p"&gt;^&lt;/span&gt;2 + 9&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Powers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tex"&gt;&lt;code&gt;x&lt;span class="p"&gt;^{&lt;/span&gt;12&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Integrals:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tex"&gt;&lt;code&gt;&lt;span class="k"&gt;\int&lt;/span&gt;&lt;span class="p"&gt;_&lt;/span&gt;0&lt;span class="p"&gt;^&lt;/span&gt;5 x&lt;span class="p"&gt;^&lt;/span&gt;2 &lt;span class="k"&gt;\,&lt;/span&gt; dx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Matrices:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tex"&gt;&lt;code&gt;&lt;span class="nt"&gt;\begin{bmatrix}&lt;/span&gt;
1 &lt;span class="p"&gt;&amp;amp;&lt;/span&gt; 2 &lt;span class="k"&gt;\\&lt;/span&gt;
3 &lt;span class="p"&gt;&amp;amp;&lt;/span&gt; 4
&lt;span class="nt"&gt;\end{bmatrix}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LaTeX gives the application one consistent format for mathematical expressions.&lt;/p&gt;

&lt;p&gt;The AI does not need to invent a different visual style for every problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI gives me LaTeX. MathJax makes it readable.
&lt;/h2&gt;

&lt;p&gt;LaTeX is still text.&lt;/p&gt;

&lt;p&gt;A browser does not automatically turn this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\[\frac{x+2}{3}=7\]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;into a properly formatted equation.&lt;/p&gt;

&lt;p&gt;That is where MathJax comes in.&lt;/p&gt;

&lt;p&gt;The full flow looks more like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Input
    ↓
Input Processing
    ↓
Solver Router
    ↓
AI or Local Math Engine
    ↓
Validation
    ↓
Structured JSON
    ↓
LaTeX Expressions
    ↓
MathJax
    ↓
Step-by-Step Interface
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI decides what the solution should contain.&lt;/p&gt;

&lt;p&gt;LaTeX describes the mathematical notation.&lt;/p&gt;

&lt;p&gt;MathJax renders that notation inside the page.&lt;/p&gt;

&lt;p&gt;Each part has one clear job.&lt;/p&gt;

&lt;h2&gt;
  
  
  I tell the model exactly how to format math
&lt;/h2&gt;

&lt;p&gt;The prompt matters a lot.&lt;/p&gt;

&lt;p&gt;I do not send only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Solve this:
2x + 5 = 17
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives the model too much freedom.&lt;/p&gt;

&lt;p&gt;I define the expected output.&lt;/p&gt;

&lt;p&gt;A simplified prompt might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Solve the math problem step by step.

Keep each explanation short.

Do not skip important operations.

Return mathematical expressions as LaTeX.

Use \( ... \) for inline math.

Use \[ ... \] for equations that should appear on their own line.

Do not return HTML.

Do not place LaTeX inside Markdown code blocks.

Return valid JSON.

Use this structure:

{
  "finalAnswer": "",
  "steps": [
    {
      "explanation": "",
      "math": ""
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I can also add instructions for specific types of problems.&lt;/p&gt;

&lt;p&gt;For algebra:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Show what operation happens to both sides of the equation.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For fractions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Show the common denominator when one is required.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For calculus:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;State the rule used before applying it.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The prompt does not need to teach mathematics from scratch.&lt;/p&gt;

&lt;p&gt;The model already handles the reasoning.&lt;/p&gt;

&lt;p&gt;The prompt defines how I want the result delivered.&lt;/p&gt;

&lt;h2&gt;
  
  
  JSON escaping matters with LaTeX
&lt;/h2&gt;

&lt;p&gt;There is one small detail that can cause confusing bugs.&lt;/p&gt;

&lt;p&gt;LaTeX uses backslashes.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tex"&gt;&lt;code&gt;&lt;span class="k"&gt;\frac&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;3&lt;span class="p"&gt;}{&lt;/span&gt;4&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JSON strings also use backslashes for escaping.&lt;/p&gt;

&lt;p&gt;That means serialized JSON may contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"math"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;[&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;frac{3}{4}&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;]"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The double backslashes are normal.&lt;/p&gt;

&lt;p&gt;After JavaScript parses the JSON, the string becomes the LaTeX expression that MathJax needs.&lt;/p&gt;

&lt;p&gt;This matters for commands such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\frac
\sqrt
\times
\div
\int
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Incorrect escaping can break otherwise valid AI output.&lt;/p&gt;

&lt;h2&gt;
  
  
  Loading MathJax
&lt;/h2&gt;

&lt;p&gt;A page can load MathJax from a content delivery network.&lt;/p&gt;

&lt;p&gt;A simple setup can look 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;script&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MathJax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;tex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;inlineMath&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="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s1"&gt;(&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="se"&gt;\\&lt;/span&gt;&lt;span class="s1"&gt;)&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="na"&gt;displayMath&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="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s1"&gt;[&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="se"&gt;\\&lt;/span&gt;&lt;span class="s1"&gt;]&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="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script
  &lt;/span&gt;&lt;span class="na"&gt;defer&lt;/span&gt;
  &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/mathjax@4/tex-svg.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I prefer explicit delimiters.&lt;/p&gt;

&lt;p&gt;Inline math uses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\( x = 6 \)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Display math uses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\[ x = 6 \]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This also avoids depending only on dollar signs.&lt;/p&gt;

&lt;p&gt;Dollar signs can appear in normal text.&lt;/p&gt;

&lt;p&gt;Take this question:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A $50 product gets a 20% discount.
What is the new price?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using &lt;code&gt;$...$&lt;/code&gt; as the only delimiter can create problems when the input contains currency.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;\(...\)&lt;/code&gt; and &lt;code&gt;\[...\]&lt;/code&gt; delimiters make the boundary much clearer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dynamic AI output needs another MathJax step
&lt;/h2&gt;

&lt;p&gt;This part matters in an AI calculator.&lt;/p&gt;

&lt;p&gt;MathJax can process equations that already exist when the page loads.&lt;/p&gt;

&lt;p&gt;AI responses arrive later.&lt;/p&gt;

&lt;p&gt;The user enters a problem.&lt;/p&gt;

&lt;p&gt;JavaScript sends a request.&lt;/p&gt;

&lt;p&gt;The server returns the solution.&lt;/p&gt;

&lt;p&gt;JavaScript then adds those new steps to the page.&lt;/p&gt;

&lt;p&gt;MathJax needs to process that new content.&lt;/p&gt;

&lt;p&gt;A simplified renderer could look like this:&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;renderSolution&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;solution&lt;/span&gt;&lt;span class="p"&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;container&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;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#solution&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replaceChildren&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;solution&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;section&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="s2"&gt;section&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;heading&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="s2"&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;heading&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="s2"&gt;`Step &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&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;explanation&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="s2"&gt;p&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;explanation&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="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;explanation&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;math&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="s2"&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;math&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="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;math&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;section&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;heading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;explanation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;math&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;container&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;section&lt;/span&gt;&lt;span class="p"&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;finalAnswer&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="s2"&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;finalAnswer&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="s2"&gt;`Final answer: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;solution&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;finalAnswer&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;container&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;finalAnswer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;MathJax&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;typesetPromise&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;container&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 important part is:&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;MathJax&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;typesetPromise&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI response already exists inside the container at that point.&lt;/p&gt;

&lt;p&gt;MathJax scans it and finds the LaTeX delimiters.&lt;/p&gt;

&lt;p&gt;It then renders the equations.&lt;/p&gt;

&lt;p&gt;Without that final step, users would see raw strings such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\[\frac{3}{4} + \frac{1}{2}\]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of properly formatted math.&lt;/p&gt;

&lt;h2&gt;
  
  
  I keep text and equations separate
&lt;/h2&gt;

&lt;p&gt;I prefer this structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"explanation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Subtract 5 from both sides."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"math"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;[2x = 12&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;]"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"step"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Subtract 5 from both sides so &lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;(2x = 12&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keeping them separate gives the frontend more control.&lt;/p&gt;

&lt;p&gt;The explanation can use normal paragraph styling.&lt;/p&gt;

&lt;p&gt;The equation can have more space around it.&lt;/p&gt;

&lt;p&gt;MathJax only needs to handle the mathematical part.&lt;/p&gt;

&lt;p&gt;The layout also becomes easier to adapt for phones.&lt;/p&gt;

&lt;h2&gt;
  
  
  I do not ask the AI to generate HTML
&lt;/h2&gt;

&lt;p&gt;It might seem easier to ask the model for 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;p&amp;gt;&lt;/span&gt;Subtract 5 from both sides.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;2x = 12&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;I avoid that approach.&lt;/p&gt;

&lt;p&gt;The model should return data.&lt;/p&gt;

&lt;p&gt;The application should create the markup.&lt;/p&gt;

&lt;p&gt;I prefer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"explanation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Subtract 5 from both sides."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"math"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;[2x = 12&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;]"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then JavaScript creates the elements.&lt;/p&gt;

&lt;p&gt;This keeps the application structure predictable.&lt;/p&gt;

&lt;p&gt;It also gives the model less control over the page.&lt;/p&gt;

&lt;p&gt;I would avoid doing this with raw model output:&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="nx"&gt;container&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="nx"&gt;modelResponse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AI output should count as untrusted input.&lt;/p&gt;

&lt;p&gt;Creating elements and using &lt;code&gt;textContent&lt;/code&gt; gives the application much more control.&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="nx"&gt;explanation&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="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;explanation&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;math&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="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;math&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MathJax can process the mathematical string after JavaScript adds it to the document.&lt;/p&gt;

&lt;p&gt;The model controls the equation.&lt;/p&gt;

&lt;p&gt;It does not control the page markup.&lt;/p&gt;

&lt;h2&gt;
  
  
  The browser should not contain the AI API key
&lt;/h2&gt;

&lt;p&gt;An AI-powered calculator needs access to an AI service.&lt;/p&gt;

&lt;p&gt;That usually means an API key.&lt;/p&gt;

&lt;p&gt;The key should stay on the server.&lt;/p&gt;

&lt;p&gt;It should not appear inside public browser JavaScript.&lt;/p&gt;

&lt;p&gt;This is unsafe:&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;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my-secret-api-key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Anyone can inspect the page source or network activity.&lt;/p&gt;

&lt;p&gt;Instead, the browser sends the problem to an endpoint on my own server.&lt;/p&gt;

&lt;p&gt;A simplified example looks like this:&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;solveProblem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;problem&lt;/span&gt;&lt;span class="p"&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/solve&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="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-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="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="nx"&gt;problem&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Unable to solve the problem&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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 server talks to the AI provider.&lt;/p&gt;

&lt;p&gt;The browser never receives the secret key.&lt;/p&gt;

&lt;p&gt;The server can also apply rate limits and input limits before spending money on a model request.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI still needs verification
&lt;/h2&gt;

&lt;p&gt;AI gives the calculator flexibility.&lt;/p&gt;

&lt;p&gt;It does not guarantee perfection.&lt;/p&gt;

&lt;p&gt;A language model can make calculation mistakes.&lt;/p&gt;

&lt;p&gt;It can miss a negative sign.&lt;/p&gt;

&lt;p&gt;It can misunderstand ambiguous input.&lt;/p&gt;

&lt;p&gt;It can also give a clean explanation for an incorrect answer.&lt;/p&gt;

&lt;p&gt;That means the application should verify whatever it can.&lt;/p&gt;

&lt;p&gt;Take:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2x + 5 = 17
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suppose the model returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x = 6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application can substitute &lt;code&gt;6&lt;/code&gt; back into the equation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2(6) + 5 = 17

12 + 5 = 17

17 = 17
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives another signal that the answer works.&lt;/p&gt;

&lt;p&gt;Basic arithmetic can use deterministic code for checks.&lt;/p&gt;

&lt;p&gt;A simple comparison might look like this:&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;function&lt;/span&gt; &lt;span class="nf"&gt;verifyBasicArithmetic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;modelAnswer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;modelAnswer&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;More advanced problems need more advanced verification.&lt;/p&gt;

&lt;p&gt;The main idea stays simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use AI for explanation and flexible reasoning. Verify with deterministic tools where possible.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A hybrid system makes more sense
&lt;/h2&gt;

&lt;p&gt;AI does not need to calculate everything.&lt;/p&gt;

&lt;p&gt;Take:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;25 × 8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JavaScript can solve that perfectly well.&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;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sending every basic multiplication problem to an AI model adds cost and latency without much benefit.&lt;/p&gt;

&lt;p&gt;A calculator can route different problems to different systems.&lt;/p&gt;

&lt;p&gt;A simplified version might look like this:&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;function&lt;/span&gt; &lt;span class="nf"&gt;chooseSolver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;problem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isBasicArithmetic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;problem&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;local&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="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ai&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;Simple arithmetic can use local code.&lt;/p&gt;

&lt;p&gt;More complex questions can use the AI layer.&lt;/p&gt;

&lt;p&gt;A larger system could also use dedicated math libraries for symbolic work.&lt;/p&gt;

&lt;p&gt;Different tools can handle different jobs.&lt;/p&gt;

&lt;p&gt;There is no good reason to force every problem through one solver.&lt;/p&gt;

&lt;h2&gt;
  
  
  Word problems show where AI helps
&lt;/h2&gt;

&lt;p&gt;Natural-language math questions create a good use case for AI.&lt;/p&gt;

&lt;p&gt;Take this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A train travels 240 kilometers in 3 hours.
What is its average speed?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A traditional calculator first needs to extract:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;distance = 240 km
time = 3 hours
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then it needs to identify the formula:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;speed = distance ÷ time
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then it calculates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;240 ÷ 3 = 80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An AI model can understand the sentence and produce those steps together.&lt;/p&gt;

&lt;p&gt;A structured response might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"finalAnswer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;(80&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;text{ km/h}&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"steps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"explanation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Use the average speed formula."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"math"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;[&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;text{speed} = &lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;frac{&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;text{distance}}{&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;text{time}}&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;]"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"explanation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Insert the values."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"math"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;[&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;text{speed} = &lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;frac{240}{3}&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;]"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"explanation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Calculate the result."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"math"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;[&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;text{speed} = 80&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;text{ km/h}&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;]"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MathJax can then turn those LaTeX strings into readable equations.&lt;/p&gt;

&lt;p&gt;This moves the project beyond a &lt;a href="https://dev.to/sudo-self/calculator-2n3f"&gt;normal calculator&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The system now has to understand what the user means before solving the calculation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Users do not always type clean math
&lt;/h2&gt;

&lt;p&gt;People enter the same problem in different ways.&lt;/p&gt;

&lt;p&gt;One person may type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sqrt 144
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another may type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;square root of 144
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another may use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;√144
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All three mean the same thing.&lt;/p&gt;

&lt;p&gt;Input processing can clean some common formatting before sending the request to a solver.&lt;/p&gt;

&lt;p&gt;A basic example looks like this:&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;function&lt;/span&gt; &lt;span class="nf"&gt;normalizeInput&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="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&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;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &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;Real math normalization needs more care.&lt;/p&gt;

&lt;p&gt;Changing mathematical input too aggressively can change its meaning.&lt;/p&gt;

&lt;p&gt;I prefer conservative cleanup and let the solver interpret the actual expression.&lt;/p&gt;

&lt;h2&gt;
  
  
  Invalid problems need a clear error path
&lt;/h2&gt;

&lt;p&gt;A solver should not invent an answer when the input does not make sense.&lt;/p&gt;

&lt;p&gt;Take:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;5 + × 9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application should return a clear error.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"I could not read this expression clearly."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That works better than showing a confident but unreliable result.&lt;/p&gt;

&lt;p&gt;The same rule applies when the AI response does not match the expected JSON structure.&lt;/p&gt;

&lt;p&gt;The application should reject malformed output instead of trying to guess what the model meant.&lt;/p&gt;

&lt;h2&gt;
  
  
  Public AI tools also need limits
&lt;/h2&gt;

&lt;p&gt;A public calculator needs request limits.&lt;/p&gt;

&lt;p&gt;Without them, someone could submit a huge block of unrelated text.&lt;/p&gt;

&lt;p&gt;Empty input should fail before reaching the model.&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;problem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enter a math problem first.&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;Long input can also have a limit.&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;problem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;MAX_PROBLEM_LENGTH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The problem is too long.&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 output can have limits too.&lt;/p&gt;

&lt;p&gt;A solution with 40 tiny steps often makes the problem harder to follow.&lt;/p&gt;

&lt;p&gt;The goal is not to generate the longest explanation.&lt;/p&gt;

&lt;p&gt;The goal is to show enough work for someone to understand the calculation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The interface still matters
&lt;/h2&gt;

&lt;p&gt;A correct answer can still feel difficult to use.&lt;/p&gt;

&lt;p&gt;I wanted the solution to have a clear order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Problem
↓
Final Answer
↓
Step-by-Step Work
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each equation needs enough room.&lt;/p&gt;

&lt;p&gt;The explanation should stay short.&lt;/p&gt;

&lt;p&gt;Important operations should stand out.&lt;/p&gt;

&lt;p&gt;Complex fractions and equations should remain readable on smaller screens.&lt;/p&gt;

&lt;p&gt;The user should also be able to enter another problem without reloading the entire page.&lt;/p&gt;

&lt;p&gt;The AI model handles the reasoning.&lt;/p&gt;

&lt;p&gt;MathJax handles the notation.&lt;/p&gt;

&lt;p&gt;The interface still decides whether the final experience feels easy to follow.&lt;/p&gt;

&lt;h2&gt;
  
  
  A live version
&lt;/h2&gt;

&lt;p&gt;I built a working version around these ideas.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;&lt;a href="https://math.techgrapple.com/" rel="noopener noreferrer"&gt;Step by Step Math Calculator&lt;/a&gt;&lt;/strong&gt; uses AI to help solve different types of math questions and explain the work behind the answer.&lt;/p&gt;

&lt;p&gt;The important part for me was not just showing a result.&lt;/p&gt;

&lt;p&gt;I wanted the calculator to turn the solution into readable steps and properly formatted mathematical expressions.&lt;/p&gt;

&lt;p&gt;That required much more than sending a prompt to an AI model.&lt;/p&gt;

&lt;h2&gt;
  
  
  The architecture I would use again
&lt;/h2&gt;

&lt;p&gt;The main pieces now look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌───────────────────────────┐
│        User Input         │
└─────────────┬─────────────┘
              │
              ▼
┌───────────────────────────┐
│      Input Processing     │
└─────────────┬─────────────┘
              │
              ▼
┌───────────────────────────┐
│       Solver Router       │
└────────┬───────────┬──────┘
         │           │
         ▼           ▼
┌──────────────┐ ┌──────────────┐
│  Local Math  │ │   AI Model   │
└───────┬──────┘ └───────┬──────┘
        │                │
        └────────┬───────┘
                 │
                 ▼
┌───────────────────────────┐
│       Verification        │
└─────────────┬─────────────┘
              │
              ▼
┌───────────────────────────┐
│      Structured JSON      │
└─────────────┬─────────────┘
              │
              ▼
┌───────────────────────────┐
│       LaTeX Output        │
└─────────────┬─────────────┘
              │
              ▼
┌───────────────────────────┐
│          MathJax          │
└─────────────┬─────────────┘
              │
              ▼
┌───────────────────────────┐
│    Step-by-Step Result    │
└───────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This separation also makes the project easier to change.&lt;/p&gt;

&lt;p&gt;A different AI model can replace the current one.&lt;/p&gt;

&lt;p&gt;A stronger math engine can handle more deterministic calculations.&lt;/p&gt;

&lt;p&gt;The frontend does not need to know how every solver works.&lt;/p&gt;

&lt;p&gt;MathJax only needs valid LaTeX.&lt;/p&gt;

&lt;p&gt;Each layer can change without rebuilding the whole project.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part I underestimated
&lt;/h2&gt;

&lt;p&gt;At first, the obvious challenge looked like solving the math.&lt;/p&gt;

&lt;p&gt;That turned out to be only one part.&lt;/p&gt;

&lt;p&gt;The harder product problem involved moving from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;input → answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;input
  ↓
understand
  ↓
solve
  ↓
verify
  ↓
explain
  ↓
format
  ↓
render
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AI helps with understanding and explaining.&lt;/p&gt;

&lt;p&gt;Normal code handles security and application logic.&lt;/p&gt;

&lt;p&gt;Deterministic math can verify some results.&lt;/p&gt;

&lt;p&gt;LaTeX provides a standard format for mathematical expressions.&lt;/p&gt;

&lt;p&gt;MathJax makes those expressions readable inside the browser.&lt;/p&gt;

&lt;p&gt;That combination works much better than asking one tool to handle everything.&lt;/p&gt;

&lt;p&gt;I do not need an AI model to tell me that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2 + 2 = 4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The interesting cases look more like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A shop reduces a $120 item by 15%.
Sales tax of 5% applies after the discount.
What is the final price?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The calculator has to understand the order of operations in the real-world problem.&lt;/p&gt;

&lt;p&gt;It needs to perform the calculations.&lt;/p&gt;

&lt;p&gt;It needs to explain each step.&lt;/p&gt;

&lt;p&gt;It needs to format percentages and equations.&lt;/p&gt;

&lt;p&gt;It needs to display the result clearly.&lt;/p&gt;

&lt;p&gt;That is where a &lt;a href="https://math.techgrapple.com/" rel="noopener noreferrer"&gt;step-by-step calculator&lt;/a&gt; becomes much more interesting than &lt;code&gt;eval()&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>ai</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Choose the Right Image Format for Web Performance</title>
      <dc:creator>MD Zoheb</dc:creator>
      <pubDate>Sat, 16 May 2026 12:36:49 +0000</pubDate>
      <link>https://dev.to/md_zoheb_8386785d6a92cfa2/how-to-choose-the-right-image-format-for-web-performance-1je9</link>
      <guid>https://dev.to/md_zoheb_8386785d6a92cfa2/how-to-choose-the-right-image-format-for-web-performance-1je9</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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwuzxomkoqgq3u90j195h.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%2Fwuzxomkoqgq3u90j195h.jpeg" alt="Browser Image Support" width="800" height="534"&gt;&lt;/a&gt;&lt;br&gt;
Images can make a website feel rich, clear, and professional. They can also make it slow, heavy, and frustrating if the wrong format is used. Many website owners upload images without thinking about file type. A photo becomes PNG. A logo becomes JPG. A large hero image stays uncompressed. Then the page loads slowly, mobile users leave, and performance scores drop.&lt;/p&gt;

&lt;p&gt;Choosing the right image format is not just a design decision. It directly affects loading speed, bandwidth, SEO, Core Web Vitals, and user experience. A good image format keeps the visual quality high while reducing the file size as much as possible.&lt;/p&gt;

&lt;p&gt;The good news is that the basic rules are not complicated. Once you understand when to use JPG, PNG, WebP, SVG, and newer formats like AVIF, it becomes much easier to prepare images correctly for the web.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Image Format Matters for Website Speed
&lt;/h2&gt;

&lt;p&gt;Every image on a page has a size. The browser has to download that image before the user can fully see it. If the image is large, the page takes longer to load. This is especially noticeable on mobile networks, slower connections, or pages with many images.&lt;/p&gt;

&lt;p&gt;A single image can sometimes be larger than all the HTML, CSS, and JavaScript on a page combined. That is why image optimization is one of the easiest ways to improve web performance. The &lt;a href="https://web.dev/learn/performance/image-performance" rel="noopener noreferrer"&gt;web.dev image optimization guide&lt;/a&gt; also explains how image size, dimensions, compression, and delivery can affect loading performance.&lt;/p&gt;

&lt;p&gt;The image format affects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;File size&lt;/li&gt;
&lt;li&gt;Visual quality&lt;/li&gt;
&lt;li&gt;Transparency support&lt;/li&gt;
&lt;li&gt;Animation support&lt;/li&gt;
&lt;li&gt;Browser compatibility&lt;/li&gt;
&lt;li&gt;Sharpness on different screens&lt;/li&gt;
&lt;li&gt;Loading time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using the wrong format does not always break the page, but it often wastes data. For example, saving a simple logo as a large JPG may make the edges blurry. Saving a large photo as PNG may create a much heavier file than needed. Using WebP for photos and graphics can often reduce file size while keeping the image looking clean.&lt;/p&gt;

&lt;h2&gt;
  
  
  JPG: Best for Photos and Real-Life Images
&lt;/h2&gt;

&lt;p&gt;JPG, also written as JPEG, is one of the most common image formats on the web. It works well for photographs, product images, backgrounds, travel pictures, food photos, and other images with many colors and soft details.&lt;/p&gt;

&lt;p&gt;JPG uses lossy compression. That means it reduces file size by removing some image data. When done carefully, the difference is hard to notice. But if the image is compressed too much, it can look blurry, noisy, or blocky.&lt;/p&gt;

&lt;p&gt;JPG is a good choice for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Photos&lt;/li&gt;
&lt;li&gt;Blog images&lt;/li&gt;
&lt;li&gt;Product photos&lt;/li&gt;
&lt;li&gt;Large background images&lt;/li&gt;
&lt;li&gt;Real-world pictures with many colors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;JPG is not the best choice for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logos&lt;/li&gt;
&lt;li&gt;Icons&lt;/li&gt;
&lt;li&gt;Text-heavy images&lt;/li&gt;
&lt;li&gt;Screenshots with sharp edges&lt;/li&gt;
&lt;li&gt;Images that need transparency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A common mistake is uploading a huge JPG directly from a camera or design tool. These images can be several megabytes. Before using them on a website, resize them to the actual display size and compress them properly.&lt;/p&gt;

&lt;h2&gt;
  
  
  PNG: Best for Transparency and Sharp Graphics
&lt;/h2&gt;

&lt;p&gt;PNG is another popular format. It is often used for graphics that need clean edges or transparent backgrounds. Unlike JPG, PNG can preserve sharp lines and text very well. It also supports transparency, which makes it useful for logos, icons, stickers, UI elements, and images placed over colored backgrounds.&lt;/p&gt;

&lt;p&gt;PNG usually creates larger files than JPG when used for photos. That is why PNG should not be your default choice for every image.&lt;/p&gt;

&lt;p&gt;PNG is a good choice for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logos&lt;/li&gt;
&lt;li&gt;Icons&lt;/li&gt;
&lt;li&gt;Screenshots&lt;/li&gt;
&lt;li&gt;Transparent images&lt;/li&gt;
&lt;li&gt;Simple graphics&lt;/li&gt;
&lt;li&gt;Images with text&lt;/li&gt;
&lt;li&gt;UI elements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PNG is not ideal for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large photos&lt;/li&gt;
&lt;li&gt;Full-width hero images&lt;/li&gt;
&lt;li&gt;Photo galleries&lt;/li&gt;
&lt;li&gt;Blog images with real-life scenes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, if you have a screenshot of a software interface, PNG may keep the text sharp. But if you have a photo of a beach, JPG or WebP will usually be better.&lt;/p&gt;

&lt;h2&gt;
  
  
  WebP: A Strong Default for Modern Websites
&lt;/h2&gt;

&lt;p&gt;WebP is one of the best image formats for modern web performance. It can handle both photos and graphics, supports transparency, and usually produces smaller files than JPG or PNG.&lt;/p&gt;

&lt;p&gt;This makes WebP very useful for websites that want fast loading without losing too much visual quality. Many images that were once uploaded as JPG or PNG can be converted to WebP to reduce page weight.&lt;/p&gt;

&lt;p&gt;WebP is useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blog images&lt;/li&gt;
&lt;li&gt;Thumbnails&lt;/li&gt;
&lt;li&gt;Product images&lt;/li&gt;
&lt;li&gt;Hero images&lt;/li&gt;
&lt;li&gt;Transparent graphics&lt;/li&gt;
&lt;li&gt;Website banners&lt;/li&gt;
&lt;li&gt;Image-heavy pages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For many websites, WebP is a smart default format. You can keep original JPG or PNG files for editing and storage, then use WebP versions on the live website. If you already have JPG or PNG images, you can use a simple tool to &lt;a href="https://docs.techgrapple.com/jpg-png-to-webp" rel="noopener noreferrer"&gt;convert JPG or PNG to WebP&lt;/a&gt; before uploading them to your site.&lt;/p&gt;

&lt;p&gt;That small step can make a page feel faster, especially when there are many images.&lt;/p&gt;

&lt;h2&gt;
  
  
  SVG: Best for Logos, Icons, and Simple Illustrations
&lt;/h2&gt;

&lt;p&gt;SVG is different from JPG, PNG, and WebP. It is a vector format. Instead of storing image pixels, it stores shapes, paths, and instructions. This means SVG can scale to any size without becoming blurry.&lt;/p&gt;

&lt;p&gt;SVG is excellent for simple graphics. It is often the best choice for logos, icons, arrows, line illustrations, badges, and interface graphics.&lt;/p&gt;

&lt;p&gt;SVG is good for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logos&lt;/li&gt;
&lt;li&gt;Icons&lt;/li&gt;
&lt;li&gt;Simple illustrations&lt;/li&gt;
&lt;li&gt;Decorative shapes&lt;/li&gt;
&lt;li&gt;UI graphics&lt;/li&gt;
&lt;li&gt;Graphics that need to stay sharp at all sizes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SVG is not the best choice for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Photos&lt;/li&gt;
&lt;li&gt;Complex artwork with many colors&lt;/li&gt;
&lt;li&gt;Large detailed images&lt;/li&gt;
&lt;li&gt;Images from cameras&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One big advantage of SVG is that it often stays very small in file size for simple designs. A logo that looks blurry as JPG may look perfectly sharp as SVG.&lt;/p&gt;

&lt;p&gt;However, SVG should be used carefully. Since SVG files can contain code-like data, only upload SVGs from trusted sources or sanitize them before using them on a public website.&lt;/p&gt;

&lt;h2&gt;
  
  
  AVIF: Very Small Files, But Use Carefully
&lt;/h2&gt;

&lt;p&gt;AVIF is a newer image format that can produce very small files with good quality. It can be excellent for web performance, especially for photos and large visual images.&lt;/p&gt;

&lt;p&gt;In many cases, AVIF can be smaller than WebP. But it is not always the easiest format to use. Encoding can take longer, some workflows do not support it smoothly, and older systems may have issues with it.&lt;/p&gt;

&lt;p&gt;AVIF is good for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large photos&lt;/li&gt;
&lt;li&gt;Hero images&lt;/li&gt;
&lt;li&gt;High-performance websites&lt;/li&gt;
&lt;li&gt;Image-heavy pages&lt;/li&gt;
&lt;li&gt;Sites with a modern optimization workflow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AVIF may not be ideal when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need the simplest workflow&lt;/li&gt;
&lt;li&gt;Your CMS does not handle it well&lt;/li&gt;
&lt;li&gt;You want easy editing and broad tool support&lt;/li&gt;
&lt;li&gt;You do not have fallback images&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good approach is to use AVIF where it gives a clear size benefit, but still keep WebP or JPG fallback options when needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  GIF: Use Only When Necessary
&lt;/h2&gt;

&lt;p&gt;GIF is well known for simple animations. But for modern websites, GIF is often not the best choice. Animated GIF files can become very large, especially when they contain many frames or colors.&lt;/p&gt;

&lt;p&gt;For short animations, it is often better to use video formats or animated WebP where supported. GIF is still useful in some cases, but it should not be used for large animations on performance-focused pages.&lt;/p&gt;

&lt;p&gt;GIF is okay for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Very small simple animations&lt;/li&gt;
&lt;li&gt;Tiny decorative motion&lt;/li&gt;
&lt;li&gt;Basic legacy support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Avoid GIF for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Long animations&lt;/li&gt;
&lt;li&gt;Large screen recordings&lt;/li&gt;
&lt;li&gt;Product demos&lt;/li&gt;
&lt;li&gt;Hero section animations&lt;/li&gt;
&lt;li&gt;Anything that behaves like a video&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A large GIF can slow down a page more than people expect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Rule: Which Format Should You Use?
&lt;/h2&gt;

&lt;p&gt;Here is a simple way to choose. If you want a deeper technical explanation of different image types, the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Media/Guides/Formats/Image_types" rel="noopener noreferrer"&gt;MDN guide to image file formats&lt;/a&gt; is also a useful reference.&lt;/p&gt;

&lt;p&gt;Use &lt;strong&gt;JPG&lt;/strong&gt; when the image is a normal photo and you need broad compatibility.&lt;/p&gt;

&lt;p&gt;Use &lt;strong&gt;PNG&lt;/strong&gt; when the image needs transparency, sharp text, or clean edges.&lt;/p&gt;

&lt;p&gt;Use &lt;strong&gt;WebP&lt;/strong&gt; when you want smaller files for photos, graphics, thumbnails, and general website images.&lt;/p&gt;

&lt;p&gt;Use &lt;strong&gt;SVG&lt;/strong&gt; for logos, icons, and simple scalable illustrations.&lt;/p&gt;

&lt;p&gt;Use &lt;strong&gt;AVIF&lt;/strong&gt; when you want very small image files and your website setup supports modern image delivery.&lt;/p&gt;

&lt;p&gt;Use &lt;strong&gt;GIF&lt;/strong&gt; only for small simple animations, not large motion content.&lt;/p&gt;

&lt;p&gt;For most modern websites, the practical answer is simple: use SVG for logos and icons, WebP for most normal images, and JPG or PNG only when they are specifically needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Image Format Is Only One Part of Optimization
&lt;/h2&gt;

&lt;p&gt;Choosing the right format helps a lot, but it is not the only thing that matters. A WebP image can still be too large if its dimensions are huge. A JPG can still load fast if it is properly resized and compressed.&lt;/p&gt;

&lt;p&gt;Before uploading images, check these things:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Resize Images Before Uploading
&lt;/h3&gt;

&lt;p&gt;Do not upload a 4000px wide image if your page only displays it at 800px. The browser may visually shrink it, but users still have to download the larger file.&lt;/p&gt;

&lt;p&gt;Resize the image close to the size it will actually appear on the page.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Compress Without Destroying Quality
&lt;/h3&gt;

&lt;p&gt;Compression reduces file size. But too much compression makes images look bad. The goal is not to make every file tiny at any cost. The goal is to find the balance between size and quality.&lt;/p&gt;

&lt;p&gt;A good image should look clean while being light enough to load quickly.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Use Responsive Images
&lt;/h3&gt;

&lt;p&gt;Different devices need different image sizes. A desktop screen may need a large image, while a mobile phone may need a smaller one. Responsive image techniques allow the browser to choose the right file size for the user’s screen.&lt;/p&gt;

&lt;p&gt;This avoids sending desktop-sized images to mobile users.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Lazy Load Images Below the Fold
&lt;/h3&gt;

&lt;p&gt;Images that are not visible immediately do not always need to load right away. Lazy loading lets the browser load below-the-fold images later, when the user scrolls near them.&lt;/p&gt;

&lt;p&gt;This improves the first loading experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Reserve Image Space to Avoid Layout Shift
&lt;/h3&gt;

&lt;p&gt;When images load late without reserved space, the page can jump. This creates a poor user experience and may affect Core Web Vitals. Always define image width and height, or use CSS aspect ratios, so the browser knows how much space to reserve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Mistakes to Avoid
&lt;/h2&gt;

&lt;p&gt;Many websites lose performance because of simple image mistakes.&lt;/p&gt;

&lt;p&gt;One common mistake is using PNG for every image. PNG is great for some graphics, but it can be very heavy for photos.&lt;/p&gt;

&lt;p&gt;Another mistake is uploading images straight from a phone or camera. These files are often much larger than needed for a webpage.&lt;/p&gt;

&lt;p&gt;A third mistake is using one large image for all devices. Mobile users should not have to download the same large image used for desktop screens.&lt;/p&gt;

&lt;p&gt;Another issue is ignoring transparency. If an image does not need transparency, PNG may not be necessary. If it does need transparency, JPG will not work properly.&lt;/p&gt;

&lt;p&gt;Some websites also use too many decorative images. Even optimized images add weight. Every image should have a purpose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Format Choices for Different Website Areas
&lt;/h2&gt;

&lt;p&gt;For a &lt;strong&gt;logo&lt;/strong&gt;, use SVG when possible. If SVG is not available, use PNG with transparency.&lt;/p&gt;

&lt;p&gt;For a &lt;strong&gt;blog featured image&lt;/strong&gt;, use WebP or JPG. WebP is usually better for performance.&lt;/p&gt;

&lt;p&gt;For a &lt;strong&gt;product image&lt;/strong&gt;, use WebP for the live website, while keeping the original high-quality file separately.&lt;/p&gt;

&lt;p&gt;For a &lt;strong&gt;screenshot&lt;/strong&gt;, use PNG if the text needs to stay sharp. WebP can also work well if the result remains clear.&lt;/p&gt;

&lt;p&gt;For a &lt;strong&gt;hero image&lt;/strong&gt;, use WebP or AVIF with responsive sizes. Keep the file as light as possible because hero images often affect the first view of the page.&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;icons&lt;/strong&gt;, use SVG. It stays sharp and usually loads fast.&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;animated content&lt;/strong&gt;, avoid large GIFs. Use video or a modern animated format when possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Practical Workflow for Website Images
&lt;/h2&gt;

&lt;p&gt;A simple workflow can prevent most image problems:&lt;/p&gt;

&lt;p&gt;Start with the original high-quality image. Keep that original file safe for editing.&lt;/p&gt;

&lt;p&gt;Resize the image to the size needed for the website.&lt;/p&gt;

&lt;p&gt;Choose the correct format. Use SVG for icons and logos. Use WebP for most web images. Use PNG only when sharpness or transparency is needed. Use JPG when you need a simple photo format.&lt;/p&gt;

&lt;p&gt;Compress the image.&lt;/p&gt;

&lt;p&gt;Check how it looks on desktop and mobile.&lt;/p&gt;

&lt;p&gt;Upload it to your site.&lt;/p&gt;

&lt;p&gt;Test the page speed.&lt;/p&gt;

&lt;p&gt;This process may sound small, but it can make a big difference across a full website.&lt;/p&gt;

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

&lt;p&gt;The right image format can make a website faster without making it look worse. JPG, PNG, WebP, SVG, AVIF, and GIF all have their place, but they should not be used randomly.&lt;/p&gt;

&lt;p&gt;For modern web performance, WebP is often the best everyday choice for photos, thumbnails, banners, and general website images. SVG is best for logos and icons. PNG should be saved for transparency and sharp graphics. JPG still works well for photos, but it is no longer the only practical option. AVIF can be excellent for advanced optimization, while GIF should be used carefully because animated files can become heavy.&lt;/p&gt;

&lt;p&gt;Good image optimization is not about using the newest format everywhere. It is about choosing the format that fits the image, the page, and the user’s device.&lt;/p&gt;

&lt;p&gt;When images are properly resized, compressed, and saved in the right format, your website loads faster, feels smoother, and gives users a better experience from the first click.&lt;/p&gt;

</description>
      <category>webp</category>
      <category>png</category>
      <category>jpg</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
